FreeCalypso > hg > fc-magnetite
diff src/aci2/aci/cmh_smf.c @ 3:93999a60b835
src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 26 Sep 2016 00:29:36 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/aci2/aci/cmh_smf.c Mon Sep 26 00:29:36 2016 +0000 @@ -0,0 +1,2927 @@ +/* ++----------------------------------------------------------------------------- +| 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 ========================================================*/