2393 lines
78 KiB
C
2393 lines
78 KiB
C
|
|
/*
|
||
|
|
* @version: $Revision: 1.2 $
|
||
|
|
* @date: $Date: 2018/12/19 08:59:51 $
|
||
|
|
* @author: $Author: lizhongming $
|
||
|
|
* @state: $State: Exp $
|
||
|
|
*
|
||
|
|
* @latest: $Id: mvl_acse.c,v 1.2 2018/12/19 08:59:51 lizhongming Exp $
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
/************************************************************************/
|
||
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
||
|
|
/* 1986 - 2004, All Rights Reserved */
|
||
|
|
/* */
|
||
|
|
/* MODULE NAME : mvl_acse.c */
|
||
|
|
/* PRODUCT(S) : MMSEASE-LITE */
|
||
|
|
/* */
|
||
|
|
/* MODULE DESCRIPTION : */
|
||
|
|
/* */
|
||
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
||
|
|
/* NONE */
|
||
|
|
/* */
|
||
|
|
/* MODIFICATION LOG : */
|
||
|
|
/* Date Who Rev Comments */
|
||
|
|
/* -------- --- ------ ------------------------------------------- */
|
||
|
|
/* 07/13/05 MDE 104 Fixed crash caused using mvl_init_ind_hold */
|
||
|
|
/* 06/07/05 MDE 103 Fixed deadlock caused by mvl_init_ind_hold */
|
||
|
|
/* 05/10/05 JRB 102 Call new mvl_init_aa_obj_ctrl to init struct */
|
||
|
|
/* to control AA-Specific object creation */
|
||
|
|
/* (no longer done by Foundry). */
|
||
|
|
/* 05/04/05 MDE 101 Added mvl_init_ind_hold */
|
||
|
|
/* 04/28/05 MDE 100 Added user_conn_id check on abort ind */
|
||
|
|
/* 04/06/05 MDE 99 Added test probes */
|
||
|
|
/* 03/09/05 MDE 98 Set stats startTime */
|
||
|
|
/* 08/11/04 JRB 97 Del global funct ptr u_mvl_connect_ind_fun. */
|
||
|
|
/* Fix mvl_abort_req(_ex) returns (ST_RET). */
|
||
|
|
/* 07/14/04 MDE 96 Set mvl_net_info->acse_conn_id on init req */
|
||
|
|
/* 07/08/04 JRB 95 Del unused global var mvl_local_cl_ar_name. */
|
||
|
|
/* 06/07/04 EJV 94 Removed call to a_free_security_info */
|
||
|
|
/* 04/09/04 MDE 93 Removed call to a_free_security_info */
|
||
|
|
/* 01/21/04 EJV 92 u_a_associate_ind: added a_free_security_info*/
|
||
|
|
/* added reinfo.auth_info.auth_pres = SD_FALSE*/
|
||
|
|
/* 01/20/04 MDE 91 Added logging */
|
||
|
|
/* 11/07/03 JRB 90 Add mmsop_en_version1. */
|
||
|
|
/* 08/10/03 EJV 89 ACSE_AUTH_ENABLED code wo/defines */
|
||
|
|
/* Reworked mvl_net_info_to_chan. */
|
||
|
|
/* Removed defs from around find_rem_dib_entry()*/
|
||
|
|
/* For MAP30_ACSE use a_get_chan(). */
|
||
|
|
/* 07/02/03 JRB 88 _mvl_net_service set activityFlag if more */
|
||
|
|
/* events on list (so user keeps calling). */
|
||
|
|
/* 06/16/03 EJV 87 Removed m_match.h, s_match.h includes. */
|
||
|
|
/* Renamed the match funcs & chg arg. */
|
||
|
|
/* 06/10/03 MDE 86 Added address matching */
|
||
|
|
/* 04/14/03 JRB 85 Eliminate compiler warnings. */
|
||
|
|
/* 12/18/02 ASK 84 Only check authentication on POSITIVE connect*/
|
||
|
|
/* confirm */
|
||
|
|
/* 10/30/02 JRB 83 mvl_init_audt_addr: check remote tp_type. */
|
||
|
|
/* _mvl_send_msg: do lock around a_data_req */
|
||
|
|
/* call to make it thread-safe. */
|
||
|
|
/* Chg all connID, bindID to ST_LONG to avoid */
|
||
|
|
/* compile errors on 64-bit systems. */
|
||
|
|
/* 10/11/02 ASK 82 Added mvla_initiate_req_ex, */
|
||
|
|
/* u_mvl_connect_ind_ex, and */
|
||
|
|
/* u_mvl_connect_cnf_ex functions for ACSE */
|
||
|
|
/* authentication. */
|
||
|
|
/* 07/19/02 ASK 81 Fix net_info variable in _mvl_send_msg */
|
||
|
|
/* 07/17/02 MDE 80 Added mvl_conn_filtered_logging to send */
|
||
|
|
/* 07/10/02 JRB 79 Add maxpend_ind, numpend_ind. */
|
||
|
|
/* 07/09/02 MDE 78 Fixed bad free for bad decode of init resp */
|
||
|
|
/* 05/24/02 JRB 77 Put back MVL_COMM_EVENT linked list. */
|
||
|
|
/* Occasionally copp_event gets 2 events, one */
|
||
|
|
/* from TP0 and one from TP4. */
|
||
|
|
/* 05/17/02 JRB 76 mvla_init..: set *req_out=NULL if freed */
|
||
|
|
/* so user CAN'T free it again. */
|
||
|
|
/* 05/13/02 MDE 75 Don't scan unbound mvl_net_info */
|
||
|
|
/* 05/13/02 MDE 74 Now clean up requests for release conf */
|
||
|
|
/* 05/03/02 MDE 73 Added mvl_add_bind_ctrl, associated changes */
|
||
|
|
/* 04/29/02 MDE 72 Added MLOG for initiate */
|
||
|
|
/* 04/29/02 JRB 71 DON'T re-use MVL_NET_INFO until req_pend_list*/
|
||
|
|
/* is empty, assert if pend_ind is not empty. */
|
||
|
|
/* 03/07/02 MDE 70 mvla_set_init_ar now takes NULL */
|
||
|
|
/* 03/04/02 JRB 69 Start with clean "temp_bind_ctrl" so garbage */
|
||
|
|
/* doesn't get copied. */
|
||
|
|
/* Return error if num_call*>0 but not supported*/
|
||
|
|
/* 02/25/02 MDE 68 More changes to MVL_CFG_INFO */
|
||
|
|
/* 02/20/02 MDE 67 Changes for new MVL_CFG_INFO, multiple bind */
|
||
|
|
/* 02/14/02 RKR 66 call a_associate_reqm if Marben stack */
|
||
|
|
/* 02/08/02 JRB 65 Pass MVL_CFG_INFO struct to mvl_start_acse. */
|
||
|
|
/* Del mvl_local_ar_name,mvl_set_num_connections*/
|
||
|
|
/* 01/30/02 JRB 64 Add args to copp_initialize (same as MAP30..)*/
|
||
|
|
/* Del call to a_set_msgsize. */
|
||
|
|
/* Make sure mmsl_max_msg_size, mvl_num_calling,*/
|
||
|
|
/* mvl_num_called are set. */
|
||
|
|
/* Use MMS_INIT_EN instead of MVL_NUM_CALL*. */
|
||
|
|
/* Del use of COACSE define. */
|
||
|
|
/* Del mvl_max_comm_event (not used). */
|
||
|
|
/* Merge mvl_init, _mvl_init_conn_ctrl into */
|
||
|
|
/* mvl_start_acse. */
|
||
|
|
/* Replace mvl_init_cl_netinfo funct with */
|
||
|
|
/* mvl_init_audt_addr. */
|
||
|
|
/* Del u_a_unit_data_ind & all use of stack_sel.*/
|
||
|
|
/* 01/09/02 JRB 63 Del all use of clpp_bind & bind id. */
|
||
|
|
/* Del unused u_cla_except callback function. */
|
||
|
|
/* 12/04/01 MDE 62 Change to work with MAP30_ACSE */
|
||
|
|
/* 11/30/01 GLB 61 changed MVL_LOG_ERR1 to MVL_LOG_ERR0 */
|
||
|
|
/* 11/28/01 MDE 60 mvl_set_num_connections,mvl_set_max_msg_size */
|
||
|
|
/* 11/21/01 MDE 59 mvl_loc_ar_name now auto set */
|
||
|
|
/* 11/21/01 MDE 58 Safer num channel operation */
|
||
|
|
/* 11/05/01 JRB 57 mvl_wait_req_done now returns ST_RET. */
|
||
|
|
/* 09/21/01 JRB 56 Alloc global bufs only once at startup. */
|
||
|
|
/* Fix M_FREE context. */
|
||
|
|
/* 07/31/01 MDE 55 Added mvl_conn_filtered_logging */
|
||
|
|
/* 05/21/01 MDE 54 Free NET_INFO */
|
||
|
|
/* 03/13/01 JRB 53 Check for (MMS_INIT_EN & REQ_EN). */
|
||
|
|
/* 02/26/01 MDE 52 Moved m_smem_ctxt to mem_chks.c */
|
||
|
|
/* 11/28/00 EJV 51 Changes to interface with Marben stack SUIC */
|
||
|
|
/* (see MAP30_ACSE define): */
|
||
|
|
/* Use SUIC find_loc_..., find_rem_dib_entry. */
|
||
|
|
/* Added param in copp_initialize(). */
|
||
|
|
/* Added param in mvla_initiate_req(). */
|
||
|
|
/* Changed params in copp_bind(). */
|
||
|
|
/* 10/25/00 JRB 50 Del MVL_COMM_EVENT linked list. Only one used*/
|
||
|
|
/* Del call to _mvl_free_req_pend. */
|
||
|
|
/* 09/22/00 MDE 49 Changed index init */
|
||
|
|
/* 08/21/00 RKR 48 Changed prototype of mvl_init_cl_netinfo */
|
||
|
|
/* 08/23/00 MDE 47 Call '_mvl_set_net_req_done' on aborts too */
|
||
|
|
/* 05/15/00 MDE 46 Added MMS statistics */
|
||
|
|
/* 04/27/00 JRB 45 Fixed calloc (0) problem */
|
||
|
|
/* 04/14/00 JRB 44 Lint cleanup. */
|
||
|
|
/* 04/12/00 MDE 43 Added AA resize, MVL_STATISTICS */
|
||
|
|
/* 03/15/00 JRB 42 Del #ifdef MVL_REQ_BUF_ENABLED: not used. */
|
||
|
|
/* 03/09/00 MDE 41 Added _mvl_init_conn_ctrl */
|
||
|
|
/* 01/21/00 MDE 40 Now use MEM_SMEM for dynamic memory */
|
||
|
|
/* 12/20/99 GLB 39 Remove extra initialization and add asserts */
|
||
|
|
/* 11/23/99 MDE 38 Added mvla_check_req_que (from mvl_serv.c) */
|
||
|
|
/* 10/20/99 NAV 37 Add maxpend_req support */
|
||
|
|
/* 11/03/99 RKR 36 Set aborted pend req results to DISCONN */
|
||
|
|
/* 10/29/99 GLB 35 Added check for lack of connection */
|
||
|
|
/* 09/07/99 MDE 34 Added _mvlu_rpt_disconnect_rcvd_fun */
|
||
|
|
/* 07/30/99 JRB 33 Added MVL_GOOSE_SUPPORT define use */
|
||
|
|
/* Chg ma_clbind_ctrl from static to global. */
|
||
|
|
/* 07/14/99 JRB 32 On assoc ind, save acse_conn_id first. */
|
||
|
|
/* 04/13/99 MDE 31 Added '_mvla_initiate_locDe' */
|
||
|
|
/* 04/07/99 MDE 30 Fixed mvla_initiate_req return code */
|
||
|
|
/* 04/01/99 MDE 29 Eliminated connection handling memory leaks */
|
||
|
|
/* 04/01/99 MDE 28 Changes to decode buffer allocation scheme */
|
||
|
|
/* 03/18/99 MDE 27 Made # connection limits changable runtime */
|
||
|
|
/* 03/08/99 MDE 26 Added ICCP support */
|
||
|
|
/* 12/08/98 MDE 25 Cleanup on request control handling */
|
||
|
|
/* 12/08/98 MDE 24 Allow user to initiate w/o supplying a */
|
||
|
|
/* 'resp_info' buffer. */
|
||
|
|
/* 11/16/98 MDE 23 Conclude/Release cleanup, misc cleanup */
|
||
|
|
/* 10/22/98 JRB 22 mvl_start_acse init mvl_debug_sel. Other lint*/
|
||
|
|
/* 09/21/98 MDE 21 Minor lint cleanup */
|
||
|
|
/* 08/25/98 MDE 20 Fixed bind/unbind bug for CLACSE */
|
||
|
|
/* 08/14/98 MDE 19 Removed !ALLOW_COMPLEX_NET_EVENTS code */
|
||
|
|
/* 08/14/98 MDE 18 Updated 'u_a_data_ind' parameters as reqd */
|
||
|
|
/* 07/20/98 JRB 17 If MVL_NUM_CALLED not defined, reject all */
|
||
|
|
/* associate indications. */
|
||
|
|
/* 07/16/98 MDE 16 Addded 'mvl_dib_entry_to_app_ref' */
|
||
|
|
/* 07/06/98 JRB 15 mvl_init_cl_netinfo use new DIB_ENTRY and */
|
||
|
|
/* init rem_mac_valid so it sends to ALL-ES. */
|
||
|
|
/* 06/18/98 JRB 14 Bind to TP4 and TCP if tp_type=TP_TYPE_TPX. */
|
||
|
|
/* 02/10/98 MDE 13 Added 'index' to connection control. */
|
||
|
|
/* 12/29/97 JRB 12 Call c?pp_terminate if bind fails. */
|
||
|
|
/* 12/22/97 MDE 11 Changed '_mvl_net_service' to report activity */
|
||
|
|
/* 09/18/97 MDE 10 Now call 'a_set_msgsize' */
|
||
|
|
/* 02/07/97 MDE 09 Changed to use new MMS-EASE opcode defines */
|
||
|
|
/* 12/13/96 MDE 08 Now support CLACSE, other enhancements */
|
||
|
|
/* 11/18/96 MDE 07 Minor name cleanup, some CLACSE stuff */
|
||
|
|
/* 11/15/96 MDE 06 Global variable work */
|
||
|
|
/* 11/11/96 MDE 05 Added async functions, other cleanup */
|
||
|
|
/* 10/31/96 MDE 04 Added ALLOW_COMPLEX_NET_EVENTS code */
|
||
|
|
/* 08/19/96 MDE 03 Now save all remote node's initiate info */
|
||
|
|
/* 07/22/96 MDE 02 Changes towards A-Unit-Data support */
|
||
|
|
/* 01/21/94 MDE 01 Initial */
|
||
|
|
/************************************************************************/
|
||
|
|
#include <assert.h>
|
||
|
|
#include "rdb_client.h"
|
||
|
|
#include "glbtypes.h"
|
||
|
|
#include "sysincs.h"
|
||
|
|
#include "glbsem.h"
|
||
|
|
|
||
|
|
#include "mmsdefs.h"
|
||
|
|
#include "mms_pvar.h"
|
||
|
|
#include "mms_vvar.h"
|
||
|
|
#include "mms_err.h"
|
||
|
|
#include "mms_pcon.h"
|
||
|
|
#include "asn1defs.h"
|
||
|
|
#include "slog.h"
|
||
|
|
#include "tp4api.h"
|
||
|
|
#include "mvl_acse.h"
|
||
|
|
#include "mvl_defs.h"
|
||
|
|
#include "mvl_log.h"
|
||
|
|
#include "mloguser.h"
|
||
|
|
#include "mmsop_en.h"
|
||
|
|
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
#include "suicacse.h"
|
||
|
|
|
||
|
|
/* To limit the number of Marben stack files in the \mmslite\inc we */
|
||
|
|
/* prototype few referenced SUIC functions here. */
|
||
|
|
DIB_ENTRY *find_loc_dib_entry (ST_CHAR *name);
|
||
|
|
DIB_ENTRY *find_dib_entry (ST_CHAR *name);
|
||
|
|
#elif defined(LEAN_T)
|
||
|
|
#include "acse2.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined(_S_TEST_PROBES)
|
||
|
|
#include "stestprb.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* For debug version, use a static pointer to avoid duplication of */
|
||
|
|
/* __FILE__ strings. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
#ifdef DEBUG_SISCO
|
||
|
|
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
MVL_MMS_STATISTICS mvl_mms_statistics;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
#define NEGIOTIATE_INITIATE_PARAM
|
||
|
|
#define MVL_MMSOP_RELEASE 512 /* Add a MMS opcode define ... */
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* Global variables - Connection Oriented Only */
|
||
|
|
/* The user must fill in a table of DIB entries for local and remote */
|
||
|
|
/* nodes of interest. This can be done by the user via the 'init_dirser'*/
|
||
|
|
/* function, can be hard coded, etc.. */
|
||
|
|
|
||
|
|
#if !defined(MAP30_ACSE) /* For MAP30_ACSE use SUIC function instead */
|
||
|
|
ST_INT num_loc_dib_entries;
|
||
|
|
DIB_ENTRY *loc_dib_table;
|
||
|
|
ST_INT num_rem_dib_entries;
|
||
|
|
DIB_ENTRY *rem_dib_table;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
DIB_ENTRY *_mvla_initiate_locDe;
|
||
|
|
NET_BIND_CTRL *_mvla_initiate_bc;
|
||
|
|
|
||
|
|
/* Our connection controls - we support multiple called and/or calling */
|
||
|
|
/* simultanious connections. */
|
||
|
|
|
||
|
|
MVL_NET_INFO *mvl_calling_conn_ctrl;
|
||
|
|
MVL_NET_INFO *mvl_called_conn_ctrl;
|
||
|
|
|
||
|
|
/* Other user configurable parameters */
|
||
|
|
#ifndef MMS_INIT_EN
|
||
|
|
#error MMS_INIT_EN not defined. Must include mmsop_en.h
|
||
|
|
#endif
|
||
|
|
#if (MMS_INIT_EN & RESP_EN)
|
||
|
|
INIT_INFO *mvl_init_resp_info;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
ST_VOID (*u_mvl_disc_ind_fun) (MVL_NET_INFO *cc, ST_INT discType);
|
||
|
|
ST_VOID (*_mvlu_rpt_disconnect_rcvd_fun)(MVL_NET_INFO *netInfo);
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* This variable is set SD_TRUE when the ACSE interface is viable */
|
||
|
|
ST_INT mvl_acse_ok;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* These arrays are created in mmsop_en.c */
|
||
|
|
extern SD_CONST ST_UCHAR m_param[2];
|
||
|
|
extern SD_CONST ST_UCHAR m_service_resp[11];
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* Bind Control */
|
||
|
|
|
||
|
|
|
||
|
|
NET_BIND_CTRL ma_clbind_ctrl; /* to save clpp_bind info. */
|
||
|
|
|
||
|
|
/* These variables are used in making some asynchronous ACSE functions */
|
||
|
|
/* work in a blocking mode */
|
||
|
|
static ST_INT ma_cmd_done;
|
||
|
|
static ST_INT ma_cmd_rslt;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
MVL_CFG_INFO *mvl_cfg_info;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* MMS COMM EVENT CONTROL MANAGEMENT */
|
||
|
|
|
||
|
|
static MVL_COMM_EVENT *mvl_comm_event_up_head; /* ptr to linked list */
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* MVL_NET_INFO handling for incoming A-Unit Data */
|
||
|
|
|
||
|
|
#if defined(CLACSE)
|
||
|
|
ST_INT16 mvl_max_net_info = 10;
|
||
|
|
static ST_INT16 mvl_net_info_count;
|
||
|
|
static MVL_NET_INFO *mvl_net_info_avail_head;
|
||
|
|
|
||
|
|
static MVL_NET_INFO *mvl_get_net_info (ST_VOID);
|
||
|
|
static ST_VOID mvl_free_net_info (MVL_NET_INFO *netInfo);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
typedef struct
|
||
|
|
{
|
||
|
|
DBL_LNK l;
|
||
|
|
ST_LONG u_bind_id;
|
||
|
|
ST_LONG acse_conn_id;
|
||
|
|
AARQ_APDU *info;
|
||
|
|
} MVL_ASSOC_IND;
|
||
|
|
MVL_ASSOC_IND *mvlAssocIndList;
|
||
|
|
|
||
|
|
ST_BOOLEAN mvl_init_ind_hold;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/* Internal functions */
|
||
|
|
static ST_VOID ma_wait_req_done (ST_RET *retOut);
|
||
|
|
#if (MMS_INIT_EN & RESP_EN)
|
||
|
|
static MVL_NET_INFO *ma_get_called_conn_ctrl (NET_BIND_CTRL *);
|
||
|
|
#endif
|
||
|
|
#if (MMS_INIT_EN & REQ_EN)
|
||
|
|
static MVL_NET_INFO *ma_get_calling_conn_ctrl (NET_BIND_CTRL *);
|
||
|
|
#endif
|
||
|
|
static ST_VOID copp_unbind_sync (ST_LONG copp_bind_id);
|
||
|
|
static ST_RET ma_bind (NET_BIND_CTRL *bc, ST_BOOLEAN activate);
|
||
|
|
|
||
|
|
static MVL_COMM_EVENT *mvl_get_com_event (ST_VOID);
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* _mvl_net_service */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_BOOLEAN _mvl_net_service (MVL_COMM_EVENT **eventOut)
|
||
|
|
{
|
||
|
|
ST_BOOLEAN activityFlag;
|
||
|
|
MVL_ASSOC_IND *mvlAssocInd;
|
||
|
|
|
||
|
|
*eventOut = NULL;
|
||
|
|
if (mvl_acse_ok != SD_TRUE)
|
||
|
|
return (SD_FALSE);
|
||
|
|
|
||
|
|
S_LOCK_COMMON_RESOURCES ();
|
||
|
|
|
||
|
|
/* If we have a delayed initiate indication (ICCP Lite redundancy), */
|
||
|
|
/* handle it now */
|
||
|
|
if (mvlAssocIndList && !mvl_init_ind_hold)
|
||
|
|
{
|
||
|
|
mvlAssocInd = list_get_first (&mvlAssocIndList);
|
||
|
|
u_a_associate_ind (mvlAssocInd->u_bind_id,
|
||
|
|
mvlAssocInd->acse_conn_id,
|
||
|
|
mvlAssocInd->info);
|
||
|
|
chk_free (mvlAssocInd);
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (SD_TRUE);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* May cause the 'acse' user function to be called if something is */
|
||
|
|
/* going on that we need to know about. If so, the functions will */
|
||
|
|
/* get the event and put them onto the 'mvl_comm_event_up_head' list */
|
||
|
|
|
||
|
|
activityFlag = copp_event ();
|
||
|
|
/* Occasionally copp_event gets 2 events, one from TP0 and one from TP4,*/
|
||
|
|
/* so they are put on this linked list. "Usually" only one on list. */
|
||
|
|
if (mvl_comm_event_up_head)
|
||
|
|
*eventOut = (MVL_COMM_EVENT *) list_get_first((ST_VOID **) &mvl_comm_event_up_head);
|
||
|
|
|
||
|
|
if (mvl_comm_event_up_head != NULL)
|
||
|
|
{
|
||
|
|
/* more events on linked list */
|
||
|
|
activityFlag=SD_TRUE; /* force it so user knows to call again */
|
||
|
|
}
|
||
|
|
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (activityFlag);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_get_com_event */
|
||
|
|
/************************************************************************/
|
||
|
|
/* This function is used to get a MVL_COMM_EVENT control buffer to be */
|
||
|
|
/* passed up to the caller of '_mvl_net_service'. */
|
||
|
|
|
||
|
|
static MVL_COMM_EVENT *mvl_get_com_event (ST_VOID)
|
||
|
|
{
|
||
|
|
MVL_COMM_EVENT *commEvent;
|
||
|
|
|
||
|
|
S_LOCK_COMMON_RESOURCES ();
|
||
|
|
commEvent = (MVL_COMM_EVENT *) M_CALLOC (MSMEM_COM_EVENT, 1, sizeof (MVL_COMM_EVENT));
|
||
|
|
if (commEvent == NULL)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Error: No MVL_COMM_EVENT available");
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
list_add_last((ST_VOID **) &mvl_comm_event_up_head, (ST_VOID *) commEvent);
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (commEvent);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* _mvl_free_comm_event */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID _mvl_free_comm_event (MVL_COMM_EVENT *event)
|
||
|
|
{
|
||
|
|
S_LOCK_COMMON_RESOURCES ();
|
||
|
|
if (event->event_type == MMS_MSG_RCVD)
|
||
|
|
{
|
||
|
|
M_FREE (MSMEM_RXPDU, event->u.mms.pdu);
|
||
|
|
|
||
|
|
if (event->u.mms.dec_rslt.data_pres)
|
||
|
|
{
|
||
|
|
M_FREE (MSMEM_DEC_OS_INFO, event->u.mms.dec_rslt.data_ptr);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
M_FREE (MSMEM_COM_EVENT, event);
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_set_max_msg_size */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID mvl_set_max_msg_size (ST_INT max_msg_size)
|
||
|
|
{
|
||
|
|
mvl_cfg_info->max_msg_size = max_msg_size;
|
||
|
|
mmsl_enc_buf_size = max_msg_size + ASN1_MAX_ELEMENT_OVERHEAD;
|
||
|
|
if (mmsl_enc_buf != NULL)
|
||
|
|
M_FREE (MSMEM_STARTUP, mmsl_enc_buf);
|
||
|
|
|
||
|
|
mmsl_enc_buf = M_MALLOC (MSMEM_STARTUP, mmsl_enc_buf_size);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_init_aa_obj_ctrl */
|
||
|
|
/* Init struct to control AA-Specific object creation (var and nvl). */
|
||
|
|
/* Init one MVL_AA_OBJ_CTRL struct for one connection. */
|
||
|
|
/* NOTE: if OBSOLETE_AA_OBJ_INIT, this initialization is done by Foundry.*/
|
||
|
|
/************************************************************************/
|
||
|
|
#if !defined(OBSOLETE_AA_OBJ_INIT)
|
||
|
|
static MVL_AA_OBJ_CTRL *mvl_init_aa_obj_ctrl ()
|
||
|
|
{
|
||
|
|
MVL_AA_OBJ_CTRL *aa_obj;
|
||
|
|
aa_obj = (MVL_AA_OBJ_CTRL *) M_CALLOC (MSMEM_STARTUP, 1, sizeof(MVL_AA_OBJ_CTRL));
|
||
|
|
|
||
|
|
/* Set up for dynamic creation of AA-Specific Variables. */
|
||
|
|
aa_obj->max_num_var_assoc = mvl_max_dyn.aa_vars;
|
||
|
|
aa_obj->num_var_assoc = 0;
|
||
|
|
if (aa_obj->max_num_var_assoc)
|
||
|
|
aa_obj->var_assoc_tbl = (MVL_VAR_ASSOC **) M_CALLOC (MSMEM_STARTUP, aa_obj->max_num_var_assoc, sizeof (MVL_VAR_ASSOC *));
|
||
|
|
|
||
|
|
/* Set up for dynamic creation of AA-Specific NamedVariableLists (NVL). */
|
||
|
|
aa_obj->max_num_nvlist = mvl_max_dyn.aa_nvls;
|
||
|
|
aa_obj->num_nvlist = 0;
|
||
|
|
if (aa_obj->max_num_nvlist)
|
||
|
|
aa_obj->nvlist_tbl = (MVL_NVLIST_CTRL **) M_CALLOC (MSMEM_STARTUP, aa_obj->max_num_nvlist, sizeof (MVL_NVLIST_CTRL *));
|
||
|
|
return (aa_obj);
|
||
|
|
}
|
||
|
|
#endif /* #if !defined(OBSOLETE_AA_OBJ_INIT) */
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_start_acse */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvl_start_acse (MVL_CFG_INFO *cfgInfo)
|
||
|
|
{
|
||
|
|
NET_BIND_CTRL *bind_ctrl_src;
|
||
|
|
NET_BIND_CTRL *bind_ctrl_dest;
|
||
|
|
NET_BIND_CTRL temp_bind_ctrl;
|
||
|
|
ST_INT mvl_cfg_info_size;
|
||
|
|
ST_INT ret;
|
||
|
|
ST_INT i;
|
||
|
|
ST_INT index = 0;
|
||
|
|
extern int mmsop_en_version1;
|
||
|
|
|
||
|
|
mmsop_en_version1=0; /* value of this var means nothing, but it */
|
||
|
|
/* causes error if you link to older mmsop_en.c */
|
||
|
|
|
||
|
|
MVL_LOG_ACSE0 ("ACSE: Starting");
|
||
|
|
|
||
|
|
mvl_debug_sel |= MVLLOG_ERR; /* Always enable error logging. */
|
||
|
|
|
||
|
|
/* Here we will make the MVL configuration information persistant */
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
if (cfgInfo->use_bind_ctrl != SD_TRUE)
|
||
|
|
#endif
|
||
|
|
{ /* Create the required bind control structures, if not supplied */
|
||
|
|
/* Use memset to start with clean structure */
|
||
|
|
memset (&temp_bind_ctrl, 0, sizeof (NET_BIND_CTRL)); /* CRITICAL*/
|
||
|
|
strcpy (temp_bind_ctrl.ar_name, cfgInfo->local_ar_name);
|
||
|
|
temp_bind_ctrl.num_calling = cfgInfo->num_calling;
|
||
|
|
temp_bind_ctrl.num_called = cfgInfo->num_called;
|
||
|
|
cfgInfo->bind_ctrl = &temp_bind_ctrl;
|
||
|
|
cfgInfo->max_bind_ctrl = 1;
|
||
|
|
cfgInfo->num_bind_ctrl = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* OK, now copy the MVL configuration info */
|
||
|
|
mvl_cfg_info_size = sizeof (MVL_CFG_INFO) +
|
||
|
|
(cfgInfo->max_bind_ctrl * sizeof (NET_BIND_CTRL));
|
||
|
|
mvl_cfg_info = chk_calloc (1, mvl_cfg_info_size);
|
||
|
|
*mvl_cfg_info = *cfgInfo;
|
||
|
|
|
||
|
|
if (mvl_cfg_info->max_bind_ctrl == 0)
|
||
|
|
mvl_cfg_info->max_bind_ctrl = mvl_cfg_info->num_bind_ctrl;
|
||
|
|
|
||
|
|
mvl_cfg_info->calling_used = 0;
|
||
|
|
mvl_cfg_info->called_used = 0;
|
||
|
|
|
||
|
|
mvl_cfg_info->bind_ctrl = (NET_BIND_CTRL *) (mvl_cfg_info + 1);
|
||
|
|
bind_ctrl_dest = mvl_cfg_info->bind_ctrl;
|
||
|
|
bind_ctrl_src = cfgInfo->bind_ctrl;
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_bind_ctrl; ++i)
|
||
|
|
{
|
||
|
|
*bind_ctrl_dest = *bind_ctrl_src;
|
||
|
|
++bind_ctrl_src;
|
||
|
|
++bind_ctrl_dest;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Make sure max msg size has been set. */
|
||
|
|
if (mvl_cfg_info->max_msg_size == 0)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Max MMS message size must be set");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
mvl_set_max_msg_size (mvl_cfg_info->max_msg_size); /* save to global & alloc bufs*/
|
||
|
|
|
||
|
|
/* Initialize function pointers for MMS allocation. */
|
||
|
|
m_calloc_os_fun = _mvl_calloc_os;
|
||
|
|
m_realloc_os_fun = _mvl_realloc_os;
|
||
|
|
m_free_os_fun = _mvl_free_os;
|
||
|
|
|
||
|
|
#if !(MMS_INIT_EN & REQ_EN)
|
||
|
|
if (mvl_cfg_info->num_calling != 0)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("num_calling > 0 is illegal because Initiate.Req is NOT enabled");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#if !(MMS_INIT_EN & RESP_EN)
|
||
|
|
if (mvl_cfg_info->num_called != 0)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("num_called > 0 is illegal because Initiate.Resp is NOT enabled");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* Make sure "num_calling" AND/OR "num_called" has been set. */
|
||
|
|
if (mvl_cfg_info->num_calling == 0 && mvl_cfg_info->num_called == 0)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("num_calling AND num_called both 0, must set at least one." );
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Alloc & fill in array of "calling" connection control structures. */
|
||
|
|
#if (MMS_INIT_EN & REQ_EN)
|
||
|
|
if (mvl_cfg_info->num_calling != 0)
|
||
|
|
mvl_calling_conn_ctrl = M_CALLOC (MSMEM_GEN, mvl_cfg_info->num_calling, sizeof (MVL_NET_INFO));
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_calling; ++i)
|
||
|
|
{
|
||
|
|
mvl_calling_conn_ctrl[i].index = index++;
|
||
|
|
#if !defined(OBSOLETE_AA_OBJ_INIT)
|
||
|
|
mvl_calling_conn_ctrl[i].aa_objs = mvl_init_aa_obj_ctrl ();
|
||
|
|
#endif /* #if !defined(OBSOLETE_AA_OBJ_INIT) */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* Alloc & fill in array of "called" connection control structures. */
|
||
|
|
#if (MMS_INIT_EN & RESP_EN)
|
||
|
|
if (mvl_cfg_info->num_called != 0)
|
||
|
|
mvl_called_conn_ctrl = M_CALLOC (MSMEM_GEN, mvl_cfg_info->num_called, sizeof (MVL_NET_INFO));
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_called; ++i)
|
||
|
|
{
|
||
|
|
mvl_called_conn_ctrl[i].index = index++;
|
||
|
|
#if !defined(OBSOLETE_AA_OBJ_INIT)
|
||
|
|
mvl_called_conn_ctrl[i].aa_objs = mvl_init_aa_obj_ctrl ();
|
||
|
|
#endif /* #if !defined(OBSOLETE_AA_OBJ_INIT) */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* Initialize Connection Oriented OSI Stack. */
|
||
|
|
ret = copp_initialize (mvl_cfg_info->num_calling + mvl_cfg_info->num_called, mmsl_enc_buf_size);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR1 ("Error: copp_initialize returned error '0x%x'", ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Initialize Connectionless OSI Stack. */
|
||
|
|
#if defined(CLACSE)
|
||
|
|
ret = clpp_initialize ();
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR1 ("Error: clpp_initialize returned error '0x%x'", ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* Bind local AR names */
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_bind_ctrl; ++i)
|
||
|
|
{
|
||
|
|
ret = ma_bind (&mvl_cfg_info->bind_ctrl[i], SD_TRUE);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Binding not necessary for CLACSE. */
|
||
|
|
|
||
|
|
/* Initialize all mms objects (generated by foundry). */
|
||
|
|
if (ret == SD_SUCCESS)
|
||
|
|
mvl_init_mms_objs ();
|
||
|
|
|
||
|
|
if (ret == SD_SUCCESS)
|
||
|
|
mvl_acse_ok = SD_TRUE;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
copp_terminate ();
|
||
|
|
#if defined(CLACSE)
|
||
|
|
clpp_terminate ();
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: Start complete, returning '0x%x'", ret);
|
||
|
|
mvl_mms_statistics.startTime = sGetMsTime ();
|
||
|
|
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_end_acse */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvl_end_acse (ST_VOID)
|
||
|
|
{
|
||
|
|
NET_BIND_CTRL *bc;
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
MVL_LOG_ACSE0 ("ACSE: Ending");
|
||
|
|
|
||
|
|
/* Unbind all */
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_bind_ctrl; ++i)
|
||
|
|
{
|
||
|
|
bc = &mvl_cfg_info->bind_ctrl[i];
|
||
|
|
#ifdef LEAN_T
|
||
|
|
if (bc->copp_bind_id_tcp)
|
||
|
|
copp_unbind_sync (bc->copp_bind_id_tcp);
|
||
|
|
if (bc->copp_bind_id_tp4)
|
||
|
|
copp_unbind_sync (bc->copp_bind_id_tp4);
|
||
|
|
#else /* !LEAN_T */
|
||
|
|
copp_unbind_sync (bc->copp_bind_id);
|
||
|
|
#endif /* !LEAN_T */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Shut down the ACSE interface, as well as it's subsystems */
|
||
|
|
|
||
|
|
copp_terminate ();
|
||
|
|
#if defined(CLACSE)
|
||
|
|
clpp_terminate ();
|
||
|
|
#endif
|
||
|
|
|
||
|
|
MVL_LOG_ACSE0 ("ACSE: Ended");
|
||
|
|
return (SD_SUCCESS);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* _mvl_send_msg */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT _mvl_send_msg (ST_UCHAR *pdu, ST_INT pdu_len, MVL_NET_INFO *net_info)
|
||
|
|
{
|
||
|
|
ST_INT ret;
|
||
|
|
|
||
|
|
/* See if we are supposed to log ACSE data for this connection */
|
||
|
|
if (mvl_conn_filtered_logging == SD_FALSE || net_info->log_enable)
|
||
|
|
{
|
||
|
|
MVL_LOG_ACSEDATA2 ("ACSE: Sending %d bytes on MVL_NET_INFO 0x%08lx",
|
||
|
|
pdu_len, net_info);
|
||
|
|
MVL_LOG_ACSEDATAH (pdu_len, pdu);
|
||
|
|
}
|
||
|
|
|
||
|
|
ret = SD_FAILURE;
|
||
|
|
|
||
|
|
#if (MMS_INIT_EN != REQ_RESP_DIS)
|
||
|
|
if (net_info->conn_active == SD_FALSE)
|
||
|
|
{ /* no connection */
|
||
|
|
ret = MVL_ERR_CNF_DISCONNECTED; /* more precise error code */
|
||
|
|
MVL_LOG_NERR1 ("ACSE: no connection '0x%x'", ret);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{ /* valid connection */
|
||
|
|
S_LOCK_COMMON_RESOURCES ();
|
||
|
|
ret = a_data_req (net_info->acse_conn_id, pdu_len, pdu);
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: a_data_req error '0x%x'", ret);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* DIRECTORY SERVICES FUNCTIONS */
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* find_loc_dib_entry */
|
||
|
|
/************************************************************************/
|
||
|
|
#if !defined(MAP30_ACSE) /* For MAP30_ACSE use SUIC function instead */
|
||
|
|
DIB_ENTRY *find_loc_dib_entry (ST_CHAR *name)
|
||
|
|
{
|
||
|
|
ST_INT i;
|
||
|
|
DIB_ENTRY *de;
|
||
|
|
|
||
|
|
for (i = 0; i < num_loc_dib_entries; i++)
|
||
|
|
{
|
||
|
|
de = &loc_dib_table[i];
|
||
|
|
if (!strcmp (de->name, name))
|
||
|
|
return (de);
|
||
|
|
}
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
#endif /* !defined(MAP30_ACSE) */
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* find_rem_dib_entry */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
DIB_ENTRY *find_rem_dib_entry (ST_CHAR *name)
|
||
|
|
{
|
||
|
|
#if !defined(MAP30_ACSE)
|
||
|
|
ST_INT i;
|
||
|
|
#endif
|
||
|
|
DIB_ENTRY *de;
|
||
|
|
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
/* For Marben stack use SUIC function */
|
||
|
|
de = find_dib_entry (name); /* searches first loc then rem tables */
|
||
|
|
return (de);
|
||
|
|
#else /* !defined(MAP30_ACSE) */
|
||
|
|
for (i = 0; i < num_rem_dib_entries; i++)
|
||
|
|
{
|
||
|
|
de = &rem_dib_table[i];
|
||
|
|
if (!strcmp (de->name, name))
|
||
|
|
return (de);
|
||
|
|
}
|
||
|
|
return (NULL);
|
||
|
|
#endif /* !defined(MAP30_ACSE) */
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_dib_entry_to_app_ref */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID mvl_dib_entry_to_app_ref (DIB_ENTRY *de, APP_REF *appRef)
|
||
|
|
{
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
appRef->form = APP_REF_FORM2;
|
||
|
|
appRef->ap_title_pres = de->AP_title_pres;
|
||
|
|
if (appRef->ap_title_pres == SD_TRUE)
|
||
|
|
{
|
||
|
|
appRef->ap_title.form_2.num_comps = de->AP_title.num_comps;
|
||
|
|
for (i = 0; i < de->AP_title.num_comps; ++i)
|
||
|
|
appRef->ap_title.form_2.comps[i] = de->AP_title.comps[i];
|
||
|
|
}
|
||
|
|
appRef->ap_invoke_pres = de->AP_inv_id_pres;
|
||
|
|
appRef->ap_invoke = de->AP_invoke_id;
|
||
|
|
appRef->ae_qual_pres = de->AE_qual_pres;
|
||
|
|
appRef->ae_qual.form_2 = de->AE_qual;
|
||
|
|
appRef->ae_invoke_pres = de->AE_inv_id_pres;
|
||
|
|
appRef->ae_invoke = de->AE_invoke_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
#if (MMS_INIT_EN != REQ_RESP_DIS) /* COACSE SPECIFIC FUNCTIONS */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvla_set_init_ar (ST_CHAR *ar_name)
|
||
|
|
{
|
||
|
|
NET_BIND_CTRL *bc;
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
/* See if user want's to use the default AR */
|
||
|
|
if (ar_name == NULL)
|
||
|
|
{
|
||
|
|
_mvla_initiate_bc = NULL;
|
||
|
|
return (SD_SUCCESS);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_bind_ctrl; ++i)
|
||
|
|
{
|
||
|
|
bc = &mvl_cfg_info->bind_ctrl[i];
|
||
|
|
if (!strcmp (ar_name, bc->ar_name))
|
||
|
|
{
|
||
|
|
_mvla_initiate_bc = bc;
|
||
|
|
return (SD_SUCCESS);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
#if (MMS_INIT_EN & REQ_EN)
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_initiate_req */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvl_initiate_req (ST_CHAR *remAr,
|
||
|
|
INIT_INFO *req_info,
|
||
|
|
INIT_INFO *resp_info,
|
||
|
|
MVL_NET_INFO **net_info_out)
|
||
|
|
{
|
||
|
|
MVL_REQ_PEND *req;
|
||
|
|
ST_INT rc;
|
||
|
|
|
||
|
|
if (_mvl_comm_serve_active == SD_TRUE)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("Error: mvl_comm_serv active");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
rc = mvla_initiate_req (remAr, req_info, resp_info, net_info_out, &req);
|
||
|
|
if (rc != SD_SUCCESS)
|
||
|
|
return (rc);
|
||
|
|
|
||
|
|
rc = mvl_wait_req_done (req);
|
||
|
|
if (rc != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("ACSE: Initiate failed");
|
||
|
|
}
|
||
|
|
|
||
|
|
mvl_free_req_ctrl (req); /* we are done with this req ctrl */
|
||
|
|
return (rc);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvla_initiate_req */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvla_initiate_req (ST_CHAR *remAr,
|
||
|
|
INIT_INFO *req_info,
|
||
|
|
INIT_INFO *resp_info,
|
||
|
|
MVL_NET_INFO **net_info_out,
|
||
|
|
MVL_REQ_PEND **req_out)
|
||
|
|
{
|
||
|
|
ST_INT rc;
|
||
|
|
|
||
|
|
rc = mvla_initiate_req_ex (remAr, req_info, resp_info, net_info_out,
|
||
|
|
req_out, NULL, NULL);
|
||
|
|
|
||
|
|
return rc;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvla_initiate_req_ex */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
|
||
|
|
ST_INT mvla_initiate_req_ex (ST_CHAR *remAr,
|
||
|
|
INIT_INFO *req_info,
|
||
|
|
INIT_INFO *resp_info,
|
||
|
|
MVL_NET_INFO **net_info_out,
|
||
|
|
MVL_REQ_PEND **req_out,
|
||
|
|
ACSE_AUTH_INFO *auth_info,
|
||
|
|
S_SEC_ENCRYPT_CTRL *encrypt_info)
|
||
|
|
{
|
||
|
|
ST_INT rc;
|
||
|
|
MVL_NET_INFO *cc;
|
||
|
|
DIB_ENTRY *locDe;
|
||
|
|
DIB_ENTRY *remDe;
|
||
|
|
AARQ_APDU aarq_apdu;
|
||
|
|
ST_LONG acse_conn_id;
|
||
|
|
MVL_REQ_PEND *req;
|
||
|
|
|
||
|
|
*req_out = NULL; /* make sure it's initialized */
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: Initiate Request to '%s'", remAr);
|
||
|
|
|
||
|
|
/* Get a calling connection control structure */
|
||
|
|
|
||
|
|
cc = ma_get_calling_conn_ctrl (_mvla_initiate_bc);
|
||
|
|
if (!cc)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Error - Could not get calling MVL_NET_INFO");
|
||
|
|
return (MVL_ERR_NO_CONN_CTRL);
|
||
|
|
}
|
||
|
|
MVL_LOG_CACSE1 ("Using MVL_NET_INFO %08lx", cc);
|
||
|
|
|
||
|
|
req = _mvl_get_req_ctrl (cc, MMSOP_INITIATE);
|
||
|
|
if (!req)
|
||
|
|
{
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
return (MVL_ERR_NO_REQ_CTRL);
|
||
|
|
}
|
||
|
|
*req_out = req;
|
||
|
|
req->invoke_id = -1;
|
||
|
|
|
||
|
|
rc = mpl_init (req_info);
|
||
|
|
if (rc == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
/* We can log here if so desired */
|
||
|
|
/* if ((mms_debug_sel & MMS_LOG_REQ) && ml_log_req_info_fun != NULL)
|
||
|
|
(*ml_log_req_info_fun) (0, MMSOP_INITIATE, req_info);*/
|
||
|
|
|
||
|
|
/* Save the output pointer in the MMS request control element */
|
||
|
|
req->u.init.resp_info = resp_info;
|
||
|
|
|
||
|
|
/* Save our initiate request information ... */
|
||
|
|
memcpy (&cc->locl_init_info, req_info, sizeof (INIT_INFO));
|
||
|
|
|
||
|
|
/* Retrieve the DIB_ENTRY's for local and remote. These are used to set */
|
||
|
|
/* the AARQ_APDU information */
|
||
|
|
if (_mvla_initiate_locDe != NULL)
|
||
|
|
locDe = _mvla_initiate_locDe;
|
||
|
|
else
|
||
|
|
locDe = cc->bind_ctrl->de;
|
||
|
|
|
||
|
|
remDe = find_rem_dib_entry (remAr);
|
||
|
|
if (remDe)
|
||
|
|
{
|
||
|
|
/* Now set up all AARQ_APDU information based on DIB_ENTRY information */
|
||
|
|
|
||
|
|
#if !defined(MAP30_ACSE) /* most info not needed for Lite over Marben stack */
|
||
|
|
/* AP Context is MMS */
|
||
|
|
aarq_apdu.ASO_context_name_pres = SD_TRUE;
|
||
|
|
aarq_apdu.ASO_context_name.num_comps = 5;
|
||
|
|
aarq_apdu.ASO_context_name.comps[0] = 1;
|
||
|
|
aarq_apdu.ASO_context_name.comps[1] = 0;
|
||
|
|
aarq_apdu.ASO_context_name.comps[2] = 9506;
|
||
|
|
aarq_apdu.ASO_context_name.comps[3] = 2;
|
||
|
|
aarq_apdu.ASO_context_name.comps[4] = 3;
|
||
|
|
|
||
|
|
/* Calling AE Title */
|
||
|
|
aarq_apdu.calling_ae_title.AP_title_pres = locDe->AP_title_pres;
|
||
|
|
memcpy (&aarq_apdu.calling_ae_title.AP_title,
|
||
|
|
&locDe->AP_title,
|
||
|
|
sizeof (MMS_OBJ_ID));
|
||
|
|
|
||
|
|
aarq_apdu.calling_ae_title.AE_qual_pres = locDe->AE_qual_pres;
|
||
|
|
aarq_apdu.calling_ae_title.AE_qual = locDe->AE_qual;
|
||
|
|
aarq_apdu.calling_ae_title.AP_inv_id_pres = locDe->AP_inv_id_pres;
|
||
|
|
aarq_apdu.calling_ae_title.AP_inv_id = locDe->AP_invoke_id;
|
||
|
|
aarq_apdu.calling_ae_title.AE_qual_pres = locDe->AE_qual_pres;
|
||
|
|
aarq_apdu.calling_ae_title.AE_qual = locDe->AE_qual;
|
||
|
|
aarq_apdu.calling_ae_title.AE_inv_id_pres = locDe->AE_inv_id_pres;
|
||
|
|
aarq_apdu.calling_ae_title.AE_inv_id = locDe->AE_invoke_id;
|
||
|
|
|
||
|
|
/* Called AE Title */
|
||
|
|
aarq_apdu.called_ae_title.AP_title_pres = remDe->AP_title_pres;
|
||
|
|
memcpy (&aarq_apdu.called_ae_title.AP_title,
|
||
|
|
&remDe->AP_title,
|
||
|
|
sizeof (MMS_OBJ_ID));
|
||
|
|
|
||
|
|
aarq_apdu.called_ae_title.AE_qual_pres = remDe->AE_qual_pres;
|
||
|
|
aarq_apdu.called_ae_title.AE_qual = remDe->AE_qual;
|
||
|
|
aarq_apdu.called_ae_title.AP_inv_id_pres = remDe->AP_inv_id_pres;
|
||
|
|
aarq_apdu.called_ae_title.AP_inv_id = remDe->AP_invoke_id;
|
||
|
|
aarq_apdu.called_ae_title.AE_qual_pres = remDe->AE_qual_pres;
|
||
|
|
aarq_apdu.called_ae_title.AE_qual = remDe->AE_qual;
|
||
|
|
aarq_apdu.called_ae_title.AE_inv_id_pres = remDe->AE_inv_id_pres;
|
||
|
|
aarq_apdu.called_ae_title.AE_inv_id = remDe->AE_invoke_id;
|
||
|
|
#endif /* !defined(MAP30_ACSE) */
|
||
|
|
|
||
|
|
#ifdef REDUCED_STACK
|
||
|
|
/* For Reduced Stack, the presentation address consists only of the */
|
||
|
|
/* ADLC address. */
|
||
|
|
aarq_apdu.called_paddr.adlcAddr = remDe->adlcAddr;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef LEAN_T
|
||
|
|
/* For Trim 7, the presentation address has all the parts */
|
||
|
|
memcpy (&aarq_apdu.called_paddr, &remDe->pres_addr, sizeof (PRES_ADDR));
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* ACSE Authentication */
|
||
|
|
if(auth_info != NULL)
|
||
|
|
memcpy (&aarq_apdu.auth_info, auth_info, sizeof (ACSE_AUTH_INFO));
|
||
|
|
else
|
||
|
|
aarq_apdu.auth_info.auth_pres = SD_FALSE;
|
||
|
|
/* copy encryption info */
|
||
|
|
if (encrypt_info != NULL)
|
||
|
|
memcpy (&aarq_apdu.encrypt_ctrl, encrypt_info, sizeof (S_SEC_ENCRYPT_CTRL));
|
||
|
|
else
|
||
|
|
aarq_apdu.encrypt_ctrl.encryptMode = S_SEC_ENCRYPT_NONE;
|
||
|
|
|
||
|
|
/* User Data */
|
||
|
|
aarq_apdu.user_info.ptr = mmsl_msg_start;
|
||
|
|
aarq_apdu.user_info.len = mmsl_msg_len;
|
||
|
|
|
||
|
|
MVL_LOG_ACSEDATAH (mmsl_msg_len, mmsl_msg_start);
|
||
|
|
|
||
|
|
/* Send the associate request */
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
acse_conn_id = a_associate_reqm (cc->bind_ctrl->copp_bind_id,
|
||
|
|
(ST_LONG) cc, &aarq_apdu,
|
||
|
|
cc->bind_ctrl->ar_name, remAr);
|
||
|
|
#elif defined(LEAN_T)
|
||
|
|
if (remDe->pres_addr.tp_type == TP_TYPE_TCP)
|
||
|
|
acse_conn_id = a_associate_req (cc->bind_ctrl->copp_bind_id_tcp, (ST_LONG) cc, &aarq_apdu);
|
||
|
|
else
|
||
|
|
acse_conn_id = a_associate_req (cc->bind_ctrl->copp_bind_id_tp4, (ST_LONG) cc, &aarq_apdu);
|
||
|
|
#else
|
||
|
|
acse_conn_id = a_associate_req (cc->bind_ctrl->copp_bind_id, (ST_LONG) cc, &aarq_apdu);
|
||
|
|
#endif
|
||
|
|
if (!acse_conn_id)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("ACSE: a_associate_req failed");
|
||
|
|
rc = MVL_ERR_ASSOC_REQ;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
++mvl_mms_statistics.callingConn;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: Remote name '%s' not found", remAr);
|
||
|
|
rc = MVLE_REMOTE_NAME;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: mpl_init error '0x%x'", rc);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (rc == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
*net_info_out = cc;
|
||
|
|
cc->acse_conn_id = acse_conn_id;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
mvl_free_req_ctrl (req);
|
||
|
|
*req_out = NULL; /* So user CANNOT free it too. */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* All is good, return the connection control too */
|
||
|
|
return (rc);
|
||
|
|
}
|
||
|
|
/************************************************************************/
|
||
|
|
#endif /* #if (MMS_INIT_EN & REQ_EN) */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_abort_req */
|
||
|
|
/* mvl_abort_req_ex */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvl_abort_req (MVL_NET_INFO *cc)
|
||
|
|
{
|
||
|
|
return (mvl_abort_req_ex (cc, SD_FALSE, 0));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
ST_RET mvl_abort_req_ex (MVL_NET_INFO *cc,
|
||
|
|
ST_BOOLEAN diagnostic_pres,
|
||
|
|
ST_ACSE_AUTH diagnostic)
|
||
|
|
{
|
||
|
|
ABRT_APDU abrtinfo;
|
||
|
|
ST_RET ret;
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: sending abort for MVL_NET_INFO %08lx", cc);
|
||
|
|
|
||
|
|
abrtinfo.source = 0; /* user */
|
||
|
|
abrtinfo.diagnostic_pres = diagnostic_pres;
|
||
|
|
abrtinfo.diagnostic = diagnostic;
|
||
|
|
abrtinfo.user_info.len = 0;
|
||
|
|
|
||
|
|
ret = a_abort_req (cc->acse_conn_id, &abrtinfo);
|
||
|
|
if (ret == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
++mvl_mms_statistics.localAbort;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
cc->conn_active = SD_FALSE;
|
||
|
|
if (_mvlu_rpt_disconnect_rcvd_fun != NULL)
|
||
|
|
(*_mvlu_rpt_disconnect_rcvd_fun)(cc);
|
||
|
|
_mvl_set_net_req_done (NULL, cc, MVL_ERR_CNF_DISCONNECTED);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: Abort error '0x%x'", ret);
|
||
|
|
echo_warn1("ACSE: Abort error '0x%x'\n", ret);
|
||
|
|
}
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_release_req */
|
||
|
|
/* mvla_release_req */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvl_release_req (MVL_NET_INFO *cc)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("ACSE: Using obsolete function 'mvl_release_req'");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
ST_INT mvla_release_req (MVL_NET_INFO *cc, MVL_REQ_PEND **req_out)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("ACSE: Using obsolete function 'mvla_release_req'");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* _mvla_release */
|
||
|
|
/************************************************************************/
|
||
|
|
/* Called from conclude confirm */
|
||
|
|
|
||
|
|
ST_VOID _mvl_release (MVL_REQ_PEND *req)
|
||
|
|
{
|
||
|
|
RLRQ_APDU rlinfo;
|
||
|
|
ST_INT ret;
|
||
|
|
MVL_NET_INFO *net_info;
|
||
|
|
|
||
|
|
net_info = req->net_info;
|
||
|
|
req->op = MVL_MMSOP_RELEASE; /* Change the opcode in the req ctrl */
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: sending release for MVL_NET_INFO %08lx", net_info);
|
||
|
|
|
||
|
|
rlinfo.reason_pres = SD_TRUE;
|
||
|
|
rlinfo.reason = 1;
|
||
|
|
rlinfo.user_info.len = 0;
|
||
|
|
ret = a_release_req (net_info->acse_conn_id, &rlinfo);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: Release error '0x%x'", ret);
|
||
|
|
_mvl_set_req_done (req, SD_FAILURE);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
++mvl_mms_statistics.clientConcl;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_add_bind_ctrl */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvl_add_bind_ctrl (NET_BIND_CTRL *bc)
|
||
|
|
{
|
||
|
|
NET_BIND_CTRL *mvlBc;
|
||
|
|
ST_BOOLEAN activate;
|
||
|
|
ST_INT i;
|
||
|
|
ST_RET rc;
|
||
|
|
|
||
|
|
/* First let's check to see if we have room for one more */
|
||
|
|
if (mvl_cfg_info->num_bind_ctrl >= mvl_cfg_info->max_bind_ctrl)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("Error: no availble bind control");
|
||
|
|
return (SD_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Let's see if this local AR has already been activated */
|
||
|
|
activate = SD_TRUE;
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_bind_ctrl; ++i)
|
||
|
|
{
|
||
|
|
if (!strcmp (mvl_cfg_info->bind_ctrl[i].ar_name, bc->ar_name))
|
||
|
|
{
|
||
|
|
activate = SD_FALSE;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* OK, now we can copy the bind control information */
|
||
|
|
|
||
|
|
mvlBc = &mvl_cfg_info->bind_ctrl[mvl_cfg_info->num_bind_ctrl];
|
||
|
|
*mvlBc = *bc;
|
||
|
|
++mvl_cfg_info->num_bind_ctrl;
|
||
|
|
|
||
|
|
rc = ma_bind (mvlBc, activate);
|
||
|
|
return (rc);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_bind */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_RET ma_bind (NET_BIND_CTRL *bc, ST_BOOLEAN activate)
|
||
|
|
{
|
||
|
|
#if !defined(MAP30_ACSE)
|
||
|
|
DIB_ENTRY *de;
|
||
|
|
PRES_ADDR loc_pres_addr;
|
||
|
|
#endif
|
||
|
|
ST_INT ret;
|
||
|
|
ST_INT numConn;
|
||
|
|
MVL_NET_INFO *ni;
|
||
|
|
ST_INT j;
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: binding local name '%s'", bc->ar_name);
|
||
|
|
|
||
|
|
#if !defined(MAP30_ACSE)
|
||
|
|
/* Locate the local DIB entry for this name, so we can find the addr */
|
||
|
|
de = find_loc_dib_entry (bc->ar_name);
|
||
|
|
if (!de)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR1 ("Error: Local AR name '%s' not found", bc->ar_name);
|
||
|
|
return (MVLE_LOCAL_NAME);
|
||
|
|
}
|
||
|
|
bc->de = de;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (((bc->num_calling + mvl_cfg_info->calling_used) > mvl_cfg_info->num_calling) ||
|
||
|
|
((bc->num_called + mvl_cfg_info->called_used) > mvl_cfg_info->num_called))
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Error: not enough connections");
|
||
|
|
return (MVLE_NUM_CONNECTIONS);
|
||
|
|
}
|
||
|
|
numConn = bc->num_calling + bc->num_called;
|
||
|
|
|
||
|
|
#ifdef REDUCED_STACK
|
||
|
|
/* For Reduced Stack, the presentation address consists only of the */
|
||
|
|
/* ADLC address. */
|
||
|
|
loc_pres_addr.adlcAddr = de->adlcAddr;
|
||
|
|
/* We make the binds synchronous */
|
||
|
|
ma_cmd_done = SD_FALSE;
|
||
|
|
ma_cmd_rslt = REQ_INCOMPLETE;
|
||
|
|
ret = copp_bind ((ST_LONG) bc, &loc_pres_addr, SD_FALSE, numConn);
|
||
|
|
ma_wait_req_done (&ret);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR2 ("Error: copp_bind (TCP) of AR '%s' returned '0x%x'",
|
||
|
|
bc->ar_name, ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef LEAN_T
|
||
|
|
/* For Trim 7, the presentation address has all the parts */
|
||
|
|
memcpy (&loc_pres_addr, &de->pres_addr, sizeof (PRES_ADDR));
|
||
|
|
if (de->pres_addr.tp_type == TP_TYPE_TPX)
|
||
|
|
{ /* do 2 binds */
|
||
|
|
/* Bind for TP4 (overwrite the "tp_type" in loc_pres_addr). */
|
||
|
|
bc->tp_type = loc_pres_addr.tp_type = TP_TYPE_TP4;
|
||
|
|
ma_cmd_done = SD_FALSE;
|
||
|
|
ma_cmd_rslt = REQ_INCOMPLETE;
|
||
|
|
ret = copp_bind ((ST_LONG) bc, &loc_pres_addr, SD_FALSE, numConn);
|
||
|
|
ma_wait_req_done (&ret);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR2 ("Error: copp_bind (TP4) of AR '%s' returned '0x%x'",
|
||
|
|
bc->ar_name, ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Bind for TCP (overwrite the "tp_type" in loc_pres_addr). */
|
||
|
|
bc->tp_type = loc_pres_addr.tp_type = TP_TYPE_TCP;
|
||
|
|
ret = copp_bind ((ST_LONG) bc, &loc_pres_addr, SD_FALSE, numConn);
|
||
|
|
ma_wait_req_done (&ret);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR2 ("Error: copp_bind (TCP) of AR '%s' returned '0x%x'",
|
||
|
|
bc->ar_name, ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else /* Not TPX */
|
||
|
|
{
|
||
|
|
bc->tp_type = loc_pres_addr.tp_type;
|
||
|
|
ma_cmd_done = SD_FALSE;
|
||
|
|
ma_cmd_rslt = REQ_INCOMPLETE;
|
||
|
|
ret = copp_bind ((ST_LONG) bc, &loc_pres_addr, SD_FALSE, numConn);
|
||
|
|
ma_wait_req_done (&ret);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR2 ("Error: copp_bind of AR '%s' returned '0x%x'",
|
||
|
|
bc->ar_name, ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
ma_cmd_done = SD_FALSE;
|
||
|
|
ma_cmd_rslt = REQ_INCOMPLETE;
|
||
|
|
ret = _copp_bind ((ST_LONG) bc, bc->ar_name, bc->num_calling, bc->num_called, activate);
|
||
|
|
ma_wait_req_done (&ret);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR2 ("Error: copp_bind of AR '%s' failed '0x%x'",
|
||
|
|
bc->ar_name, ret);
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
#endif /* defined(MAP30_ACSE) */
|
||
|
|
|
||
|
|
MVL_LOG_ACSE0 ("ACSE: bind OK");
|
||
|
|
|
||
|
|
|
||
|
|
/* OK, now attach the bind controls to the MVL_NET_INFO */
|
||
|
|
ni = mvl_called_conn_ctrl + mvl_cfg_info->called_used;
|
||
|
|
for (j = 0; j < bc->num_called; ++j, ++ni)
|
||
|
|
ni->bind_ctrl = bc;
|
||
|
|
|
||
|
|
ni = mvl_calling_conn_ctrl + mvl_cfg_info->calling_used;
|
||
|
|
for (j = 0; j < bc->num_calling; ++j, ++ni)
|
||
|
|
ni->bind_ctrl = bc;
|
||
|
|
|
||
|
|
mvl_cfg_info->calling_used += bc->num_calling;
|
||
|
|
mvl_cfg_info->called_used += bc->num_called;
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* copp_unbind_sync */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_VOID copp_unbind_sync (ST_LONG copp_bind_id)
|
||
|
|
{
|
||
|
|
ST_RET ret;
|
||
|
|
|
||
|
|
ma_cmd_done = SD_FALSE;
|
||
|
|
ma_cmd_rslt = REQ_INCOMPLETE;
|
||
|
|
ret = copp_unbind (copp_bind_id);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR1 ("Error: unbind result '0x%x'", ret);
|
||
|
|
}
|
||
|
|
else /* Now just wait for the 'confirm' function to be called */
|
||
|
|
ma_wait_req_done (&ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* COACSE USER FUNCTIONS */
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_copp_bind_cnf */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_copp_bind_cnf (ST_LONG user_bind_id, ST_LONG copp_bind_id, ST_INT result)
|
||
|
|
{
|
||
|
|
NET_BIND_CTRL *bc;
|
||
|
|
|
||
|
|
/* Save the acse interface's bind ID for future use */
|
||
|
|
bc = (NET_BIND_CTRL *) user_bind_id;
|
||
|
|
#ifdef LEAN_T
|
||
|
|
if (bc->tp_type == TP_TYPE_TP4)
|
||
|
|
bc->copp_bind_id_tp4 = copp_bind_id;
|
||
|
|
else
|
||
|
|
bc->copp_bind_id_tcp = copp_bind_id;
|
||
|
|
#else
|
||
|
|
bc->copp_bind_id = copp_bind_id;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* Allow sync binds to complete */
|
||
|
|
ma_cmd_done = SD_TRUE;
|
||
|
|
ma_cmd_rslt = result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_copp_unbind_cnf */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_copp_unbind_cnf (ST_LONG user_bind_id)
|
||
|
|
{
|
||
|
|
/* Allow the request function to complete */
|
||
|
|
ma_cmd_done = SD_TRUE;
|
||
|
|
ma_cmd_rslt = SD_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_associate_ind */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_associate_ind (ST_LONG u_bind_id, ST_LONG acse_conn_id,
|
||
|
|
AARQ_APDU *info)
|
||
|
|
{
|
||
|
|
#if (MMS_INIT_EN & RESP_EN)
|
||
|
|
|
||
|
|
MMSDEC_INFO rslt;
|
||
|
|
INIT_INFO *init_req;
|
||
|
|
INIT_INFO init_resp;
|
||
|
|
MVL_NET_INFO *cc;
|
||
|
|
#if !defined(ICCP_LITE)
|
||
|
|
ST_ACSE_AUTH auth_ret;
|
||
|
|
#endif
|
||
|
|
ST_INT ret;
|
||
|
|
AARE_APDU reinfo;
|
||
|
|
ST_INT accept;
|
||
|
|
ST_BOOLEAN free_dec_info;
|
||
|
|
MVL_ASSOC_IND *mvlAssocInd;
|
||
|
|
AARQ_APDU *reqinfo;
|
||
|
|
ST_UCHAR *user_info_buf;
|
||
|
|
|
||
|
|
if (mvl_init_ind_hold)
|
||
|
|
{
|
||
|
|
/* Can't rely on this data being persistent */
|
||
|
|
/* Allocate buffer big enough for the control structure, */
|
||
|
|
/* the AARQ info, and the user data */
|
||
|
|
mvlAssocInd = chk_malloc (sizeof (MVL_ASSOC_IND) +
|
||
|
|
sizeof (AARQ_APDU) +
|
||
|
|
info->user_info.len);
|
||
|
|
mvlAssocInd->u_bind_id = u_bind_id;
|
||
|
|
mvlAssocInd->acse_conn_id = acse_conn_id;
|
||
|
|
|
||
|
|
/* Copy the AARQ data */
|
||
|
|
reqinfo = (AARQ_APDU *) (mvlAssocInd + 1);
|
||
|
|
*reqinfo = *info;
|
||
|
|
mvlAssocInd->info = reqinfo;
|
||
|
|
|
||
|
|
/* Copy the user data, set the pointer to it */
|
||
|
|
user_info_buf = (ST_UCHAR *) (reqinfo + 1);
|
||
|
|
reqinfo->user_info.ptr = user_info_buf;
|
||
|
|
memcpy (user_info_buf, info->user_info.ptr, info->user_info.len);
|
||
|
|
|
||
|
|
list_add_last (&mvlAssocIndList, mvlAssocInd);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined(_S_TEST_PROBES)
|
||
|
|
if (_sTestProbeEnabled(_MI_TEST_INITIATE_IND_NO_RESPOND))
|
||
|
|
{
|
||
|
|
echo_warn ("TEST: Initiate indication, do not respond");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
++mvl_mms_statistics.calledConn;
|
||
|
|
|
||
|
|
MVL_LOG_ACSE0 ("ACSE: Associate Indication received");
|
||
|
|
MVL_LOG_ACSEDATAH (info->user_info.len, info->user_info.ptr);
|
||
|
|
|
||
|
|
free_dec_info = SD_FALSE;
|
||
|
|
|
||
|
|
/* Assume the worst ... */
|
||
|
|
accept = SD_FALSE;
|
||
|
|
reinfo.user_info.len = 0;
|
||
|
|
reinfo.auth_info.auth_pres = SD_FALSE;
|
||
|
|
|
||
|
|
/* Get a 'called' connection control structure, if one is available */
|
||
|
|
cc = ma_get_called_conn_ctrl ((NET_BIND_CTRL *) u_bind_id);
|
||
|
|
if (cc)
|
||
|
|
{
|
||
|
|
MVL_LOG_CACSE1 ("Using MVL_NET_INFO %08lx", cc);
|
||
|
|
|
||
|
|
/* Copy the whole AARQ Info struct, for the user to see */
|
||
|
|
memcpy (&cc->ass_ind_info, info, sizeof (AARQ_APDU));
|
||
|
|
|
||
|
|
/* IMPORTANT: Save the ACSE connection ID before calling user funtions.*/
|
||
|
|
cc->acse_conn_id = acse_conn_id;
|
||
|
|
|
||
|
|
/* We need to parse the MMS Initiate PDU */
|
||
|
|
free_dec_info = SD_TRUE;
|
||
|
|
_ms_mms_decode (info->user_info.ptr, info->user_info.len, &rslt);
|
||
|
|
if (rslt.err_code == NO_DECODE_ERR && rslt.type == MMSINITREQ)
|
||
|
|
{
|
||
|
|
init_req = (INIT_INFO *) rslt.data_ptr;
|
||
|
|
init_req->mms_p_context_pres = SD_TRUE;
|
||
|
|
|
||
|
|
/* We can log here if so desired */
|
||
|
|
if ((mms_debug_sel & MMS_LOG_IND) && ml_log_ind_info_fun != NULL)
|
||
|
|
(*ml_log_ind_info_fun) (0, MMSOP_INITIATE, init_req);
|
||
|
|
|
||
|
|
/* OK, we handle telling the user differently depending on whether this */
|
||
|
|
/* is ICCP Lite, and whether ACSE Authentication is in use or not */
|
||
|
|
#ifdef ICCP_LITE
|
||
|
|
ret = mi_connect_ind_fun (cc, init_req, &reinfo.auth_info);
|
||
|
|
#else
|
||
|
|
/* Let the user have a look to see if they want to accept */
|
||
|
|
auth_ret = u_mvl_connect_ind_ex(cc, init_req,
|
||
|
|
&cc->ass_ind_info.auth_info, /* partner authentication */
|
||
|
|
&reinfo.auth_info); /* ret rsp authentication */
|
||
|
|
/* User did not like something about the authentication */
|
||
|
|
if (auth_ret != ACSE_AUTH_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: ACSE Authentication failure. Reason: %d", auth_ret);
|
||
|
|
mvl_abort_req_ex (cc, SD_TRUE, auth_ret);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
ret = SD_SUCCESS; /* User is OK with it */
|
||
|
|
#endif /* ICCP_LITE */
|
||
|
|
|
||
|
|
if (ret == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
/* Build an initiate response PDU, negiotiating the calling init */
|
||
|
|
/* parameters vs. what we support */
|
||
|
|
|
||
|
|
#ifdef NEGIOTIATE_INITIATE_PARAM
|
||
|
|
/* Start with the default initiate response info */
|
||
|
|
memcpy (&init_resp, mvl_init_resp_info, sizeof (INIT_INFO));
|
||
|
|
if (init_req->version < init_resp.version)/* thiers is lower */
|
||
|
|
init_resp.version = init_req->version; /* accept lower version */
|
||
|
|
if (init_req->max_segsize_pres)
|
||
|
|
{
|
||
|
|
if (init_req->max_segsize < init_resp.max_segsize)
|
||
|
|
init_resp.max_segsize = init_req->max_segsize;
|
||
|
|
}
|
||
|
|
if (init_req->maxreq_calling < init_resp.maxreq_calling)
|
||
|
|
init_resp.maxreq_calling = init_req->maxreq_calling;
|
||
|
|
if (init_req->maxreq_called < init_resp.maxreq_called)
|
||
|
|
init_resp.maxreq_called = init_req->maxreq_called;
|
||
|
|
if (init_req->max_nest_pres)
|
||
|
|
{
|
||
|
|
if (init_req->max_nest < init_resp.max_nest)
|
||
|
|
init_resp.max_nest = init_req->max_nest;
|
||
|
|
}
|
||
|
|
/* These 'supported' bitstring parameters are set up in mmsop_en.c */
|
||
|
|
memcpy (init_resp.serv_supp, m_service_resp, 11);
|
||
|
|
init_resp.param_supp[0] = m_param[0] & init_req->param_supp[0];
|
||
|
|
init_resp.param_supp[1] = m_param[1] & init_req->param_supp[1];
|
||
|
|
#else
|
||
|
|
/* Just send back what the user wants to send */
|
||
|
|
memcpy (&init_resp, mvl_init_resp_info, sizeof (INIT_INFO));
|
||
|
|
#endif
|
||
|
|
|
||
|
|
ret = mpl_init_resp (&init_resp);
|
||
|
|
if (ret == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
/* We can log here if so desired */
|
||
|
|
if ((mms_debug_sel & MMS_LOG_RESP) && ml_log_resp_info_fun != NULL)
|
||
|
|
(*ml_log_resp_info_fun) (0, MMSOP_INITIATE, &init_resp);
|
||
|
|
|
||
|
|
accept = SD_TRUE;
|
||
|
|
|
||
|
|
cc->conn_active = SD_TRUE;
|
||
|
|
|
||
|
|
/* Save the remote node's initiate information */
|
||
|
|
memcpy (&cc->rem_init_info, init_req, sizeof (INIT_INFO));
|
||
|
|
memcpy (&cc->locl_init_info, &init_resp, sizeof (INIT_INFO));
|
||
|
|
cc->max_pdu_size = (ST_INT) init_resp.max_segsize;
|
||
|
|
/* NOTE: maxreq_calling = num of outstanding indications */
|
||
|
|
/* allowed at the calling app (similar for maxreq_called). */
|
||
|
|
cc->maxpend_req = init_resp.maxreq_calling;
|
||
|
|
cc->maxpend_ind = init_resp.maxreq_called;
|
||
|
|
cc->numpend_req = 0;
|
||
|
|
cc->numpend_ind = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("ACSE: User does not want connection");
|
||
|
|
ret = mpl_init_err (8, 0);
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ret == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
reinfo.user_info.len = mmsl_msg_len;
|
||
|
|
reinfo.user_info.ptr = mmsl_msg_start;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("ACSE: Initiate indication PDU parse error");
|
||
|
|
free_dec_info = SD_FALSE;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Error - Could not get called MVL_NET_INFO");
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Initiate Response (or error) PDU is built, or len set to 0. */
|
||
|
|
/* Set the remaining ACSE parameters and send the response */
|
||
|
|
|
||
|
|
/* Use the calling context as the responding, to be friendly */
|
||
|
|
reinfo.ASO_context_name_pres = info->ASO_context_name_pres;
|
||
|
|
memcpy (&reinfo.ASO_context_name, &info->ASO_context_name,
|
||
|
|
sizeof (MMS_OBJ_ID));
|
||
|
|
|
||
|
|
/* For now, just reflect the ACSE indication information */
|
||
|
|
/* Note that it may (or may not) be more appropriate to use the 'local' */
|
||
|
|
/* DIB_ENTRY info for this purpose. */
|
||
|
|
memcpy (&reinfo.responding_ae_title, &info->called_ae_title,
|
||
|
|
sizeof (AE_TITLE));
|
||
|
|
|
||
|
|
|
||
|
|
if (accept)
|
||
|
|
{
|
||
|
|
MVL_LOG_ACSE0 ("Accepting the connection");
|
||
|
|
reinfo.result = 0; /* ACCEPT */
|
||
|
|
reinfo.result_source_diag_pres = SD_FALSE;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_ACSE0 ("Rejecting the connection");
|
||
|
|
reinfo.result = 1; /* REJECT */
|
||
|
|
reinfo.result_source_diag_pres = SD_TRUE;
|
||
|
|
reinfo.result_source = 1;
|
||
|
|
reinfo.result_diag = 9;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Send ACSE response */
|
||
|
|
MVL_LOG_ACSEDATAH (reinfo.user_info.len, reinfo.user_info.ptr);
|
||
|
|
ret = a_associate_rsp (acse_conn_id, (ST_LONG) cc, &reinfo);
|
||
|
|
if (ret != SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: a_associate_rsp error '0x%x", ret);
|
||
|
|
if (cc != NULL)
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
++mvl_mms_statistics.calledConnFail;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
++mvl_mms_statistics.calledConnOK;
|
||
|
|
|
||
|
|
|
||
|
|
if (free_dec_info == SD_TRUE)
|
||
|
|
M_FREE (MSMEM_DEC_OS_INFO, _mms_dec_info);
|
||
|
|
|
||
|
|
#else /* !(MMS_INIT_EN & RESP_EN) */
|
||
|
|
|
||
|
|
AARE_APDU reinfo;
|
||
|
|
ST_LONG user_conn_id;
|
||
|
|
ST_INT ret;
|
||
|
|
|
||
|
|
++mvl_mms_statistics.calledConn;
|
||
|
|
|
||
|
|
/* Incoming connections not supported, so Reject the association. */
|
||
|
|
MVL_LOG_ACSE0 ("ACSE: Associate Indication received. Rejecting.");
|
||
|
|
|
||
|
|
/* Just use the ASO-context from the request in the response. */
|
||
|
|
reinfo.ASO_context_name_pres = info->ASO_context_name_pres;
|
||
|
|
memcpy (&reinfo.ASO_context_name, &info->ASO_context_name,
|
||
|
|
sizeof (MMS_OBJ_ID));
|
||
|
|
|
||
|
|
/* Just use the called AE-Title as the responding AE-Title. */
|
||
|
|
memcpy (&reinfo.responding_ae_title, &info->called_ae_title,
|
||
|
|
sizeof (AE_TITLE));
|
||
|
|
|
||
|
|
/* Reject */
|
||
|
|
reinfo.result = 1; /* Rejected-permanent */
|
||
|
|
reinfo.result_source_diag_pres = SD_TRUE;
|
||
|
|
reinfo.result_source = 1; /* Source = user. */
|
||
|
|
reinfo.result_diag = 1; /* no-reason-given */
|
||
|
|
/* No User Information */
|
||
|
|
reinfo.user_info.len = 0;
|
||
|
|
reinfo.user_info.ptr = NULL;
|
||
|
|
reinfo.auth_info.auth_pres = SD_FALSE;
|
||
|
|
|
||
|
|
user_conn_id = 0; /* id doesn't matter because rejecting */
|
||
|
|
if ((ret = a_associate_rsp (acse_conn_id, user_conn_id, &reinfo))!=SD_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR1 ("Error sending a_associate_rsp. Error = %d", ret);
|
||
|
|
}
|
||
|
|
++mvl_mms_statistics.calledConnFail;
|
||
|
|
#endif /* !(MMS_INIT_EN & RESP_EN) */
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_associate_cnf */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_associate_cnf (ST_LONG acse_conn_id, ST_LONG user_conn_id,
|
||
|
|
AARE_APDU *info)
|
||
|
|
{
|
||
|
|
#if (MMS_INIT_EN & REQ_EN)
|
||
|
|
MMSDEC_INFO rslt;
|
||
|
|
MVL_NET_INFO *cc;
|
||
|
|
INIT_INFO *init_resp;
|
||
|
|
MVL_REQ_PEND *req;
|
||
|
|
ST_BOOLEAN free_dec_info;
|
||
|
|
ST_RET result;
|
||
|
|
ST_ACSE_AUTH auth_ret;
|
||
|
|
|
||
|
|
/* Need to save off the ACSE interface's connection ID for future use */
|
||
|
|
cc = (MVL_NET_INFO *) user_conn_id;
|
||
|
|
cc->acse_conn_id = acse_conn_id;
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: associate confirm for MVL_NET_INFO %08lx", cc);
|
||
|
|
|
||
|
|
req = _mvl_find_req_ctrl (cc, MMSOP_INITIATE, -1);
|
||
|
|
if (!req)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("ACSE: Associate Confirm - no matching req ctrl");
|
||
|
|
info->result = SD_FAILURE; /* Cause disconnect */
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Only check ACSE authentication if this is a positive connect confirm */
|
||
|
|
if (info->result == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
auth_ret = u_mvl_connect_cnf_ex(cc, info);
|
||
|
|
|
||
|
|
/* User did not like something about the authentication */
|
||
|
|
if(auth_ret != ACSE_AUTH_SUCCESS)
|
||
|
|
{
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: ACSE Authentication failure. Reason: %d", auth_ret);
|
||
|
|
mvl_abort_req_ex (cc, SD_TRUE, auth_ret);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
free_dec_info = SD_FALSE;
|
||
|
|
result = info->result;
|
||
|
|
|
||
|
|
if (info->result == SD_SUCCESS)
|
||
|
|
{
|
||
|
|
cc->conn_active = SD_TRUE;
|
||
|
|
|
||
|
|
MVL_LOG_ACSEDATAH (info->user_info.len, info->user_info.ptr);
|
||
|
|
|
||
|
|
/* OK, now we need to parse the MMS Initiate PDU */
|
||
|
|
free_dec_info = SD_TRUE;
|
||
|
|
_ms_mms_decode (info->user_info.ptr, info->user_info.len, &rslt);
|
||
|
|
if (rslt.err_code == NO_DECODE_ERR)
|
||
|
|
{
|
||
|
|
switch (rslt.type)
|
||
|
|
{
|
||
|
|
case MMSINITRESP :
|
||
|
|
init_resp = (INIT_INFO *) rslt.data_ptr;
|
||
|
|
init_resp->mms_p_context_pres = SD_TRUE;
|
||
|
|
|
||
|
|
/* We can log here if so desired */
|
||
|
|
/* if ((mms_debug_sel & MMS_LOG_CONF) && ml_log_conf_info_fun != NULL)
|
||
|
|
(*ml_log_conf_info_fun) (0, MMSOP_INITIATE, init_resp);*/
|
||
|
|
|
||
|
|
if (req->u.init.resp_info != NULL)
|
||
|
|
memcpy (req->u.init.resp_info, init_resp, sizeof (INIT_INFO));
|
||
|
|
|
||
|
|
memcpy (&cc->rem_init_info, init_resp, sizeof (INIT_INFO));
|
||
|
|
MVL_LOG_CACSE0 ("ACSE: initiate confirm OK");
|
||
|
|
cc->max_pdu_size = init_resp->max_segsize;
|
||
|
|
/* NOTE: maxreq_calling = num of outstanding indications */
|
||
|
|
/* allowed at the calling app (similar for maxreq_called). */
|
||
|
|
cc->maxpend_req = init_resp->maxreq_called;
|
||
|
|
cc->maxpend_ind = init_resp->maxreq_calling;
|
||
|
|
cc->numpend_req = 0;
|
||
|
|
cc->numpend_ind = 0;
|
||
|
|
++mvl_mms_statistics.callingConnOk;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MMSINITERR :
|
||
|
|
result = SD_FAILURE;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
MVL_LOG_NERR0 ("ACSE: initiate confirm error");
|
||
|
|
++mvl_mms_statistics.callingConnFail;
|
||
|
|
break;
|
||
|
|
|
||
|
|
default :
|
||
|
|
MVL_LOG_NERR1 ("ACSE: associate confirm PDU wrong type (%d)",
|
||
|
|
rslt.type);
|
||
|
|
result = SD_FAILURE;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
info->result = SD_FAILURE; /* Cause disconnect */
|
||
|
|
++mvl_mms_statistics.callingConnFail;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else /* PDU decode error, abort the connection */
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("ACSE: associate confirm PDU Decode Error");
|
||
|
|
result = SD_FAILURE;
|
||
|
|
info->result = SD_FAILURE; /* Cause disconnect */
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
++mvl_mms_statistics.callingConnFail;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("ACSE: associate confirm result != SD_SUCCESS");
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
++mvl_mms_statistics.callingConnFail;
|
||
|
|
}
|
||
|
|
|
||
|
|
_mvl_set_req_done (req, result);
|
||
|
|
|
||
|
|
if (free_dec_info == SD_TRUE && rslt.data_pres)
|
||
|
|
M_FREE (MSMEM_DEC_OS_INFO, rslt.data_ptr);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_data_ind */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_data_ind (ST_LONG user_conn_id, ST_UINT data_len, ST_UCHAR *data)
|
||
|
|
{
|
||
|
|
MVL_NET_INFO *ni;
|
||
|
|
MVL_COMM_EVENT *commEvent;
|
||
|
|
|
||
|
|
ni = (MVL_NET_INFO *) user_conn_id;
|
||
|
|
|
||
|
|
/* See if we are supposed to log ACSE data for this connection */
|
||
|
|
if (mvl_conn_filtered_logging == SD_FALSE || ni->log_enable)
|
||
|
|
{
|
||
|
|
MVL_LOG_ACSEDATA2 ("ACSE: Rx'd %d bytes on MVL_NET_INFO 0x%08lx",
|
||
|
|
data_len, ni);
|
||
|
|
MVL_LOG_ACSEDATAH (data_len, data);
|
||
|
|
}
|
||
|
|
|
||
|
|
commEvent = mvl_get_com_event ();
|
||
|
|
if (!commEvent)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("ACSE: Error - could not get MVL_COMM_EVENT");
|
||
|
|
u_a_except (user_conn_id, SD_FAILURE, __FILE__, __LINE__);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
commEvent->event_type = MMS_MSG_RCVD;
|
||
|
|
commEvent->net_info = ni;
|
||
|
|
commEvent->u.mms.pdu_len = data_len;
|
||
|
|
commEvent->u.mms.pdu = (ST_UCHAR *) M_MALLOC (MSMEM_RXPDU,data_len);
|
||
|
|
memcpy (commEvent->u.mms.pdu, data, data_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_release_ind */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_release_ind (ST_LONG user_conn_id, RLRQ_APDU *info)
|
||
|
|
{
|
||
|
|
RLRE_APDU reinfo;
|
||
|
|
MVL_NET_INFO *cc;
|
||
|
|
|
||
|
|
cc = (MVL_NET_INFO *) user_conn_id;
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: Release Indication received on MVL_NET_INFO 0x%08lx", cc);
|
||
|
|
++mvl_mms_statistics.serverConcl;
|
||
|
|
|
||
|
|
cc->conn_active = SD_FALSE;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
if (_mvlu_rpt_disconnect_rcvd_fun != NULL)
|
||
|
|
(*_mvlu_rpt_disconnect_rcvd_fun)(cc);
|
||
|
|
|
||
|
|
reinfo.reason_pres = SD_TRUE;
|
||
|
|
reinfo.reason = 1;
|
||
|
|
|
||
|
|
/* Send no data on the release response */
|
||
|
|
reinfo.user_info.len = 0;
|
||
|
|
reinfo.user_info.ptr = NULL;
|
||
|
|
a_release_rsp (cc->acse_conn_id, &reinfo);
|
||
|
|
|
||
|
|
/* Set any outstanding requests to 'done' */
|
||
|
|
_mvl_set_net_req_done (NULL, cc, SD_FAILURE);
|
||
|
|
|
||
|
|
#ifdef ICCP_LITE
|
||
|
|
if (cc->mi_in_use)
|
||
|
|
mi_release_ind_fun (cc);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (u_mvl_disc_ind_fun)
|
||
|
|
(*u_mvl_disc_ind_fun) (cc, MVL_ACSE_RELEASE_IND);
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
if (u_mvl_disc_ind_fun)
|
||
|
|
(*u_mvl_disc_ind_fun) (cc, MVL_ACSE_RELEASE_IND);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
cc->maxpend_req = 0;
|
||
|
|
cc->numpend_req = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_abort_ind */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_abort_ind (ST_LONG user_conn_id, ABRT_APDU *info)
|
||
|
|
{
|
||
|
|
MVL_NET_INFO *cc;
|
||
|
|
MVL_ASSOC_IND *mvlAssocInd;
|
||
|
|
ST_BOOLEAN conn_active;
|
||
|
|
|
||
|
|
cc = (MVL_NET_INFO *) user_conn_id;
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: Abort Indication received on MVL_NET_INFO 0x%08lx", cc);
|
||
|
|
|
||
|
|
/* This can happen if we have not responded to an initiate indication */
|
||
|
|
/* In this case, just flush the initiate indication hold list */
|
||
|
|
if (cc == NULL)
|
||
|
|
{
|
||
|
|
while (mvlAssocIndList)
|
||
|
|
{
|
||
|
|
mvlAssocInd = list_get_first (&mvlAssocIndList);
|
||
|
|
chk_free (mvlAssocInd);
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
++mvl_mms_statistics.remoteAbort;
|
||
|
|
|
||
|
|
/* Verify we can safely use this as a MVL_NET_INFO */
|
||
|
|
if (user_conn_id == -1L)
|
||
|
|
return;
|
||
|
|
|
||
|
|
conn_active = cc->conn_active;
|
||
|
|
cc->conn_active = SD_FALSE;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
if (_mvlu_rpt_disconnect_rcvd_fun != NULL)
|
||
|
|
(*_mvlu_rpt_disconnect_rcvd_fun)(cc);
|
||
|
|
|
||
|
|
/* Set any outstanding requests to 'done' */
|
||
|
|
_mvl_set_net_req_done (NULL, cc, MVL_ERR_CNF_DISCONNECTED);
|
||
|
|
if (conn_active == SD_TRUE)
|
||
|
|
{
|
||
|
|
#ifdef ICCP_LITE
|
||
|
|
if (cc->mi_in_use == SD_TRUE)
|
||
|
|
mi_abort_ind_fun (cc);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (u_mvl_disc_ind_fun)
|
||
|
|
(*u_mvl_disc_ind_fun) (cc, MVL_ACSE_ABORT_IND);
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
if (u_mvl_disc_ind_fun)
|
||
|
|
(*u_mvl_disc_ind_fun) (cc, MVL_ACSE_ABORT_IND);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
cc->maxpend_req = 0;
|
||
|
|
cc->numpend_req = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_release_cnf */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_release_cnf (ST_LONG user_conn_id, RLRE_APDU *info)
|
||
|
|
{
|
||
|
|
MVL_NET_INFO *cc;
|
||
|
|
MVL_REQ_PEND *req;
|
||
|
|
|
||
|
|
|
||
|
|
cc = (MVL_NET_INFO *) user_conn_id;
|
||
|
|
|
||
|
|
MVL_LOG_ACSE1 ("ACSE: release confirm received for MVL_NET_INFO %08lx", cc);
|
||
|
|
|
||
|
|
/* Find the conclude request */
|
||
|
|
req = _mvl_find_req_ctrl (cc, MVL_MMSOP_RELEASE, -1);
|
||
|
|
if (!req)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("ACSE: Release Confirm - no matching req ctrl");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Set any outstanding requests to 'done' */
|
||
|
|
_mvl_set_net_req_done (req, cc, MVL_ERR_CNF_DISCONNECTED);
|
||
|
|
|
||
|
|
cc->conn_active = SD_FALSE;
|
||
|
|
cc->in_use = SD_FALSE;
|
||
|
|
if (_mvlu_rpt_disconnect_rcvd_fun != NULL)
|
||
|
|
(*_mvlu_rpt_disconnect_rcvd_fun)(cc);
|
||
|
|
|
||
|
|
_mvl_set_req_done (req, SD_SUCCESS);
|
||
|
|
cc->maxpend_req = 0;
|
||
|
|
cc->numpend_req = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* u_a_except */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID u_a_except (ST_LONG user_conn_id, ST_INT code,
|
||
|
|
ST_CHAR *filename, ST_INT line)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR2 ("ACSE: Error - Exception, code 0x%x, MVL_NET_INFO %08lx",
|
||
|
|
code, user_conn_id);
|
||
|
|
MVL_LOG_CERR2 ("File %s, Line %d", filename, line);
|
||
|
|
mvl_acse_ok = SD_FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* CONNECTION CONTROL RELATED STUFF */
|
||
|
|
/************************************************************************/
|
||
|
|
/* ma_get_called_conn_ctrl */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
#if (MMS_INIT_EN & RESP_EN)
|
||
|
|
|
||
|
|
static MVL_NET_INFO *ma_get_called_conn_ctrl (NET_BIND_CTRL *bc)
|
||
|
|
{
|
||
|
|
MVL_NET_INFO *ni;
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
ni = mvl_called_conn_ctrl;
|
||
|
|
for (i = 0; i < mvl_cfg_info->called_used; ++i, ++ni)
|
||
|
|
{
|
||
|
|
/* CRITICAL: don't reuse 'ni' until req_pend_list cleaned up from */
|
||
|
|
/* last conn. May be waiting for user to call mvl_free_req_ctrl. */
|
||
|
|
if (!ni->in_use && ni->req_pend_list==NULL)
|
||
|
|
{
|
||
|
|
if (bc == NULL || !strcmp (bc->ar_name, ni->bind_ctrl->ar_name))
|
||
|
|
{
|
||
|
|
ni->in_use = SD_TRUE;
|
||
|
|
ni->conn_active = SD_FALSE;
|
||
|
|
return (ni);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* ma_get_calling_conn_ctrl */
|
||
|
|
/************************************************************************/
|
||
|
|
#if (MMS_INIT_EN & REQ_EN)
|
||
|
|
|
||
|
|
static MVL_NET_INFO *ma_get_calling_conn_ctrl (NET_BIND_CTRL *bc)
|
||
|
|
{
|
||
|
|
MVL_NET_INFO *ni;
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
ni = mvl_calling_conn_ctrl;
|
||
|
|
for (i = 0; i < mvl_cfg_info->calling_used; ++i, ++ni)
|
||
|
|
{
|
||
|
|
/* CRITICAL: don't reuse 'ni' until req_pend_list cleaned up from */
|
||
|
|
/* last conn. May be waiting for user to call mvl_free_req_ctrl. */
|
||
|
|
if (!ni->in_use && ni->req_pend_list==NULL)
|
||
|
|
{
|
||
|
|
if (bc == NULL || !strcmp (bc->ar_name, ni->bind_ctrl->ar_name))
|
||
|
|
{
|
||
|
|
ni->in_use = SD_TRUE;
|
||
|
|
ni->conn_active = SD_FALSE;
|
||
|
|
return (ni);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
#endif /* End of COACSE specific functions */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
#if defined(CLACSE) /* CONNECTIONLESS ACSE FUNCTIONS */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_get_com_event */
|
||
|
|
/************************************************************************/
|
||
|
|
/* This function is used to get a MVL_COMM_EVENT control buffer to be */
|
||
|
|
/* passed up to the caller of '_mvl_net_service'. */
|
||
|
|
|
||
|
|
static MVL_NET_INFO *mvl_get_net_info (ST_VOID)
|
||
|
|
{
|
||
|
|
MVL_NET_INFO *netInfo;
|
||
|
|
|
||
|
|
#if 1
|
||
|
|
netInfo = (MVL_NET_INFO *) M_CALLOC (MSMEM_NETINFO, 1, sizeof (MVL_NET_INFO));
|
||
|
|
if (netInfo == NULL)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Error: No MVL_NET_INFO available");
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
if (mvl_net_info_avail_head)
|
||
|
|
netInfo = (MVL_NET_INFO *) list_get_first((ST_VOID **) &mvl_net_info_avail_head);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (mvl_net_info_count >= mvl_max_net_info)
|
||
|
|
{
|
||
|
|
MVL_LOG_ERR0 ("Error: No MVL_NET_INFO available");
|
||
|
|
return (NULL);
|
||
|
|
}
|
||
|
|
++mvl_net_info_count;
|
||
|
|
netInfo = (MVL_NET_INFO *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_NET_INFO));
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return (netInfo);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_init_audt_addr */
|
||
|
|
/* User must pass pointer (AUDT_APDU *) to their struct. */
|
||
|
|
/* This function fills in the addressing info in the struct. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvl_init_audt_addr (AUDT_APDU *audt, ST_CHAR *locArName, ST_CHAR *remArName)
|
||
|
|
{
|
||
|
|
DIB_ENTRY *locDe;
|
||
|
|
DIB_ENTRY *remDe;
|
||
|
|
|
||
|
|
/* Retrieve the DIB_ENTRY's for local and remote. These are used to set */
|
||
|
|
/* the AUDT_APDU information */
|
||
|
|
|
||
|
|
locDe = find_loc_dib_entry (locArName);
|
||
|
|
if (!locDe)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: Local name '%s' not found", locArName);
|
||
|
|
return (MVLE_LOCAL_NAME);
|
||
|
|
}
|
||
|
|
|
||
|
|
remDe = find_rem_dib_entry (remArName);
|
||
|
|
if (!remDe)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: Remote name '%s' not found", remArName);
|
||
|
|
return (MVLE_REMOTE_NAME);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (remDe->pres_addr.tp_type != TP_TYPE_TP4) /* must be TP4 (need NSAP) */
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR1 ("ACSE: Remote name '%s' is not TP4 Transport type", remArName);
|
||
|
|
return (MVLE_REMOTE_NAME);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* AP Context is MMS */
|
||
|
|
audt->ASO_context_name_pres = SD_TRUE;
|
||
|
|
audt->ASO_context_name.num_comps = 5;
|
||
|
|
audt->ASO_context_name.comps[0] = 1;
|
||
|
|
audt->ASO_context_name.comps[1] = 0;
|
||
|
|
audt->ASO_context_name.comps[2] = 9506;
|
||
|
|
audt->ASO_context_name.comps[3] = 2;
|
||
|
|
audt->ASO_context_name.comps[4] = 3;
|
||
|
|
|
||
|
|
/* Calling Addressing information */
|
||
|
|
audt->calling_ae_title.AP_title_pres = locDe->AP_title_pres;
|
||
|
|
memcpy (&audt->calling_ae_title.AP_title, &locDe->AP_title,
|
||
|
|
sizeof (MMS_OBJ_ID));
|
||
|
|
|
||
|
|
audt->calling_ae_title.AE_qual_pres = locDe->AE_qual_pres;
|
||
|
|
audt->calling_ae_title.AE_qual = locDe->AE_qual;
|
||
|
|
audt->calling_ae_title.AP_inv_id_pres = locDe->AP_inv_id_pres;
|
||
|
|
audt->calling_ae_title.AP_inv_id = locDe->AP_invoke_id;
|
||
|
|
audt->calling_ae_title.AE_qual_pres = locDe->AE_qual_pres;
|
||
|
|
audt->calling_ae_title.AE_qual = locDe->AE_qual;
|
||
|
|
audt->calling_ae_title.AE_inv_id_pres = locDe->AE_inv_id_pres;
|
||
|
|
audt->calling_ae_title.AE_inv_id = locDe->AE_invoke_id;
|
||
|
|
|
||
|
|
memcpy (&audt->calling_paddr, &locDe->pres_addr, sizeof (PRES_ADDR));
|
||
|
|
|
||
|
|
/* Called Addressing information */
|
||
|
|
audt->called_ae_title.AP_title_pres = remDe->AP_title_pres;
|
||
|
|
memcpy (&audt->called_ae_title.AP_title, &remDe->AP_title,
|
||
|
|
sizeof (MMS_OBJ_ID));
|
||
|
|
audt->called_ae_title.AE_qual_pres = remDe->AE_qual_pres;
|
||
|
|
audt->called_ae_title.AE_qual = remDe->AE_qual;
|
||
|
|
audt->called_ae_title.AP_inv_id_pres = remDe->AP_inv_id_pres;
|
||
|
|
audt->called_ae_title.AP_inv_id = remDe->AP_invoke_id;
|
||
|
|
audt->called_ae_title.AE_qual_pres = remDe->AE_qual_pres;
|
||
|
|
audt->called_ae_title.AE_qual = remDe->AE_qual;
|
||
|
|
audt->called_ae_title.AE_inv_id_pres = remDe->AE_inv_id_pres;
|
||
|
|
audt->called_ae_title.AE_inv_id = remDe->AE_invoke_id;
|
||
|
|
|
||
|
|
memcpy (&audt->called_paddr, &remDe->pres_addr, sizeof (PRES_ADDR));
|
||
|
|
|
||
|
|
audt->rem_mac_valid = SD_FALSE; /* CRITICAL: must send to ALL-ES MAC*/
|
||
|
|
|
||
|
|
return (SD_SUCCESS);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_free_net_info */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_VOID mvl_free_net_info (MVL_NET_INFO *netInfo)
|
||
|
|
{
|
||
|
|
#if 1
|
||
|
|
M_FREE (MSMEM_NETINFO, netInfo);
|
||
|
|
#else
|
||
|
|
list_add_last((ST_VOID **) &mvl_net_info_avail_head, (ST_VOID *) netInfo);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
#endif /* End of CLACSE specific functions */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* UTILITY FUNCTIONS */
|
||
|
|
/************************************************************************/
|
||
|
|
/* ma_wait_req_done */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_VOID ma_wait_req_done (ST_RET *retOut)
|
||
|
|
{
|
||
|
|
/* See if the call failed */
|
||
|
|
if (*retOut != SD_SUCCESS)
|
||
|
|
return;
|
||
|
|
|
||
|
|
/* Now just wait for the 'confirm' function to be called */
|
||
|
|
while (ma_cmd_done != SD_TRUE)
|
||
|
|
{
|
||
|
|
copp_event ();
|
||
|
|
if (u_mvl_check_timeout && (*u_mvl_check_timeout)())
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* OK, the function is done or the user gave up */
|
||
|
|
if (ma_cmd_done == SD_TRUE)
|
||
|
|
*retOut = ma_cmd_rslt;
|
||
|
|
else
|
||
|
|
{ /* User timeout */
|
||
|
|
if (ma_cmd_rslt != SD_SUCCESS)
|
||
|
|
*retOut = ma_cmd_rslt;
|
||
|
|
else
|
||
|
|
*retOut = SD_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* AA OBJECT HANDLING FUNCTIONS */
|
||
|
|
/* These functions must be here because the sizeof MVL_NET_INFO */
|
||
|
|
/* varies depending on the stack selection. */
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_aa_resize */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID mvl_aa_resize (ST_INT max_num_var, ST_INT max_num_nvl,
|
||
|
|
ST_INT max_num_jou)
|
||
|
|
{
|
||
|
|
MVL_AA_OBJ_CTRL *aa_objs;
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
/* Do AA specific variables */
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_called; ++i)
|
||
|
|
{
|
||
|
|
aa_objs = (MVL_AA_OBJ_CTRL *) mvl_called_conn_ctrl[i].aa_objs;
|
||
|
|
if (aa_objs == NULL)
|
||
|
|
{
|
||
|
|
aa_objs = mvl_called_conn_ctrl[i].aa_objs =
|
||
|
|
(MVL_AA_OBJ_CTRL *) M_CALLOC (NULL, 1, sizeof(MVL_AA_OBJ_CTRL));
|
||
|
|
}
|
||
|
|
mvl_aa_resize_conn (aa_objs, max_num_var, max_num_nvl, max_num_jou);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < mvl_cfg_info->num_calling; ++i)
|
||
|
|
{
|
||
|
|
aa_objs = (MVL_AA_OBJ_CTRL *) mvl_calling_conn_ctrl[i].aa_objs;
|
||
|
|
if (aa_objs == NULL)
|
||
|
|
{
|
||
|
|
aa_objs = mvl_calling_conn_ctrl[i].aa_objs =
|
||
|
|
(MVL_AA_OBJ_CTRL *) M_CALLOC (NULL, 1, sizeof(MVL_AA_OBJ_CTRL));
|
||
|
|
}
|
||
|
|
mvl_aa_resize_conn (aa_objs, max_num_var, max_num_nvl, max_num_jou);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* _mvl_clear_aa_objs */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID _mvl_clear_aa_objs (MVL_AA_OBJ_CTRL *aa_objs)
|
||
|
|
{
|
||
|
|
ST_INT i;
|
||
|
|
|
||
|
|
/* Delete NVL's. We need to delete the 'entries' pointer table for each */
|
||
|
|
/* NVL, then delete the table of NVL's. */
|
||
|
|
if (aa_objs->max_num_nvlist)
|
||
|
|
{
|
||
|
|
for (i = 0; i < aa_objs->num_nvlist; ++i)
|
||
|
|
mvl_nvl_destroy (aa_objs->nvlist_tbl[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Delete the variable association table. */
|
||
|
|
if (aa_objs->max_num_var_assoc)
|
||
|
|
{
|
||
|
|
for (i = 0; i < aa_objs->num_var_assoc; ++i)
|
||
|
|
M_FREE (MSMEM_GEN, aa_objs->var_assoc_tbl[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Delete the Journal control table. */
|
||
|
|
if (aa_objs->max_num_jou)
|
||
|
|
{
|
||
|
|
for (i = 0; i < aa_objs->num_jou; ++i)
|
||
|
|
M_FREE (MSMEM_GEN, aa_objs->jou_tbl[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
aa_objs->num_var_assoc = 0;
|
||
|
|
aa_objs->num_nvlist = 0;
|
||
|
|
aa_objs->num_jou = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_VOID mvl_aa_resize_conn (MVL_AA_OBJ_CTRL *aa_objs, ST_INT max_num_var, ST_INT max_num_nvl,
|
||
|
|
ST_INT max_num_jou)
|
||
|
|
{
|
||
|
|
if (max_num_var < aa_objs->num_var_assoc)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("Resizing VMD: new max VA is less than current");
|
||
|
|
max_num_var = aa_objs->num_var_assoc;
|
||
|
|
}
|
||
|
|
if (max_num_nvl < aa_objs->num_nvlist)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("Resizing VMD: new max NVL is less than current");
|
||
|
|
max_num_nvl = aa_objs->num_nvlist;
|
||
|
|
}
|
||
|
|
if (max_num_jou < aa_objs->num_jou)
|
||
|
|
{
|
||
|
|
MVL_LOG_NERR0 ("Resizing VMD: new max JOU is less than current");
|
||
|
|
max_num_jou = aa_objs->num_jou;
|
||
|
|
}
|
||
|
|
|
||
|
|
_mvl_resize_ptr_tbl (&(aa_objs->max_num_var_assoc),
|
||
|
|
(ST_VOID ***)&(aa_objs->var_assoc_tbl), max_num_var);
|
||
|
|
_mvl_resize_ptr_tbl (&(aa_objs->max_num_nvlist),
|
||
|
|
(ST_VOID ***)&(aa_objs->nvlist_tbl), max_num_nvl);
|
||
|
|
_mvl_resize_ptr_tbl (&(aa_objs->max_num_jou),
|
||
|
|
(ST_VOID ***)&(aa_objs->jou_tbl), max_num_jou);
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_match_remote_ar */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvl_match_remote_ar (DIB_MATCH_CTRL *matchCtrl, MVL_NET_INFO *cc,
|
||
|
|
DIB_ENTRY **dib_entry_out)
|
||
|
|
{
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
ST_INT chan;
|
||
|
|
|
||
|
|
if (a_get_chan (cc->acse_conn_id, &chan) == SD_SUCCESS)
|
||
|
|
return (dib_match_remote_ar (matchCtrl, chan, dib_entry_out));
|
||
|
|
else
|
||
|
|
return (SD_FAILURE);
|
||
|
|
#else
|
||
|
|
return (dib_match_remote_ar (matchCtrl, &cc->ass_ind_info, dib_entry_out));
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_match_local_ar */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvl_match_local_ar (DIB_MATCH_CTRL *matchCtrl, MVL_NET_INFO *cc,
|
||
|
|
DIB_ENTRY **dib_entry_out)
|
||
|
|
{
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
ST_INT chan;
|
||
|
|
|
||
|
|
if (a_get_chan (cc->acse_conn_id, &chan) == SD_SUCCESS)
|
||
|
|
return (dib_match_local_ar (matchCtrl, chan, dib_entry_out));
|
||
|
|
else
|
||
|
|
return (SD_FAILURE);
|
||
|
|
#else
|
||
|
|
return (dib_match_local_ar (matchCtrl, &cc->ass_ind_info, dib_entry_out));
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_cmp_local_addr */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvl_cmp_local_addr (DIB_MATCH_CTRL *matchCtrl, MVL_NET_INFO *cc,
|
||
|
|
DIB_ENTRY *dib_entry)
|
||
|
|
{
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
ST_INT chan;
|
||
|
|
|
||
|
|
if (a_get_chan (cc->acse_conn_id, &chan) == SD_SUCCESS)
|
||
|
|
return (dib_cmp_local_addr (matchCtrl, chan, dib_entry));
|
||
|
|
else
|
||
|
|
return (DIB_MATCH_NOT);
|
||
|
|
#else
|
||
|
|
return (dib_cmp_local_addr (matchCtrl, &cc->ass_ind_info, dib_entry));
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_cmp_remote_addr */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_INT mvl_cmp_remote_addr (DIB_MATCH_CTRL *matchCtrl, MVL_NET_INFO *cc,
|
||
|
|
DIB_ENTRY *dib_entry)
|
||
|
|
{
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
ST_INT chan;
|
||
|
|
|
||
|
|
if (a_get_chan (cc->acse_conn_id, &chan) == SD_SUCCESS)
|
||
|
|
return (dib_cmp_remote_addr (matchCtrl, chan, dib_entry));
|
||
|
|
else
|
||
|
|
return (DIB_MATCH_NOT);
|
||
|
|
#else
|
||
|
|
return (dib_cmp_remote_addr (matchCtrl, &cc->ass_ind_info, dib_entry));
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* mvl_net_info_to_chan */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET mvl_net_info_to_chan (MVL_NET_INFO *cc, ST_INT *chanOut)
|
||
|
|
{
|
||
|
|
#if defined(MAP30_ACSE)
|
||
|
|
return (a_get_chan (cc->acse_conn_id, chanOut));
|
||
|
|
#else
|
||
|
|
return (SD_FAILURE);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|