diff g23m/condat/ms/src/aci/cmh_smf.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m/condat/ms/src/aci/cmh_smf.c	Mon Jun 01 03:24:05 2015 +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 ========================================================*/