FreeCalypso > hg > fc-magnetite
view src/aci2/aci/cmh_smf.c @ 320:3f3c98f8b85d
changes under src/cs/riviera to support addition of FCHG SWE
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 04 Dec 2017 00:43:20 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | Modul : +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This module defines the functions used by the command | handler for GPRS session management ( SM ). +----------------------------------------------------------------------------- */ #if defined (GPRS) && defined (DTI) #ifndef CMH_SMF_C #define CMH_SMF_C #endif #include "aci_all.h" /*==== INCLUDES ===================================================*/ #include "gprs.h" #include "dti.h" /* functionality of the dti library */ #include "aci_cmh.h" #include "ati_cmd.h" #include "aci_cmd.h" #include "aci_lst.h" #include "aci.h" #include "dti_conn_mng.h" #include "dti_cntrl_mng.h" #include "gaci.h" #include "gaci_cmh.h" #include "psa.h" #include "psa_gmm.h" #include "psa_sm.h" #include "psa_gppp.h" #include "phb.h" #include "cmh.h" #include "cmh_gmm.h" #include "cmh_sm.h" #include "cmh_gppp.h" #include "gaci_srcc.h" #include "psa_cc.h" #if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP) #include "wap_aci.h" #include "psa_tcpip.h" #include "cmh_ipa.h" #endif /* WAP || FF_GPF_TCPIP OR SAT E */ #ifdef SIM_TOOLKIT #include "psa_sat.h" #include "cmh_sat.h" #endif #include "psa_sim.h" #include "cmh_sim.h" #include "cmh_snd.h" /* temp needed because of use of ATI functions here: should eventually disappear */ #include "ati_int.h" #ifdef FF_GPF_TCPIP #include "dcm_utils.h" #include "dcm_state.h" #include "dcm_env.h" #endif #include "dcm_f.h" #include "psa_uart.h" /*==== CONSTANTS ==================================================*/ /*==== TYPES ======================================================*/ typedef struct { T_CGEREP_EVENT event; T_CGEREP_EVENT_REP_PARAM parm; } T_CGERP_EVENT_BUFFER; typedef enum { T_CDS_IDLE, T_CDS_RUNNING } T_CONTEXTS_DEACTIVATION_STATUS; typedef struct { T_CONTEXTS_DEACTIVATION_STATUS state; USHORT nsapi_set; T_ACI_CMD_SRC srcId; USHORT cid_set; } T_CONTEXTS_DEACTIVATION_INFORMATION; /*==== EXPORT =====================================================*/ /*==== VARIABLES ==================================================*/ GLOBAL SHORT nsapi_to_cid[SMH_NSAPI_MAX]; static T_CGSMS_SERVICE m_service; static T_CGERP_EVENT_BUFFER gprs_event_buffer[GPRS_EVENT_REPORTING_BUFFER_SIZE]; static SHORT gprs_eb_current_p, gprs_eb_oldest_p; static BOOL m_mt_te_link; static BOOL call_waits_in_table; static T_CONTEXTS_DEACTIVATION_INFORMATION working_cgact_actions; /*==== FUNCTIONS ==================================================*/ /* * functions for ATA and ATH */ /* GLOBAL BOOL cmhSM_sAT_H ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret ); */ /* GLOBAL BOOL cmhSM_sAT_A ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret ); */ static BOOL cmhSM_sAT_A_H_intern ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret, SHORT mode); /* * functions for DTI */ /* GLOBAL ULONG cmhSM_get_link_id_SNDCP_peer ( SHORT cid, T_SNDCP_PEER which ); */ /* GLOBAL BOOL cmhSM_context_deactivated ( USHORT nsapi_set ); */ /* GLOBAL T_ACI_RETURN cmhSNDCP_Disable( UBYTE dti_id ); */ /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Init | +--------------------------------------------------------------------+ PURPOSE : Fill variables for the own use with default values. */ GLOBAL void cmhSM_Init (void) { SHORT i = 0; /* SM CMH global parameter */ smEntStat.curCmd = AT_CMD_NONE; smEntStat.entOwn = OWN_NONE; /* GPRS event reporting */ memset(gprs_event_buffer, 0, sizeof(T_CGERP_EVENT_BUFFER) * GPRS_EVENT_REPORTING_BUFFER_SIZE); gprs_eb_current_p = 0; gprs_eb_oldest_p = 0; cmhSM_empty_call_table(); /* used for network requested context reactivation */ call_waits_in_table = FALSE; working_cgact_actions.state = T_CDS_IDLE; working_cgact_actions.nsapi_set = 0; working_cgact_actions.srcId = CMD_SRC_NONE; working_cgact_actions.cid_set = 0; /* * The following command has to be in the init and the reset function!!! * * Set all to zero in init. In the reset function is a contion action to * not equeal zero. */ memset(pdp_context,0 , sizeof(T_GPRS_CONT_CLASS) * MAX_CID); for (i = 0; i < MAX_CID; i++) { pdp_context[i].link_id_uart = DTI_LINK_ID_NOTPRESENT; pdp_context[i].link_id_new = DTI_LINK_ID_NOTPRESENT; pdp_context[i].link_id_sn = DTI_LINK_ID_NOTPRESENT; } m_mt_te_link = FALSE; } GLOBAL void cmhSM_ResetNonWorkingContexts( void ) { SHORT i = 0, j = 0; UBYTE srcId = srcId_cb; UBYTE gprs_default_pco[] = { 0x80,0x80,0x21,0x10,0x01,0x01,0x00,0x10,0x81,0x06, 0x00,0x00,0x00,0x00,0x83,0x06,0x00,0x00,0x00,0x00 }; for (i = 0; i < MAX_CID; i++) { if ( (pdp_context[i].state EQ CS_UNDEFINED) OR (pdp_context[i].state EQ CS_DEFINED) ) { for (j = 0; j < SMH_NSAPI_MAX; j++) { if ( nsapi_to_cid[j] EQ i + 1 ) { nsapi_to_cid[j] = INVALID_CID; } } memset(&pdp_context[i], 0, sizeof(T_GPRS_CONT_CLASS)); pdp_context[i].state = CS_UNDEFINED; pdp_context[i].smreg_ti = UNDEFINED_TI; pdp_context[i].link_id_uart = DTI_LINK_ID_NOTPRESENT; pdp_context[i].link_id_new = DTI_LINK_ID_NOTPRESENT; pdp_context[i].link_id_sn = DTI_LINK_ID_NOTPRESENT; pdp_context[i].user_pco.len = sizeof (gprs_default_pco); memcpy (pdp_context[i].user_pco.pco, gprs_default_pco, sizeof (gprs_default_pco)); } } memset(work_cids, 0, sizeof(SHORT) * MAX_CID_PLUS_EINS); cid_pointer = 0; /* set default context parameter */ memset(&defaultCtx, 0, sizeof(T_GPRS_CONT_REC)); strcpy(defaultCtx.pdp_type,"IP" ); /* mode of CGAUTO*/ automatic_response_mode = 3; m_service = CGSMS_SERVICE_CS_PREFERRED; /* GPRS event reporting */ ati_user_output_cfg[srcId].CGEREP_mode = CGEREP_MODE_BUFFER; ati_user_output_cfg[srcId].CGEREP_bfr = CGEREP_BFR_CLEAR; sm_cgsms_service = CGSMS_SERVICE_CS_PREFERRED; } GLOBAL void cmhSM_Reset( void ) { SHORT i = 0; UBYTE gprs_default_pco[] = { 0x80,0x80,0x21,0x10,0x01,0x01,0x00,0x10,0x81,0x06, 0x00,0x00,0x00,0x00,0x83,0x06,0x00,0x00,0x00,0x00 }; /* SMF CMH local parameter */ memset(pdp_context, 0, sizeof(T_GPRS_CONT_CLASS) * MAX_CID); for (i = 0; i < MAX_CID; i++) { pdp_context[i].state = CS_UNDEFINED; pdp_context[i].smreg_ti = UNDEFINED_TI; pdp_context[i].link_id_uart = DTI_LINK_ID_NOTPRESENT; pdp_context[i].link_id_new = DTI_LINK_ID_NOTPRESENT; pdp_context[i].link_id_sn = DTI_LINK_ID_NOTPRESENT; pdp_context[i].user_pco.len = sizeof (gprs_default_pco); memcpy (pdp_context[i].user_pco.pco, gprs_default_pco, sizeof (gprs_default_pco)); } memset(work_cids, 0, sizeof(SHORT) * MAX_CID_PLUS_EINS); for (i = 0; i < SMH_NSAPI_MAX; i++) nsapi_to_cid[i] = INVALID_CID; cid_pointer = 0; /* set default context parameter */ memset(&defaultCtx, 0, sizeof(T_GPRS_CONT_REC)); strcpy(defaultCtx.pdp_type,"IP" ); /* mode of CGAUTO*/ automatic_response_mode = 3; m_service = CGSMS_SERVICE_CS_PREFERRED; /* GPRS event reporting */ ati_user_output_cfg[CMD_SRC_ATI].CGEREP_mode = CGEREP_MODE_BUFFER; ati_user_output_cfg[CMD_SRC_ATI].CGEREP_bfr = CGEREP_BFR_CLEAR; sm_cgsms_service = CGSMS_SERVICE_CS_PREFERRED; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_empty_call_table | +--------------------------------------------------------------------+ PURPOSE : Fill variables for the own use with default values. */ GLOBAL void cmhSM_empty_call_table (void) { memset (gprs_call_table, 0, sizeof(T_GPRS_CALL_TABLE) *MAX_GPRS_CALL_TABLE_ENTRIES); current_gprs_ct_index = 0; gprs_ct_index = 0; gprs_call_table[0].sm_ind.smreg_ti = UNDEFINED_TI; } /* +-------------------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : code ROUTINE : cmhSM_getSrcIdOfRunningCGACTDeactivation | +-------------------------------------------------------------------------------+ PURPOSE : Returns a source ID if the given cid is requested to deactivate by +CGACT. The source ID indicates where the +CGACT was started. */ GLOBAL T_ACI_CMD_SRC cmhSM_getSrcIdOfRunningCGACTDeactivation(SHORT cid) { switch( working_cgact_actions.state ) { case T_CDS_RUNNING: if( (1 << (cid - 1) & working_cgact_actions.cid_set) OR INVALID_NSAPI NEQ pdp_context[cid - 1].nsapi AND (pdp_context[cid - 1].nsapi & working_cgact_actions.nsapi_set) ) { return working_cgact_actions.srcId; } break; case T_CDS_IDLE: break; } return CMD_SRC_NONE; } /* +-------------------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : code ROUTINE : cmhSM_getSrcIdOfRunningCGACTDeactivation | +-------------------------------------------------------------------------------+ PURPOSE : Returns TRUE if +CGACT is running on the given cid -> NO_CARRIER FASE if no CGACT was running on this cid -> CME_ERROR */ GLOBAL BOOL isContextDeactivationRequestedByCGACT(SHORT cid) { TRACE_FUNCTION("***isContextDeactivationRequestedByCGACT"); switch( working_cgact_actions.state ) { case T_CDS_RUNNING: if ( (1 << (cid - 1)) & working_cgact_actions.cid_set ) { return TRUE; } } return FALSE; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : code ROUTINE : cmhSM_connection_down | +----------------------------------------------------------------------+ PURPOSE : Control the answer of context deactivations started by an AT command. */ GLOBAL void cmhSM_connection_down( UBYTE dti_id ) { SHORT cid = gaci_get_cid_over_dti_id( dti_id ); TRACE_FUNCTION("cmhSM_connection_down"); switch( working_cgact_actions.state ) { case T_CDS_RUNNING: TRACE_EVENT_P1("T_CDS_RUNNING, cid:%d", cid); if ( (1 << (cid - 1)) & working_cgact_actions.cid_set ) { /* nsapi deactivation is requested */ working_cgact_actions.cid_set &= (USHORT) ~(1U << (cid - 1)); TRACE_EVENT_P1("new set: %d",working_cgact_actions.cid_set); if ( ! (working_cgact_actions.cid_set OR working_cgact_actions.nsapi_set ) ) { R_AT( RAT_OK, working_cgact_actions.srcId ) ( AT_CMD_CGACT ); working_cgact_actions.state = T_CDS_IDLE; } else { TRACE_EVENT_P2("NO OK: cid_set:%d, nsapi_set:%d",working_cgact_actions.cid_set,working_cgact_actions.nsapi_set); } } else { TRACE_EVENT_P1("meets not the set: %d",working_cgact_actions.cid_set); } break; case T_CDS_IDLE: TRACE_EVENT("T_CDS_IDLE"); break; } } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_GetNewNSapi | +--------------------------------------------------------------------+ PURPOSE : Give a free NSapi no. or invalid if all NSapi's are in use. */ LOCAL UBYTE cmhSM_GetNewNSapi ( void ) { BYTE i = SMH_FIRST_FREE_NSAPIS; TRACE_FUNCTION("cmhSM_GetNewNSapi"); while ( i <= SMH_LAST_FREE_NSAPIS AND nsapi_to_cid[i] NEQ INVALID_CID ) i++; if ( i <= SMH_LAST_FREE_NSAPIS) { pdp_context[work_cids[cid_pointer] - 1].nsapi = i; nsapi_to_cid[i] = work_cids[cid_pointer]; TRACE_EVENT_P1("new NSAPI: %d", i); return i; } return INVALID_NSAPI; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_GiveNSapiFree | +--------------------------------------------------------------------+ PURPOSE : Give a NSapi free after use. */ GLOBAL void cmhSM_GiveNSapiFree ( USHORT cid ) { UBYTE *nsapi = &pdp_context[cid - 1].nsapi; if ( *nsapi <= SMH_LAST_FREE_NSAPIS ) { nsapi_to_cid[*nsapi] = INVALID_CID; } } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_contextDeactivated | +--------------------------------------------------------------------+ PURPOSE : Detach mobile if necessary? */ GLOBAL void cmhSM_contextDeactivated ( void ) { if ( ! cmhSM_isContextActive() ) { cmhGMM_allContextsDeactivated(); } } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_pdp_type | +--------------------------------------------------------------------+ PURPOSE : Give the PDP type of the current PDP context that will build. */ GLOBAL UBYTE cmhSM_Get_pdp_type ( void ) { if (!strcmp(pdp_context[work_cids[cid_pointer] - 1].con.pdp_type, "IP")) return IP_V_4; return 0; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_pdp_address | +--------------------------------------------------------------------+ PURPOSE : Give the PDP address of the current PDP context that will build. */ GLOBAL void cmhSM_Get_pdp_address ( T_pdp_address *pdp_address ) { pdp_address->c_buff = (UBYTE) cmhSM_pdp_address_to_ip(&pdp_context[work_cids[cid_pointer] - 1].con.pdp_addr, (UBYTE*) pdp_address->buff); #ifdef _SIMULATION_ memset (pdp_address->buff + pdp_address->c_buff, 0, sizeof(pdp_address->buff) - pdp_address->c_buff); #endif } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_pdp_address_to_ip | +--------------------------------------------------------------------+ PURPOSE : Transform a PDP address to 4 BYTE IP form. */ GLOBAL SHORT cmhSM_pdp_address_to_ip ( T_PDP_ADDRESS *pdp_address, UBYTE *ip ) { SHORT i = 0; BOOL isDynamicIP = TRUE; char *start = *pdp_address, *end; if ( **pdp_address ) { for (i = 0; i < 4; i++) { ip[i] = (UBYTE) strtol(start, &end, 10); start = end + 1; /* * dynamic ip patch * 12.02.02 brz * * if it is a dynamic IP Address than the SM entity need the length set to zero */ if ( ip[i] ) { isDynamicIP = FALSE; } } if ( isDynamicIP EQ TRUE ) { return 0; } else { return 4; } } else { *ip = 0; } return 0; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_ip_to_pdp_address | +--------------------------------------------------------------------+ PURPOSE : Transform a 4 BYTE IP form to the PDP address. */ GLOBAL void cmhSM_ip_to_pdp_address ( UBYTE *ip, T_PDP_ADDRESS pdp_address ) { sprintf(pdp_address, "%03hd.%03hd.%03hd.%03hd", ip[0], ip[1], ip[2], ip[3] ); } /* +-------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : convert_netaddr_to_apn | +-------------------------------------------------------------------+ PURPOSE : converts a domain name into an APN Technical Information: The APN contains out of labels separated by dots. (e.g. xxx.yyy.zzz) This string representation must be translated to a network representation. The APN network representation contains out of a sequence of a length field (not ASCII) followed by a ASCII string. xxx.yyy.zzz => 3xxx3yyy3zzz */ LOCAL void convert_netaddr_to_apn ( T_smreg_apn *apn ) { UBYTE counter = 0, buffer = apn->buffer[0], *pdest = apn->buffer + apn->c_buffer, *psource = pdest - 1; if(apn->c_buffer EQ 0) { return; } if(apn->c_buffer >= sizeof apn->buffer) { apn->c_buffer = 0; TRACE_EVENT_P2 ("convert_netaddr_to_apn: array out of bounds exeption (%d >= %d)", apn->c_buffer, sizeof apn->buffer); return; } /* The network representation is 1 byte longer. */ apn->c_buffer++; /* A sentinel */ apn->buffer[0] = '.'; /* Algorithm: copy from back to front! */ while(pdest > apn->buffer ) { counter = 0; while(*psource NEQ '.') { *(pdest--) = *(psource--); counter++; } *(pdest--) = counter; psource--; } /* Correction according to the sentinel */ apn->buffer[1] = buffer; apn->buffer[0] = ++counter; /* Modify special empty APN to the need of SMREG_SAP */ if ((apn->c_buffer EQ 2) AND (apn->buffer[0] EQ 1) AND (apn->buffer[1] EQ 255)) { apn->c_buffer = 1; /* Special SMREG_SAP indicating that there is an APN present but empty */ apn->buffer[0]= 0; } } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_smreg_apn | +--------------------------------------------------------------------+ PURPOSE : Give the APN of the current PDP context that will build. */ GLOBAL void cmhSM_Get_smreg_apn ( T_smreg_apn *smreg_apn ) { smreg_apn->c_buffer = strlen(pdp_context[work_cids[cid_pointer] - 1].con.apn); strncpy((char *)smreg_apn->buffer, (const char *)pdp_context[work_cids[cid_pointer] - 1].con.apn, smreg_apn->c_buffer); convert_netaddr_to_apn(smreg_apn); #ifdef _SIMULATION_ memset (smreg_apn->buffer + smreg_apn->c_buffer, 0, sizeof(smreg_apn->buffer) - smreg_apn->c_buffer); #endif } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_h_comp | +--------------------------------------------------------------------+ PURPOSE : Give the h_comp of the current PDP context that will build. */ GLOBAL UBYTE cmhSM_Get_h_comp ( void ) { return (UBYTE) pdp_context[work_cids[cid_pointer] - 1].con.h_comp; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_d_comp | +--------------------------------------------------------------------+ PURPOSE : Give the d_comp of the current PDP context that will build. */ GLOBAL UBYTE cmhSM_Get_d_comp ( void ) { return (UBYTE) pdp_context[work_cids[cid_pointer] - 1].con.d_comp; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_change_def_QOS | +--------------------------------------------------------------------+ PURPOSE : Set the quality of service (requested) of default context. */ GLOBAL void cmhSM_change_def_QOS ( T_QOS *qos ) { memcpy(&defaultCtx.qos, qos, sizeof(T_QOS)); } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_change_def_QOS_min | +--------------------------------------------------------------------+ PURPOSE : Set the quality of service (min.) of default context. */ GLOBAL void cmhSM_change_def_QOS_min ( T_QOS *qos ) { memcpy(&defaultCtx.min_qos, qos, sizeof(T_QOS)); } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Set_default_QOS | +--------------------------------------------------------------------+ PURPOSE : Set the quality of service of the spezified PDP context to default. */ GLOBAL void cmhSM_Set_default_QOS ( SHORT cid ) { memcpy(&pdp_context[cid - 1].con.qos, &defaultCtx.qos, sizeof(T_QOS)); } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Set_default_QOS | +--------------------------------------------------------------------+ PURPOSE : Set the quality of service of the spezified PDP context to default. */ GLOBAL void cmhSM_Set_default_QOS_min ( SHORT cid ) { memcpy(&pdp_context[cid - 1].con.min_qos, &defaultCtx.min_qos, sizeof(T_QOS)); } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_QOS | +--------------------------------------------------------------------+ PURPOSE : Give the requested quality of service of the current PDP context that will build. */ GLOBAL void cmhSM_Get_QOS ( T_smreg_qos *dest_qos ) { T_QOS *source_qos = &pdp_context[work_cids[cid_pointer] - 1].con.qos; dest_qos->preced = source_qos->preced; dest_qos->delay = source_qos->delay; dest_qos->relclass = source_qos->relclass; dest_qos->peak = source_qos->peak; dest_qos->mean = source_qos->mean; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_Get_QOS_min | +--------------------------------------------------------------------+ PURPOSE : Give the minimum acceptable quality of service of the current PDP context that will build. */ GLOBAL void cmhSM_Get_QOS_min ( T_smreg_min_qos *dest_qos_min ) { T_QOS *source_qos = &pdp_context[work_cids[cid_pointer] - 1].con.min_qos; dest_qos_min->preced = source_qos->preced; dest_qos_min->delay = source_qos->delay; dest_qos_min->relclass = source_qos->relclass; dest_qos_min->peak = source_qos->peak; dest_qos_min->mean = source_qos->mean; } GLOBAL USHORT cmhSM_pdp_typ_to_string ( UBYTE pdp_typ_no, char* string ) { switch ( pdp_typ_no ) { case 0: strcpy (string, "X_121"); return 5; case 33: strcpy (string, "IP_V_4"); return 6; case 87: strcpy (string, "IP_V_6"); return 6; default: strcpy (string, ""); return 0; } } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_ring_gprs_par | +--------------------------------------------------------------------+ PURPOSE : Return the information for CRING. */ GLOBAL char* cmhSM_ring_gprs_par ( void ) { static char string[MAX_CRING_INFORMATION_LENGTH] = "\""; unsigned int i = 1; i += cmhSM_pdp_typ_to_string(gprs_call_table[current_gprs_ct_index].sm_ind.pdp_type, string + i); string[i++] = '\"'; string[i++] = ','; string[i++] = '\"'; memcpy (string + i, gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.buff, gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.c_buff); i += gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.c_buff + 1; string[i++] = '\"'; if ( *gprs_call_table[current_gprs_ct_index].L2P ) { string[i++] = ','; string[i++] = '\"'; strcpy (string + i, gprs_call_table[current_gprs_ct_index].L2P); i += strlen (gprs_call_table[current_gprs_ct_index].L2P); string[i++] = '\"'; } string[i] = 0; return string; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_call_answer | +--------------------------------------------------------------------+ PURPOSE : Return TRUE in this case, if an auto answer is needed. */ GLOBAL BOOL cmhSM_call_answer ( UBYTE ring_counter, T_ACI_CRING_MOD mode ) { switch(automatic_response_mode) { case 0: /* GPRS off, GSM controlled by S0 */ if ( mode NEQ CRING_MOD_Gprs AND at.S[0] AND at.S[0] <= ring_counter ) return TRUE; break; case 1: /* GPRS on, GSM controlled by S0 */ if ( mode EQ CRING_MOD_Gprs ) return TRUE; if (at.S[0] AND at.S[0] <= ring_counter) return TRUE; break; case 2: /* modem copatibility mode, GPRS on, GSM off */ if ( mode NEQ CRING_MOD_Gprs ) break; /*lint -fallthrough*/ case 3: /* modem copatibility mode, GPRS on, GSM on */ if (at.S[0] AND ring_counter >= at.S[0]) return TRUE; } return FALSE; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_call_reject | +--------------------------------------------------------------------+ PURPOSE : Return TRUE in this case, if an auto reject is needed. */ GLOBAL BOOL cmhSM_call_reject ( UBYTE ring_counter, T_ACI_CRING_MOD mode ) { switch(automatic_response_mode) { case 0: /* GPRS off, GSM controlled by S0 */ return FALSE; case 1: /* GPRS on, GSM controlled by S0 */ if (at.S99 AND mode EQ CRING_MOD_Gprs ) return TRUE; break; case 2: /* modem copatibility mode, GPRS on, GSM off */ case 3: /* modem copatibility mode, GPRS on, GSM on */ if ( mode NEQ CRING_MOD_Gprs ) break; if (at.S99 AND ring_counter >= at.S99) return TRUE; } return FALSE; } LOCAL BOOL is_GSM_call_active (void) { SHORT ctbIdx; /* holds call table index */ for( ctbIdx = 0; ctbIdx < MAX_CALL_NR; ctbIdx++ ) { if (ccShrdPrm.ctb[ctbIdx] NEQ NULL) { return (TRUE); } } return (FALSE); } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_sAT_H | +--------------------------------------------------------------------+ PURPOSE : handle GPRS calls and return FALSE if a circuit switched call need a handle. */ GLOBAL BOOL cmhSM_sAT_H ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret ) { SHORT cid_array[1] = { INVALID_CID }; T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, (UBYTE)srcId, search_ati_src_id); if ( ( at.rngPrms.isRng EQ TRUE ) AND ( at.rngPrms.mode EQ CRING_MOD_Gprs) ) { /* * brz patch: In the case of context reactivation over SMREG_PDP_ACTIVATE_IND with an used ti * the GPRS ATH command doesn't do anything! * * Why? Because the Windows Dial-Up Networking client send every time an ATH after termination * of the connection and with this a context reactivation was impossible. */ if ( gprs_call_table[current_gprs_ct_index].reactivation EQ GCTT_NORMAL ) { return cmhSM_sAT_A_H_intern(srcId, aci_ret, 0); } return TRUE; } else { if (is_GSM_call_active()) { return (FALSE); } /* if AT_H has been called and no RING is active, then disconnect the active context */ #ifdef FF_GPF_TCPIP if(is_gpf_tcpip_call()) { T_DCM_STATUS_IND_MSG err_ind_msg; err_ind_msg.hdr.msg_id = DCM_ERROR_IND_MSG; err_ind_msg.result = DCM_PS_CONN_BROKEN; dcm_send_message(err_ind_msg, DCM_SUB_NO_ACTION); } #endif *aci_ret = sAT_PlusCGACT ( srcId, CGACT_STATE_DEACTIVATED, cid_array ); switch (*aci_ret) { case (AT_CMPL): /*operation completed*/ return FALSE; /* return false, so that GSM calls will be canceled */ case (AT_EXCT): src_params->curAtCmd = AT_CMD_CGACT; return TRUE; default: cmdCmeError(CME_ERR_Unknown); /*Command failed*/ return FALSE; } } } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_sAT_A | +--------------------------------------------------------------------+ PURPOSE : handle GPRS calls and return FALSE if a circuit switched call need a handle. */ GLOBAL BOOL cmhSM_sAT_A ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret ) { BOOL b; b = cmhSM_sAT_A_H_intern(srcId, aci_ret, 1); if ( *aci_ret EQ AT_EXCT ) cmdErrStr = NULL; return b; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_sAT_A_H_intern | +--------------------------------------------------------------------+ PURPOSE : handle sAT_A and cAT_H for GPRS */ static BOOL cmhSM_sAT_A_H_intern ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret, SHORT mode) { if ( at.rngPrms.isRng EQ TRUE ) { if ( at.rngPrms.mode EQ CRING_MOD_Gprs) { *aci_ret = automatic_response_mode > 1 ? /* modem copatibility mode possible */ sAT_PlusCGANS(srcId, mode, NULL, GPRS_CID_OMITTED): AT_FAIL; } else /* circuit switched call */ { return FALSE; } } else { return FALSE; } return TRUE; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_pdp_addr_well_formed | +----------------------------------------------------------------------+ PURPOSE : check pdp address of well formed */ GLOBAL BOOL cmhSM_pdp_addr_well_formed( USHORT type, T_PDP_ADDRESS pdp_addr ) { SHORT i = 0, state = 1; char *start = pdp_addr, *end; long temp; switch ( type ) { case PDP_T_IP: /* 255.255.255.255 */ if ( *pdp_addr ) { while ( state AND i < 3) { temp = strtol(start, &end, 10); if ( temp < 0 OR temp > 255 ) state = 0; if ( *end NEQ '.' ) state = 0; start = end + 1; i++; } temp = strtol(start, &end, 10); if ( temp < 0 OR temp > 255 ) state = 0; } if(state) return TRUE; break; case PDP_T_X25: return FALSE; default: break; } return FALSE; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_apn_well_formed | +----------------------------------------------------------------------+ PURPOSE : check APN of well formed */ GLOBAL BOOL cmhSM_apn_well_formed( T_APN APN ) { SHORT i = 0, state = 1, length = strlen (APN); char *no_start_labels[] = {"rac","lac","sgsn"}, *start, *end, *mark; T_APN apn; strcpy(apn, APN); start = apn; /* change charcter of string to lower cases */ for (i = 0; i < length; i++) apn[i] = tolower(apn[i]); /* The Network Identifier shall not start with this labels */ for (i = 0; i < 3; i++) { if ( apn EQ strstr(apn, no_start_labels[i]) ) return FALSE; } /* the Wild Card APN */ if ( length EQ 1 AND *start EQ '*' ) return TRUE; /* the APN with no name */ if ( length EQ 1 AND *start EQ /*lint -e(743)*/ '\x0ff' ) return TRUE; /* Oporater Identifer is optional and the Network Identifer */ mark = strrchr(apn, '.'); if ( mark ) if ( strstr(mark + 1, "gprs") ) { /* APN Operator Identifier contained (optional) */ if ( length < 18 ) return FALSE; mark = start + length - 18; /* start of the APN Operator Identifier */ /* check APN Operator Identifier: "mncXXX.mccXXX.gprs" */ if ( mark NEQ strstr(mark, "mnc") ) return FALSE; if ( mark + 6 NEQ strstr(mark, ".mcc") ) return FALSE; strtol(mark + 3, &end, 10); if ( end NEQ mark + 6 ) return FALSE; strtol(mark + 10, &end, 10); if ( end NEQ mark + 13 ) return FALSE; /* check character between APN Network Identifier and the Operator Identifer */ mark--; if ( *mark NEQ '.' ) return FALSE; /* set stop mark */ *mark = 0; } else mark = 0; /* check APN Network Identifier */ /* shall not end in ".gprs" */ end = strrchr(apn, '.'); if ( end ) if ( strstr(end + 1, "gprs") ) return FALSE; /* parse all labels */ while ( *start ) { /* in first at least one Label */ while ( (*start >= 'a' AND *start <= 'z') OR (*start >= '0' AND *start <= '9') OR *start EQ '-' ) start ++; /* next Label or nothing */ if ( *start EQ '.' ) start ++; else if ( *start NEQ 0) return FALSE; } /* The APN Network Identifier shall have a maximum length of 63 octets. */ if ( start - apn > 63 ) return FALSE; /* clear stop mark */ if ( mark ) *mark = '.'; return TRUE; } /* +--------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finished ROUTINE : cmhSM_transform_pdp_type | +--------------------------------------------------------------------+ PURPOSE : transform pdp_type */ GLOBAL USHORT cmhSM_transform_pdp_type ( char *pdp_type ) { if ( !strcmp(pdp_type, "IP") ) return PDP_T_IP; if ( !strcmp(pdp_type, "X25") ) return PDP_T_X25; return PDP_T_NONE; } GLOBAL T_CONTEXT_STATE get_state_over_cid ( SHORT cid ) { TRACE_FUNCTION("get_state_over_cid()"); if ( (cid < 1) OR (cid > MAX_CID) ) { TRACE_EVENT("invalid cid detected!"); return CS_INVALID_STATE; } return pdp_context[cid - 1].state; } GLOBAL void set_state_over_cid ( SHORT cid, T_CONTEXT_STATE c_state ) { TRACE_EVENT_P3("set_state_over_cid: %d -> %d for cid %d", pdp_context[cid - 1].state, c_state, cid) ; if (cid > 0 AND cid <= MAX_CID) pdp_context[cid - 1].state = c_state; } GLOBAL T_CONTEXT_STATE get_state_working_cid ( void ) { if ( work_cids[cid_pointer] EQ INVALID_CID ) { TRACE_EVENT("working_cid is invalid!"); return CS_INVALID_STATE; } return pdp_context[work_cids[cid_pointer] - 1].state; } GLOBAL void set_conn_param_on_all_working_cids ( UBYTE owner, T_DTI_ENTITY_ID entity_id ) { SHORT *pcid = &(work_cids[cid_pointer]); TRACE_FUNCTION("set_conn_param_on_all_working_cids()"); while(INVALID_CID NEQ *pcid) { pdp_context[*pcid - 1].owner = owner; pdp_context[*pcid - 1].entity_id = entity_id; pcid ++; } } GLOBAL void set_conn_param_on_working_cid ( UBYTE owner, T_DTI_ENTITY_ID entity_id ) { TRACE_FUNCTION("set_conn_param_on_working_cid()"); pdp_context[work_cids[cid_pointer] - 1].owner = owner; pdp_context[work_cids[cid_pointer] - 1].entity_id = entity_id; } GLOBAL void set_state_working_cid ( T_CONTEXT_STATE c_state ) { TRACE_FUNCTION("set_state_working_cid()"); if ( work_cids[cid_pointer] NEQ INVALID_CID ) { pdp_context[work_cids[cid_pointer] - 1].state = c_state; } else { TRACE_EVENT("working cid is invalid!"); } } GLOBAL T_CONTEXT_STATE get_state_over_nsapi_set ( USHORT *nsapi_set, SHORT *cid ) { USHORT nsapi = 0; TRACE_FUNCTION("get_state_over_nsapi_set()"); while( nsapi < SMH_LAST_FREE_NSAPIS AND !((*nsapi_set >> nsapi) & 1) ) nsapi++; if ( !(*nsapi_set & ( 1 << nsapi )) ) { return CS_INVALID_STATE; } TRACE_EVENT_P1("NSAPI: %4d", nsapi); *nsapi_set &= ~( 1U << nsapi ); return get_state_over_cid( *cid = nsapi_to_cid[nsapi] ); } GLOBAL T_CONTEXT_STATE get_state_over_nsapi ( USHORT nsapi ) { return get_state_over_cid( nsapi_to_cid[nsapi] ); } GLOBAL USHORT cmhSM_Give_nsapi_set ( SHORT cid ) { if ( (cid < 1) OR (cid > MAX_CID) ) return 0; return 1 << pdp_context[cid - 1].nsapi; } GLOBAL T_ACI_CAL_OWN get_owner_over_cid ( SHORT cid ) { if ( (cid < 1) OR (cid > MAX_CID) ) return CAL_OWN_NONE; return pdp_context[cid - 1].owner; } GLOBAL void cmhGPPP_send_establish_request ( UBYTE peer ) { T_PPP_ESTABLISH_REQ est_req; memset(&est_req, 0, sizeof( T_PPP_ESTABLISH_REQ )); est_req.mode = PPP_SERVER; est_req.mru = PPP_MRU_DEFAULT; est_req.ap = gpppShrdPrm.ppp_authentication_protocol; est_req.accm = gpppShrdPrm.accm; est_req.rt = gpppShrdPrm.restart_timer; est_req.mc = gpppShrdPrm.max_configure; est_req.mt = gpppShrdPrm.max_terminate; est_req.mf = gpppShrdPrm.max_failure; est_req.peer_direction = DTI_CHANNEL_TO_LOWER_LAYER; est_req.prot_direction = DTI_CHANNEL_TO_HIGHER_LAYER; est_req.peer_link_id = pdp_context[work_cids[0] - 1].link_id_uart; est_req.prot_link_id = pdp_context[work_cids[0] - 1].link_id_new; #ifdef _SIMULATION_ memset (est_req.peer_channel.peer_entity, 0, CHANNEL_NAME_LENGTH); memset (est_req.protocol_channel.protocol_entity, 0, CHANNEL_NAME_LENGTH); #endif /* _SIMULATION_ */ strcpy ( (char *) est_req.protocol_channel.protocol_entity, SNDCP_NAME); switch (peer) { #ifdef BT_ADAPTER case DTI_ENTITY_BLUETOOTH: strcpy ( (char *) est_req.peer_channel.peer_entity, BTI_NAME); break; #endif case DTI_ENTITY_UART: strcpy ( (char *) est_req.peer_channel.peer_entity, UART_NAME); break; #ifdef FF_PSI case DTI_ENTITY_PSI: strcpy ( (char *) est_req.peer_channel.peer_entity, PSI_NAME); break; #endif /*FF_PSI*/ case DTI_ENTITY_AAA: strcpy ( (char *) est_req.peer_channel.peer_entity, RIV_NAME); break; default: TRACE_ERROR ("[cmhGPPP_send_establish_request()] Unexpected peer!"); return; } psaGPPP_Establish ( &est_req ); set_state_working_cid( CS_ESTABLISH_1 ); } GLOBAL void cmhSM_cgerep_buffer ( void ) { UBYTE srcId = srcId_cb; switch (ati_user_output_cfg[srcId].CGEREP_bfr) { case CGEREP_BFR_CLEAR: memset(gprs_event_buffer, 0, sizeof(T_CGERP_EVENT_BUFFER) * GPRS_EVENT_REPORTING_BUFFER_SIZE); break; case CGEREP_BFR_FLUSH: if ( uart_is_mt_te_link EQ FALSE) { while ( gprs_eb_oldest_p NEQ gprs_eb_current_p ) { R_AT( RAT_CGEREP, srcId ) ( gprs_event_buffer[gprs_eb_oldest_p].event, gprs_event_buffer[gprs_eb_oldest_p].parm ); gprs_eb_oldest_p++; } } break; case CGEREP_BFR_OMITTED: case CGEREP_BFR_INVALID: default: break; } } GLOBAL void cmhSM_save_event( T_CGEREP_EVENT event, T_CGEREP_EVENT_REP_PARAM *param ) { /* save event */ gprs_event_buffer[gprs_eb_current_p].event = event; if (param) memcpy (&gprs_event_buffer[gprs_eb_current_p].parm, param, sizeof(T_CGEREP_EVENT_REP_PARAM)); /* is buffer full */ if ( gprs_eb_oldest_p EQ gprs_eb_current_p ) gprs_eb_oldest_p = -1; /* new current pointer */ gprs_eb_current_p++; if ( gprs_eb_current_p EQ GPRS_EVENT_REPORTING_BUFFER_SIZE ) gprs_eb_current_p = 0; /* if buffer full correct pointer to oldest event */ if ( gprs_eb_oldest_p EQ -1 ) gprs_eb_oldest_p = gprs_eb_current_p; } GLOBAL void cmhSM_set_sms_service ( T_CGSMS_SERVICE service ) { { PALLOC (mnsms_mo_serv_req, MNSMS_MO_SERV_REQ); /* fill in primitive parameter: command request */ mnsms_mo_serv_req -> mo_sms_serv = (UBYTE) service; PSENDX (SMS, mnsms_mo_serv_req); } m_service = service; } /* +-------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_sms_service_changed | +-------------------------------------------------------------------+ PURPOSE : indicates a network initiated PDP context modification */ GLOBAL void cmhSM_sms_service_changed ( UBYTE service ) { TRACE_FUNCTION ("cmhSM_sms_service_changed()"); /* *------------------------------------------------------------------- * check for command context *------------------------------------------------------------------- */ if ( smEntStat.curCmd EQ AT_CMD_CGSMS ) { if ( m_service EQ service ) { sm_cgsms_service = m_service; R_AT( RAT_OK, smEntStat.entOwn ) ( smEntStat.curCmd ); } else { R_AT( RAT_CME, smEntStat.entOwn ) ( smEntStat.curCmd, CME_ERR_Unknown ); /* log result */ cmh_logRslt ( smEntStat.entOwn, RAT_CME, smEntStat.curCmd, -1, -1, CME_ERR_Unknown ); } smEntStat.curCmd = AT_CMD_NONE; } } GLOBAL T_ACI_RETURN cmhSM_GprsAttached( SHORT state ) { SHORT i = 1; TRACE_FUNCTION ("cmhSM_GprsAttached()"); if ( state ) { /* mobile is attached */ switch ( get_state_working_cid( ) ) { case CS_ATTACHING_AFTER_DEF: case CS_ATTACHING_AFTER_UNDEF: cmhSM_data_link_context(); return AT_EXCT; case CS_WAITS_FOR_ACTIVATING: if (cmhSM_activate_context() NEQ AT_FAIL) { return AT_EXCT; } else /*GPRS is not allowed by FDN */ { return AT_FAIL; } default: return AT_FAIL; } } else { /* attach failed */ if ( smEntStat.curCmd EQ AT_CMD_NONE AND gpppEntStat.curCmd EQ AT_CMD_NONE ) return AT_FAIL; /* * it is enough to check only the working cid, * because only one context can be in work */ switch ( get_state_working_cid( ) ) { case CS_ATTACHING_AFTER_DEF: case CS_ATTACHING_AFTER_UNDEF: pdp_context[work_cids[cid_pointer] - 1].owner = gpppEntStat.entOwn; gaci_RAT_caller ( RAT_NO_CARRIER, work_cids[cid_pointer], AT_CMD_CGDATA, 0 ); break; case CS_WAITS_FOR_ACTIVATING: pdp_context[work_cids[cid_pointer] - 1].owner = smEntStat.entOwn; gaci_RAT_caller ( RAT_CME, work_cids[cid_pointer], AT_CMD_CGACT, CME_ERR_GPRSUnspec ); break; default: /* * do nothing, because SM informs ACI over context deactivation */ return AT_FAIL; } return cmhSM_deactivateAContext( smEntStat.entOwn, work_cids[cid_pointer] ); } } GLOBAL T_ACI_RETURN cmhSM_activate_context(void) { TRACE_FUNCTION ("cmhSM_activate_context()"); if (pb_get_fdn_mode () EQ FDN_ENABLE) { if (pb_check_fdn (0, (const UBYTE *)"*99#") NEQ PHB_OK) { TRACE_EVENT("Activate Context: Entry not found in FDN, GPRS not allowed."); ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow); return (AT_FAIL); } TRACE_EVENT("Activate Context: Entry found in FDN, GPRS allowed."); } if( AT_CMPL EQ cmhGMM_contextActivation(smEntStat.entOwn, AT_CMD_CGACT) ) { cmhSM_connect_working_cid(); set_state_working_cid( CS_ACTIVATING ); } else /* AT_EXCT -> class BX class change requested (NOMIII) */ { set_state_working_cid( CS_WAITS_FOR_ACTIVATING ); } return (AT_EXCT); } #if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP) /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : cmh_smf | | STATE : initial ROUTINE : cmhSM_IP_activate_cb | +----------------------------------------------------------------------+ PURPOSE : callback function for WAP over GPRS. While handling the command ATD*98# in function atGD() the function psaTCPIP_Activate() is called for WAP handling. psaTCPIP_Activate() has this function as parameter for call backs. */ void cmhSM_IP_activate_cb(T_ACI_RETURN result) { SHORT cid = gaci_get_cid_over_dti_id(wap_dti_id); TRACE_FUNCTION("cmhSM_IP_activate_cb"); TRACE_EVENT_P1("wap_state: %s",wap_state_to_string(wap_state)); #ifndef FF_SAT_E ACI_ASSERT(DTI_DTI_ID_NOTPRESENT NEQ wap_dti_id); ACI_ASSERT(cid >= GPRS_CID_1 AND cid < GPRS_CID_INVALID); ACI_ASSERT(result NEQ AT_FAIL); #endif /* not FF_SAT_E */ if ( result EQ AT_FAIL ) { /* IP activation failed. */ TRACE_EVENT("UDP/TCP/IP activation/configuration returned AT_FAIL"); if (DTI_LINK_ID_NOTPRESENT NEQ wap_dti_id) { dti_cntrl_close_dpath_from_dti_id (wap_dti_id); cmhSM_disconnect_cid(cid, GC_TYPE_WAP ); } /* reset work_cids */ set_state_over_cid(cid, CS_DEFINED); sAT_PercentWAP(smShrdPrm.owner, 0); smEntStat.curCmd = AT_CMD_NONE; dti_cntrl_erase_entry(wap_dti_id); cmdCmeError(CME_ERR_Unknown); #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E) if( cmhSAT_OpChnGPRSPend( INVALID_CID, OPCH_EST_REQ )) { cmhSAT_OpChnUDPDeactGprs(); } #endif /* SIM_TOOLKIT */ return; } switch(wap_state) { /* in case CO_UDP_IP and FF_GPF_TCPIP is defined this is a fall through case */ UDPIP_STATEMENT(case IPA_Activated:) GPF_TCPIP_STATEMENT(case TCPIP_Activation:) if(is_gpf_tcpip_call()) { GPF_TCPIP_STATEMENT(set_conn_param_on_working_cid( (UBYTE)smEntStat.entOwn, DTI_ENTITY_TCPIP)); } else { UDPIP_STATEMENT(set_conn_param_on_working_cid( (UBYTE)smEntStat.entOwn, DTI_ENTITY_IP)); } cmhSM_activate_context(); return; UDPIP_STATEMENT(case UDPA_Configurated:) GPF_TCPIP_STATEMENT(case TCPIP_Configurated:) /* smEntStat.curCmd = AT_CMD_NONE; */ #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E) if( cmhSAT_OpChnGPRSPend( INVALID_CID, OPCH_EST_REQ )) { cmhSAT_OpChnUDPConfGprs(); } else #endif /* SIM_TOOLKIT */ { R_AT ( RAT_CONNECT, smEntStat.entOwn )( AT_CMD_CGACT, -1, wapId, FALSE ); } smEntStat.curCmd = AT_CMD_NONE; smEntStat.entOwn = OWN_NONE; #ifdef FF_GPF_TCPIP if(is_gpf_tcpip_call()) { T_DCM_STATUS_IND_MSG msg; msg.hdr.msg_id = DCM_NEXT_CMD_READY_MSG; dcm_send_message(msg, DCM_SUB_WAIT_CGACT_CNF); } #endif break; UDPIP_STATEMENT(case IPA_Deactivated:) GPF_TCPIP_STATEMENT(case TCPIP_Deactivated:) TRACE_EVENT_P1("cmhSM_IP_activate_cb, no connection, dti_id = %d", wap_dti_id); #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E) if( cmhSAT_OpChnGPRSPend( INVALID_CID, OPCH_NONE )) { cmhSAT_OpChnUDPDeactGprs(); } else #endif /* SIM_TOOLKIT */ { R_AT( RAT_NO_CARRIER, pdp_context[cid - 1].owner) ( AT_CMD_CGDATA, 0 ); } dti_cntrl_close_dpath_from_dti_id (wap_dti_id); cmhSM_connection_down(wap_dti_id); cmhSM_disconnect_cid(cid, GC_TYPE_WAP ); sAT_PercentWAP(smShrdPrm.owner, 0); if(work_cids[cid_pointer] EQ cid) { smEntStat.curCmd = AT_CMD_NONE; *work_cids = 0; cid_pointer = 0; } #ifdef FF_GPF_TCPIP if(is_gpf_tcpip_call()) { T_DCM_STATUS_IND_MSG msg; msg.hdr.msg_id = DCM_NEXT_CMD_READY_MSG; dcm_send_message(msg, DCM_SUB_WAIT_CGDEACT_CNF); } #endif break; default: TRACE_EVENT("Unexpected wap state in cmhSM_IP_activate_cb()"); if(is_gpf_tcpip_call()) { GPF_TCPIP_STATEMENT(srcc_delete_count(SRCC_TCPIP_SNDCP_LINK )); } else { UDPIP_STATEMENT(srcc_delete_count(SRCC_IP_SNDCP_LINK )); } dti_cntrl_erase_entry(wap_dti_id); sAT_PercentWAP(smShrdPrm.owner, 0); smEntStat.curCmd = AT_CMD_NONE; #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E) if( cmhSAT_OpChnGPRSPend( INVALID_CID, OPCH_NONE )) { cmhSAT_OpChnUDPDeactGprs(); } else #endif /* SIM_TOOLKIT */ { cmdCmeError(CME_ERR_Unknown); } break; } return; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : cmh_smf | | STATE : initial ROUTINE : cmhSM_IP_Enable | +----------------------------------------------------------------------+ PURPOSE : enables IP dti connection. */ GLOBAL void cmhSM_IP_Enable ( T_DTI_CONN_LINK_ID link_id) { TRACE_FUNCTION("cmhSM_IP_Enable"); #ifdef _SIMULATION_ cmhSM_connect_context ( gaci_get_cid_over_link_id( link_id ), DTI_ENTITY_IP, 0, 100 ); #else /* _SIMULATION_ */ cmhSM_connect_context ( gaci_get_cid_over_link_id( link_id ), DTI_ENTITY_IP, 0, 0 ); #endif /* _SIMULATION_ */ } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : cmh_smf | | STATE : initial ROUTINE : cmhSM_IP_Disable | +----------------------------------------------------------------------+ PURPOSE : disables IP dti connection. */ GLOBAL void cmhSM_IP_Disable () { TRACE_FUNCTION("cmhSM_IP_Disable"); } #endif /* WAP || FF_GPF_TCPIP || SAT E */ /* +-------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_data_link_context | +-------------------------------------------------------------------+ */ GLOBAL void cmhSM_data_link_context(void) { TRACE_FUNCTION ("cmhSM_data_link_context()"); R_AT( RAT_CONNECT, pdp_context[work_cids[cid_pointer] - 1].owner ) ( AT_CMD_CGDATA, 0, 0, FALSE ); /* log result */ cmh_logRslt ( pdp_context[work_cids[cid_pointer] - 1].owner, RAT_CONNECT, AT_CMD_CGDATA, -1, -1, -1 ); cmhSM_connect_working_cid(); } /* +-------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_get_cid | +-------------------------------------------------------------------+ */ GLOBAL SHORT cmhSM_get_cid ( USHORT nsapi ) { return nsapi_to_cid[nsapi]; } /* +-------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_next_work_cid | +-------------------------------------------------------------------+ PURPOSE : start the next context activation if requested */ GLOBAL BOOL cmhSM_next_work_cid ( T_ACI_AT_CMD curCmd ) { TRACE_EVENT_P1("cmhSM_next_work_cid, cid_pointer: %d", cid_pointer); cid_pointer ++; if ( work_cids[cid_pointer] EQ INVALID_CID ) { smEntStat.curCmd = AT_CMD_NONE; gpppEntStat.curCmd = AT_CMD_NONE; cid_pointer = 0; *work_cids = 0; return FALSE; } switch ( curCmd ) { case AT_CMD_CGDATA: cmhSM_data_link_context(); break; case AT_CMD_CGACT: if(AT_FAIL EQ cmhSM_activate_context()) { smEntStat.curCmd = AT_CMD_NONE; gpppEntStat.curCmd = AT_CMD_NONE; cid_pointer = 0; *work_cids = 0; /*R_AT (RAT_CME, smEntStat.entOwn)( AT_CMD_CGACT, CME_ERR_Unknown );*/ return FALSE; } break; default: cid_pointer = 0; *work_cids = 0; return FALSE; } return TRUE; } /* +-------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_define_cid_list | +-------------------------------------------------------------------+ PURPOSE : define all cid's in the list, if necessary */ GLOBAL SHORT cmhSM_define_cid_list( T_ACI_CMD_SRC srcId, SHORT *cids ) { int i = 1; TRACE_FUNCTION("cmhSM_define_cid_list"); if(INVALID_CID != *work_cids) { return 0; } if ( *cids EQ GPRS_CID_OMITTED) /* if no cid given */ { while ( i <= MAX_CID AND get_state_over_cid( (SHORT)i ) NEQ CS_DEFINED ) i++; if ( i > MAX_CID ) { i = 1; while ( i <= MAX_CID AND get_state_over_cid( (SHORT)i ) NEQ CS_UNDEFINED ) i++; if ( i <= MAX_CID ) { /* * reset of context parameter if cid undefined */ sAT_PlusCGDCONT_exec (srcId, (SHORT)i, &defaultCtx); set_state_over_cid((SHORT)i, CS_UNDEFINED); } else return 0; } *cids = work_cids[0] = i; work_cids[1] = INVALID_CID; i = 1; /* no. of cids */ } else /* if cid(s) is/are given */ { SHORT j = 0; i = 0; /* * checks given cid parameter */ while ( i < MAX_CID AND cids[i] NEQ INVALID_CID ) { /* check cid */ if ( cids[i] < GPRS_CID_1 OR cids[i] >= GPRS_CID_INVALID ) return 0; /* count cids */ i++; } if ( MAX_CID < i ) return 0; memcpy (work_cids, cids, sizeof( *work_cids ) * (i + 1) ); /* * reset of context parameter if cid undefined */ for (j = 0; work_cids[j] NEQ INVALID_CID; j++) { switch(get_state_over_cid(work_cids[j])) { case CS_UNDEFINED: sAT_PlusCGDCONT_exec (srcId, work_cids[j], &defaultCtx); set_state_over_cid(work_cids[j], CS_UNDEFINED); /*lint -fallthrough*/ case CS_DEFINED: case CS_ACTIVATED: break; default: memset (work_cids, 0, sizeof( *work_cids ) * (i + 1) ); return 0; } } } return i; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_get_pdp_addr_for_CGPADDR | +----------------------------------------------------------------------+ PURPOSE : return the PDP_address to one cid for the GPRS CGPADDR AT command */ GLOBAL SHORT cmhSM_get_pdp_addr_for_CGPADDR ( SHORT cid, T_PDP_ADDRESS pdp_adress ) { T_CONTEXT_STATE c_state; /* state of context */ c_state = get_state_over_cid( cid ); if ( c_state EQ CS_UNDEFINED OR c_state EQ CS_INVALID_STATE ) { *pdp_adress = 0; return INVALID_CID; } if ( c_state EQ CS_ACTIVATED OR c_state EQ CS_DATA_LINK ) strcpy( pdp_adress, pdp_context[cid - 1].allocated_pdp_addr ); else strcpy( pdp_adress, pdp_context[cid - 1].con.pdp_addr ); return cid; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_is_smreg_ti_used | +----------------------------------------------------------------------+ PURPOSE : handle for used smreg_ti */ GLOBAL BOOL cmhSM_is_smreg_ti_used ( UBYTE smreg_ti, SHORT *cid ) { SHORT i = 0; while ( i < MAX_CID ) { if ( pdp_context[i].smreg_ti EQ smreg_ti) { psaSM_PDP_Deactivate ( (USHORT) (1 << pdp_context[i].nsapi), SMREG_LOCAL); psaGPPP_Terminate( PPP_LOWER_LAYER_UP ); call_waits_in_table = TRUE; *cid = i + 1; set_state_over_cid(*cid, CS_CONTEXT_REACTIVATION_1); return TRUE; } i++; } return FALSE; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_context_reactivation | +----------------------------------------------------------------------+ PURPOSE : */ GLOBAL void cmhSM_context_reactivation ( void ) { T_CGEREP_EVENT_REP_PARAM event; T_SMREG_PDP_ACTIVATE_IND *sm_ind; SHORT i = 0; if ( call_waits_in_table EQ TRUE ) { call_waits_in_table = FALSE; /* * GPRS event reporting */ sm_ind = &gprs_call_table[current_gprs_ct_index].sm_ind; cmhSM_pdp_typ_to_string(sm_ind->pdp_type, (char*) &event.act.pdp_type); memcpy(&event.act.pdp_addr, &sm_ind->pdp_address.buff, sm_ind->pdp_address.c_buff); event.act.cid = gprs_call_table[current_gprs_ct_index].cid; for( i = 0 ; i < CMD_SRC_MAX; i++ ) { R_AT( RAT_CRING, i ) ( CRING_MOD_Gprs, CRING_TYP_GPRS, CRING_TYP_NotPresent ); R_AT( RAT_CGEREP, i ) ( CGEREP_EVENT_NW_REACT, &event ); R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_NW_REACT, &event ); } } else { cmhSM_next_call_table_entry(); } } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_stop_context_reactivation | +----------------------------------------------------------------------+ PURPOSE : */ GLOBAL void cmhSM_stop_context_reactivation ( void ) { call_waits_in_table = FALSE; } GLOBAL void cmhSM_next_call_table_entry( void ) { current_gprs_ct_index++; if ( current_gprs_ct_index >= gprs_ct_index ) { cmhSM_empty_call_table(); } else { cmhSM_context_reactivation(); } } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_init_GPRS_DTI_list | +----------------------------------------------------------------------+ PURPOSE : Init all DTI identifier for GPRS. */ GLOBAL SHORT cmhSM_connect_working_cid ( void ) { T_GPRS_CONT_CLASS *context_info = &pdp_context[work_cids[cid_pointer] - 1]; switch ( context_info->entity_id ) { case DTI_ENTITY_PPPS: srcc_new_count(SRCC_PPPS_SNDCP_LINK); if (IS_SRC_BT(context_info->owner)) { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_BLUETOOTH, DTI_ENTITY_PPPS, DTI_ENTITY_SNDCP}; UBYTE dti_id = dti_cntrl_new_dti(DTI_DTI_ID_NOTPRESENT); dti_cntrl_est_dpath ( dti_id, entity_list, 3, SPLIT, PPP_UART_connect_dti_cb); } else { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_PPPS, DTI_ENTITY_SNDCP}; dti_cntrl_est_dpath_indirect ((UBYTE)context_info->owner, entity_list, 2, SPLIT, PPP_UART_connect_dti_cb, DTI_CPBLTY_SER, (UBYTE)work_cids[cid_pointer]); } m_mt_te_link = TRUE; break; case DTI_ENTITY_IP: #ifdef CO_UDP_IP { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_IP, DTI_ENTITY_SNDCP}; UBYTE dti_id; #ifdef FF_SAT_E if ( satShrdPrm.opchStat EQ OPCH_EST_REQ ) dti_id = simShrdPrm.sat_class_e_dti_id; else #endif /* FF_SAT_E */ dti_id = wap_dti_id; /* link_id should be created in atGD already, so just connect: */ if (!dti_cntrl_est_dpath( dti_id, entity_list, 2, APPEND, IP_UDP_connect_dti_cb)) { TRACE_EVENT("cmhSM_connect_working_cid: dti_cntrl_est_dpath returned FALSE"); return 0; } } #endif /* CO_UDP_IP */ break; #ifdef FF_SAT_E case DTI_ENTITY_SIM: { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_SIM, DTI_ENTITY_SNDCP}; /* create a SAT class E DTI ID if not present */ if ( simShrdPrm.sat_class_e_dti_id EQ DTI_DTI_ID_NOTPRESENT ) { simShrdPrm.sat_class_e_dti_id = dti_cntrl_new_dti(DTI_DTI_ID_NOTPRESENT); TRACE_EVENT_P1("sat_class_e_dti_id = %d", simShrdPrm.sat_class_e_dti_id); } srcc_new_count(SRCC_SIM_SNDCP_LINK); TRACE_FUNCTION("cmhSM_connect_working_cid:GC_TYPE_SIM"); context_info->link_id_new = dti_conn_compose_link_id (0, 0, simShrdPrm.sat_class_e_dti_id, DTI_TUPLE_NO_NOTPRESENT); dti_cntrl_est_dpath( simShrdPrm.sat_class_e_dti_id, entity_list, 2, SPLIT, SIM_SNDCP_connect_dti_cb); break; } #endif /* FF_SAT_E */ case DTI_ENTITY_NULL: { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_NULL, DTI_ENTITY_SNDCP}; UBYTE dti_id = dti_cntrl_new_dti(DTI_DTI_ID_NOTPRESENT); srcc_new_count(SRCC_NULL_SNDCP_LINK); context_info->link_id_new = dti_conn_compose_link_id (0, 0, dti_id, DTI_TUPLE_NO_NOTPRESENT ); dti_cntrl_est_dpath( dti_id, entity_list, 2, SPLIT, NULL_SNDCP_connect_dti_cb); break; } #if defined (FF_GPF_TCPIP) case DTI_ENTITY_TCPIP: { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_TCPIP, DTI_ENTITY_SNDCP}; UBYTE dti_id; dti_id = wap_dti_id; /* link_id should be created in atGD already, so just connect: */ if (!dti_cntrl_est_dpath( dti_id, entity_list, 2, SPLIT, TCPIP_connect_dti_cb)) { TRACE_EVENT("cmhSM_connect_working_cid: dti_cntrl_est_dpath returned FALSE"); return 0; } } break; #endif /* FF_GPF_TCPIP */ #if defined(FF_PKTIO) OR defined(FF_TCP_IP) OR defined (FF_PSI) case DTI_ENTITY_INVALID: { T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_SNDCP}; srcc_new_count(SRCC_PKTIO_SNDCP_LINK); dti_cntrl_est_dpath_indirect((UBYTE)context_info->owner, entity_list, 1, SPLIT, PKTIO_SNDCP_connect_dti_cb, DTI_CPBLTY_PKT, (UBYTE)work_cids[cid_pointer]); set_state_working_cid( CS_ACTIVATING ); break; } #endif /* FF_PKTIO OR FF_TCP_IP OR FF_PSI */ default: return 0; } return 1; } GLOBAL void cmhSM_disconnect_cid ( SHORT cid, T_GPRS_CONNECT_TYPE type ) { T_DTI_CONN_LINK_ID link_id = cmhSM_get_link_id_SNDCP_peer( cid, SNDCP_PEER_NORMAL ); TRACE_FUNCTION("cmhSM_disconnect_cid"); TRACE_EVENT_P1("link_id %d",link_id); if ( DTI_LINK_ID_NOTPRESENT NEQ link_id) { switch ( type ) { case GC_TYPE_DATA_LINK: srcc_delete_count( SRCC_PPPS_SNDCP_LINK ); pdp_context[cid - 1].link_id_sn = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].link_id_new = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].link_id_uart = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].entity_id = DTI_ENTITY_INVALID; m_mt_te_link = FALSE; break; case GC_TYPE_WAP: if(is_gpf_tcpip_call()) { GPF_TCPIP_STATEMENT(srcc_delete_count( SRCC_TCPIP_SNDCP_LINK )); } else { srcc_delete_count( SRCC_IP_SNDCP_LINK ); } pdp_context[cid - 1].link_id_sn = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].link_id_new = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].link_id_uart = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].entity_id = DTI_ENTITY_INVALID; break; case GC_TYPE_NULL: case GC_TYPE_EMAIL: switch ( pdp_context[cid - 1].entity_id ) { case DTI_ENTITY_IP: GPF_TCPIP_STATEMENT(case DTI_ENTITY_TCPIP:) if(is_gpf_tcpip_call()) { GPF_TCPIP_STATEMENT(srcc_delete_count( SRCC_TCPIP_SNDCP_LINK )); } else { srcc_delete_count( SRCC_IP_SNDCP_LINK ); } dti_cntrl_erase_entry(EXTRACT_DTI_ID(link_id)); break; case DTI_ENTITY_NULL: dti_cntrl_entity_disconnected( link_id, DTI_ENTITY_NULL ); srcc_delete_count( SRCC_NULL_SNDCP_LINK ); dti_cntrl_erase_entry(EXTRACT_DTI_ID(link_id)); break; #if defined(FF_PKTIO) OR defined(FF_TCP_IP) || defined(FF_GPF_TCPIP) OR defined (FF_PSI) case DTI_ENTITY_PKTIO: case DTI_ENTITY_PSI: case DTI_ENTITY_AAA: srcc_delete_count( SRCC_PKTIO_SNDCP_LINK ); break; #endif /* FF_PKTIO OR FF_TCP_IP || FF_GPF_TCPIP OR FF_PSI */ } pdp_context[cid - 1].link_id_sn = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].link_id_new = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].link_id_uart = DTI_LINK_ID_NOTPRESENT; pdp_context[cid - 1].entity_id = DTI_ENTITY_INVALID; break; } } } GLOBAL BOOL uart_is_mt_te_link( void ) { return m_mt_te_link; } GLOBAL void cmhSNDCP_Disable( T_DTI_CONN_LINK_ID link_id ) { SHORT cid = gaci_get_cid_over_link_id( link_id ); /* * disconnects the context if the link_id is the current link_id of this context * * the other case: * the context is switching to an other peer and the old link_id is requested * to be disconnected, NOT the context itself */ if (cmhSM_get_link_id_SNDCP_peer(cid, SNDCP_PEER_NORMAL) EQ link_id) { cmhSM_deactivateAContext(CMD_SRC_NONE, cid); } } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_connect_context | +----------------------------------------------------------------------+ PURPOSE : Connect an activated or deactivated PDP context with an entity. */ GLOBAL SHORT cmhSM_connect_context ( SHORT cid, T_DTI_ENTITY_ID peer, UBYTE ppp_hc, UBYTE msid ) { ULONG dti_neighbor; UBYTE dti_direction, hcomp = cmhSM_Get_h_comp() ? SMREG_COMP_BOTH_DIRECT: SMREG_COMP_NEITHER_DIRECT; TRACE_FUNCTION("cmhSM_connect_context()"); switch ( peer ) { case DTI_ENTITY_PPPS: dti_neighbor = (ULONG) PPP_NAME; dti_direction = SMREG_HOME; break; case DTI_ENTITY_NULL: dti_neighbor = (ULONG) NULL_NAME; dti_direction = SMREG_NEIGHBOR; smShrdPrm.direc = DIREC_MO; break; case DTI_ENTITY_IP: dti_neighbor = (ULONG) IP_NAME; dti_direction = SMREG_NEIGHBOR; smShrdPrm.direc = DIREC_MO; #ifdef FF_WAP if (Wap_Call) rAT_WAP_start_gprs_login(); #endif /* FF_WAP */ break; #ifdef FF_SAT_E case DTI_ENTITY_SIM: dti_neighbor = (ULONG) SIM_NAME; dti_direction = SMREG_NEIGHBOR; smShrdPrm.direc = DIREC_MO; break; #endif /* FF_SAT_E */ #if defined(FF_PKTIO) OR defined(FF_TCP_IP) OR defined(FF_PSI) case DTI_ENTITY_PKTIO: dti_neighbor = (ULONG) PKTIO_NAME; dti_direction = SMREG_HOME; smShrdPrm.direc = DIREC_MO; break; case DTI_ENTITY_PSI: dti_neighbor = (ULONG) PSI_NAME; dti_direction = SMREG_HOME; smShrdPrm.direc = DIREC_MO; break; case DTI_ENTITY_AAA: dti_neighbor = (ULONG) RIV_NAME; dti_direction = SMREG_NEIGHBOR; smShrdPrm.direc = DIREC_MO; break; #endif /* FF_PKTIO OR FF_TCP_IP OR FF_PSI */ #ifdef FF_GPF_TCPIP case DTI_ENTITY_TCPIP: dti_neighbor = (ULONG) TCPIP_NAME; dti_direction = SMREG_NEIGHBOR; smShrdPrm.direc = DIREC_MO; break; #endif /* FF_GPF_TCPIP */ default: return 0; } pdp_context[cid - 1].entity_id = peer; #ifdef _SIMULATION_ dti_neighbor = 0xfe1234ef; #endif if ( DTI_LINK_ID_NOTPRESENT EQ pdp_context[cid - 1].link_id_sn ) { /* context is deactivated */ cmhSM_GetNewNSapi(); psaSM_ActivateReq ( cid, (UBYTE) (hcomp? ppp_hc: 0), msid, hcomp, pdp_context[cid - 1].link_id_new, dti_neighbor, dti_direction ); } else { /* context is activated */ EXTERN void psaSN_SwitchReq ( UBYTE nsapi, ULONG dti_linkid, ULONG dti_neighbor, UBYTE dti_direction ); psaSN_SwitchReq ( pdp_context[cid - 1].nsapi, pdp_context[cid - 1].link_id_new, dti_neighbor, dti_direction); dti_cntrl_close_dpath_from_dti_id (EXTRACT_DTI_ID(pdp_context[cid - 1].link_id_sn)); dti_cntrl_entity_disconnected( pdp_context[cid - 1].link_id_sn, DTI_ENTITY_SNDCP ); dti_cntrl_erase_entry( EXTRACT_DTI_ID(pdp_context[cid - 1].link_id_sn) ); } return 1; } GLOBAL void cp_pdp_primitive(T_SMREG_PDP_ACTIVATE_CNF * pdp_activate_cnf, T_PPP_PDP_ACTIVATE_RES *activate_result) { activate_result->ppp_hc = pdp_activate_cnf->ppp_hc; activate_result->msid = pdp_activate_cnf->msid; /* * copy IP address */ activate_result->ip = pdp_activate_cnf->pdp_address.buff[0]; activate_result->ip = activate_result->ip << 8; activate_result->ip+= pdp_activate_cnf->pdp_address.buff[1]; activate_result->ip = activate_result->ip << 8; activate_result->ip+= pdp_activate_cnf->pdp_address.buff[2]; activate_result->ip = activate_result->ip << 8; activate_result->ip+= pdp_activate_cnf->pdp_address.buff[3]; activate_result->sdu.l_buf = pdp_activate_cnf->sdu.l_buf; activate_result->sdu.o_buf = 0; if (pdp_activate_cnf->sdu.l_buf > 0) { memcpy(activate_result->sdu.buf, &pdp_activate_cnf->sdu.buf[pdp_activate_cnf->sdu.o_buf >> 3], pdp_activate_cnf->sdu.l_buf >> 3); } } GLOBAL SHORT cmhSM_context_connected( USHORT nsapi ) { T_GPRS_CONT_CLASS *context_info = &pdp_context[nsapi_to_cid[nsapi] - 1]; UBYTE ip[4]; TRACE_FUNCTION("cmhSM_context_connected"); context_info->link_id_sn = context_info->link_id_new; context_info->link_id_new = DTI_LINK_ID_NOTPRESENT; switch (context_info->entity_id) { case DTI_ENTITY_PPPS: cmhSM_pdp_address_to_ip(&context_info->allocated_pdp_addr, ip); psaGPPP_PDP_Activate(0, 0, ip, context_info->network_pco.pco, context_info->network_pco.len); set_state_working_cid( CS_ESTABLISH_3 ); break; #ifdef FF_PKTIO case DTI_ENTITY_PKTIO: #endif /* FF_PKTIO */ #ifdef FF_PSI case DTI_ENTITY_PSI: #endif /* FF_PSI */ #ifdef FF_SAT_E case DTI_ENTITY_SIM: #endif /* FF_SAT_E */ #ifdef FF_TCP_IP case DTI_ENTITY_AAA: #endif /* FF_TCP_IP */ #if defined (FF_SAT_E) OR defined (FF_TCP_IP) OR defined (FF_PKTIO) OR defined (FF_PSI) dti_cntrl_entity_connected( context_info->link_id_sn, DTI_ENTITY_SNDCP, DTI_OK); set_state_working_cid( CS_ACTIVATED ); #if defined(FF_PKTIO) OR defined (FF_PSI) cmhSM_next_work_cid(smEntStat.curCmd); #endif /* FF_PKTIO OR FF_PSI */ break; #endif /* #if defined (FF_SAT_E) OR defined (FF_TCP_IP) OR defined (FF_PKTIO) OR FF_PSI */ } /* switch (context_info->entity_id) */ return 1; } /* GLOBAL SHORT cmhSM_context_connected( USHORT nsapi ) */ /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_set_PCO | +----------------------------------------------------------------------+ PURPOSE : Set a PCO in the context of the cid. */ GLOBAL void cmhSM_set_PCO( SHORT cid, T_PCO_TYPE pco_type, UBYTE* buf_addr, UBYTE length) { T_GPRS_CONT_PCO* dest; switch ( pco_type ) { case PCO_USER: dest = &pdp_context[cid - 1].user_pco; break; case PCO_NETWORK: dest = &pdp_context[cid - 1].network_pco; break; } /*lint -e(644) */ /* all possible types defined */ memcpy(dest->pco, buf_addr, length); dest->len = length; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_get_dti_SNDCP_pper | +----------------------------------------------------------------------+ PURPOSE : Give back the right DTI-ID for the SNDCP - peer connection. */ GLOBAL ULONG cmhSM_get_link_id_SNDCP_peer( SHORT cid, T_SNDCP_PEER which ) { switch ( which ) { case SNDCP_PEER_NORMAL: return pdp_context[cid - 1].link_id_new NEQ DTI_LINK_ID_NOTPRESENT ? pdp_context[cid - 1].link_id_new: pdp_context[cid - 1].link_id_sn; case SNDCP_PEER_SWITCHED: return pdp_context[cid - 1].link_id_sn; } return DTI_LINK_ID_NOTPRESENT; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : code ROUTINE : cmhSM_context_deactivated | +----------------------------------------------------------------------+ PURPOSE : Control the answer of context deactivations started by an AT command. */ GLOBAL void cmhSM_context_deactivated( USHORT nsapi_set ) { switch( working_cgact_actions.state ) { case T_CDS_RUNNING: if ( nsapi_set & working_cgact_actions.nsapi_set ) { /* nsapi deactivation is requested */ working_cgact_actions.nsapi_set &= ~nsapi_set; if ( ! (working_cgact_actions.cid_set OR working_cgact_actions.nsapi_set ) ) { R_AT( RAT_OK, working_cgact_actions.srcId ) ( AT_CMD_CGACT ); working_cgact_actions.state = T_CDS_IDLE; } } break; case T_CDS_IDLE: break; } } /* +----------------------------------------------------------------------+ | PROJECT : GSM-PS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : deactivateAContextForCGACT | +----------------------------------------------------------------------+ PURPOSE : deactivate a context for CGACT RETURN VALUE : TRUE - AT_EXCT have to be returned for this context FALSE - AT_CMPL have to be reported for this context */ static T_ACI_RETURN deactivateAContextForCGACT(SHORT cid) { T_CONTEXT_STATE ctx_state = get_state_over_cid( cid ); SRCC_LINK_NO srcc_link_no= SRCC_INVALID_LINK; T_DTI_ENTITY_ID dti_entity_id= DTI_ENTITY_INVALID; TRACE_FUNCTION("deactivateAContextForCGACT()"); #if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP) /* * additinal behaviour for WAP * abort ATD*98# before context activation requested * 2003.05.06 brz */ if(is_gpf_tcpip_call()) { GPF_TCPIP_STATEMENT(srcc_link_no = SRCC_TCPIP_SNDCP_LINK); GPF_TCPIP_STATEMENT(dti_entity_id = DTI_ENTITY_TCPIP); } else { srcc_link_no = SRCC_IP_SNDCP_LINK; dti_entity_id = DTI_ENTITY_IP; } if( TRUE NEQ srcc_reserve_sources( srcc_link_no, 1 ) AND DTI_LINK_ID_NOTPRESENT NEQ pdp_context[cid - 1].link_id_new AND cid EQ work_cids[cid_pointer] OR pdp_context[cid - 1].entity_id EQ dti_entity_id) { psaTCPIP_Deactivate(cmhSM_IP_activate_cb); if(CS_UNDEFINED EQ ctx_state OR CS_DEFINED EQ ctx_state ) { if(is_gpf_tcpip_call()) { GPF_TCPIP_STATEMENT(wap_state = TCPIP_Deactivation); } else { wap_state = UDPA_Deactivation; } dti_cntrl_close_dpath_from_dti_id( EXTRACT_DTI_ID(cmhSM_get_link_id_SNDCP_peer(cid , SNDCP_PEER_NORMAL))); } if( CS_ATTACHING_AFTER_UNDEF EQ ctx_state OR CS_ATTACHING_AFTER_DEF EQ ctx_state OR CS_WAITS_FOR_ACTIVATING EQ ctx_state ) { srcc_delete_count(srcc_link_no); return cmhSM_deactivateAContext(CMD_SRC_NONE, cid); } return AT_EXCT; } else #endif /* CO_UDP_IP || FF_GPF_TCPIP */ { if( CS_DEFINED NEQ ctx_state AND CS_UNDEFINED NEQ ctx_state ) { if( CS_ATTACHING_AFTER_UNDEF EQ ctx_state OR CS_ATTACHING_AFTER_DEF EQ ctx_state OR CS_WAITS_FOR_ACTIVATING EQ ctx_state ) { return cmhSM_deactivateAContext(CMD_SRC_NONE, cid); } else { dti_cntrl_close_dpath_from_dti_id( EXTRACT_DTI_ID(cmhSM_get_link_id_SNDCP_peer(cid , SNDCP_PEER_NORMAL))); return AT_EXCT; } } } return AT_CMPL; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_deactivateAContext | +----------------------------------------------------------------------+ PURPOSE : deactivate some contexts (able for serial multiplexer mode). */ GLOBAL T_ACI_RETURN cmhSM_deactivateContexts( T_ACI_CMD_SRC srcId, SHORT *cids) { T_ACI_RETURN ret_value = AT_CMPL; T_CONTEXT_STATE state; USHORT nsapi_set = 0, cid_set = 0; SHORT i, all_cids[MAX_CID + 1] = {1, 2, INVALID_CID}; TRACE_FUNCTION("cmhSM_deactivateContexts"); if( T_CDS_RUNNING EQ working_cgact_actions.state) { TRACE_EVENT("cgact_ation is running: bussy returned"); return AT_FAIL; /* AT_BUSY */ } if(INVALID_CID EQ *cids) { cids = all_cids; } for(i = 0; cids[i] NEQ INVALID_CID; i++) { state = pdp_context[cids[i] - 1].state; #if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP) #ifndef _SIMULATION_ pdp_context[cids[i] - 1].owner = srcId; #endif #else pdp_context[cids[i] - 1].owner = srcId; #endif if(AT_EXCT EQ deactivateAContextForCGACT( cids[i] )) { ret_value = AT_EXCT; if(0 NEQ pdp_context[cids[i] - 1].nsapi) { nsapi_set |= (1 << pdp_context[cids[i] - 1].nsapi); if(state EQ CS_DATA_LINK OR state EQ CS_ACTIVATED OR state EQ CS_CONTEXT_REACTIVATION_1) { cid_set = 1 << (cids[i] - 1); } } else { cid_set = 1 << (cids[i] - 1); } } } if(cid_set OR nsapi_set) { working_cgact_actions.state = T_CDS_RUNNING; working_cgact_actions.nsapi_set = nsapi_set; working_cgact_actions.cid_set = cid_set; working_cgact_actions.srcId = srcId; } cmhSM_stop_context_reactivation(); return ret_value; } /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_getCurQOS | +----------------------------------------------------------------------+ PURPOSE : This function returns the current QOS settings. */ #ifdef FF_SAT_E GLOBAL T_QOS* cmhSM_getCurQOS( SHORT cid ) { return &pdp_context[cid - 1].qos; } #endif /* FF_SAT_E */ /* +----------------------------------------------------------------------+ | PROJECT : GPRS (8441) MODULE : CMH_SMF | | STATE : finnished ROUTINE : cmhSM_deactivateAContext | +----------------------------------------------------------------------+ PURPOSE : deactivate all contexts (able for serial multiplexer mode). */ GLOBAL T_ACI_RETURN cmhSM_deactivateAContext( T_ACI_CMD_SRC srcId, SHORT cid ) { TRACE_FUNCTION("cmhSM_deactivateAContext()") ; switch( get_state_over_cid( cid ) ) { case CS_UNDEFINED: case CS_DEFINED: /* * context ís deactivated -> not action necessary */ break; case CS_ATTACHING_AFTER_UNDEF: /* * CGDATA has started the attach procedure * before establish data link * CGDATA has to be stoped */ set_state_over_cid( cid, CS_UNDEFINED ); psaGMM_Detach( GMMREG_DT_GPRS ); gpppEntStat.curCmd = AT_CMD_NONE; cid_pointer = 0; *work_cids = 0; if(CMD_SRC_NONE EQ srcId) { pdp_context[cid - 1].owner = gpppEntStat.entOwn; gaci_RAT_caller ( RAT_NO_CARRIER, cid, AT_CMD_CGDATA, 0 ); } return AT_CMPL; case CS_ATTACHING_AFTER_DEF: /* * CGDATA has started the attach procedure * before establish data link * CGDATA has to be stoped */ set_state_over_cid( cid, CS_DEFINED ); psaGMM_Detach( GMMREG_DT_GPRS ); gpppEntStat.curCmd = AT_CMD_NONE; cid_pointer = 0; *work_cids = 0; if(CMD_SRC_NONE EQ srcId) { pdp_context[cid - 1].owner = gpppEntStat.entOwn; gaci_RAT_caller ( RAT_NO_CARRIER, cid, AT_CMD_CGDATA, 0 ); } return AT_CMPL; case CS_ESTABLISH_1: /* * context not activated, but PPP has to be terminated */ set_state_over_cid( cid, CS_ABORT_ESTABLISH ); dti_cntrl_entity_disconnected( pdp_context[cid - 1].link_id_new, DTI_ENTITY_SNDCP ); if (uartShrdPrm.escape_seq EQ UART_DETECT_ESC) { psaGPPP_Terminate( PPP_LOWER_LAYER_DOWN ); } else { psaGPPP_Terminate( PPP_LOWER_LAYER_UP ); } uartShrdPrm.escape_seq = UART_DETECT_DTR; return AT_EXCT; case CS_DATA_LINK: /*lint -fallthrough*/ case CS_ESTABLISH_2: case CS_ESTABLISH_3: /* * context has to be deactivated and PPP has to be terminated */ set_state_over_cid( cid, CS_CONTEXT_REACTIVATION_1 ); psaSM_PDP_Deactivate( (USHORT) (1 << pdp_context[cid - 1].nsapi), SMREG_NONLOCAL); psaGPPP_Terminate( PPP_LOWER_LAYER_UP ); return AT_EXCT; case CS_ACTIVATED: /* * special handling for context switching */ if(DTI_LINK_ID_NOTPRESENT NEQ pdp_context[cid - 1].link_id_sn AND DTI_LINK_ID_NOTPRESENT NEQ pdp_context[cid - 1].link_id_new ) { return AT_CMPL; } /*lint -fallthrough*/ case CS_ACTIVATING: /* * +CGACT aborted */ set_state_over_cid( cid, CS_DEACTIVATE_NORMAL ); psaSM_PDP_Deactivate( (USHORT) (1 << pdp_context[cid - 1].nsapi), SMREG_NONLOCAL); return AT_EXCT; case CS_WAITS_FOR_ACTIVATING: /* * reset command state it is enough */ set_state_working_cid( CS_DEFINED ); gpppEntStat.curCmd = AT_CMD_NONE; smEntStat.curCmd = AT_CMD_NONE; *work_cids = 0; cid_pointer = 0; return AT_CMPL; case CS_ABORT_ESTABLISH: case CS_DEACTIVATE_NORMAL: case CS_BREAKDOWN_LINK_ERROR: case CS_BREAKDOWN_LINK_NORMAL: /* * context is during deactivation procedure -> not action necessary */ return AT_EXCT; case CS_CONTEXT_REACTIVATION_1: case CS_CONTEXT_REACTIVATION_2: /* * context is during deactivation procedure * -> not action for context deactivation or PPP termination necessary */ return AT_EXCT; } return AT_FAIL; } GLOBAL BOOL cmhSM_isContextActive( void ) { int i = SMH_FIRST_FREE_NSAPIS; while ( i <= SMH_LAST_FREE_NSAPIS AND ( nsapi_to_cid[i] EQ INVALID_CID)) i++; if ( i > SMH_LAST_FREE_NSAPIS) return FALSE; return TRUE; } #endif /* GPRS */ /*==== EOF ========================================================*/