Compal & Pirelli targets: APCOFF register setting
changed to match what the respective original firmwares set
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 ========================================================*/