view src/aci2/aci/cmh_smr.c @ 600:8f50b202e81f

board preprocessor conditionals: prep for more FC hw in the future This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and all preprocessor conditionals throughout the code base that tested for it, replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These new symbols are specified as follows: CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by Mother Mychaela under the FreeCalypso trademark. This family will include modem products (repackagings of the FCDEV3B, possibly with RFFE or even RF transceiver changes), and also my desired FreeCalypso handset product. CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products (which will be firmware-compatible with the FCDEV3B if they use TI Rita transceiver, or will require a different fw build if we switch to one of Silabs Aero transceivers), but not the handset product. Right now this CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize everything dealing with MCSI. At the present moment the future of FC hardware evolution is still unknown: it is not known whether we will ever have any beyond-FCDEV3B hardware at all (contingent on uncertain funding), and if we do produce further FC hardware designs, it is not known whether they will retain the same FIC modem core (triband), if we are going to have a quadband design that still retains the classic Rita transceiver, or if we are going to switch to Silabs Aero II or some other transceiver. If we produce a quadband modem that still uses Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination, and the current fcdev3b build target will be renamed to fcmodem. OTOH, if that putative quadband modem will be Aero-based, then it will require a different fw build target, the fcdev3b target will stay as it is, and the two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM, but will have different RF_FAM numbers. But no matter which way we are going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B in places like ACI, and the present change clears the way for future evolution.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 01 Apr 2019 01:05:24 +0000
parents 93999a60b835
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  
|  Modul   :  
+----------------------------------------------------------------------------- 
|  Copyright 2002 Texas Instruments Berlin, AG 
|                 All rights reserved. 
| 
|                 This file is confidential and a trade secret of Texas 
|                 Instruments Berlin, AG 
|                 The receipt of or possession of this file does not convey 
|                 any rights to reproduce or disclose its contents or to 
|                 manufacture, use, or sell anything it may describe, in 
|                 whole, or in part, without the specific written consent of 
|                 Texas Instruments Berlin, AG. 
+----------------------------------------------------------------------------- 
|  Purpose :  This module defines the functions which are responsible
|             for the responses of the protocol stack adapter for
|             GPRS session management ( SM ).
+----------------------------------------------------------------------------- 
*/ 

#if defined (GPRS) && defined (DTI)

#ifndef CMH_SMR_C
#define CMH_SMR_C
#endif

#include "aci_all.h"
/*==== INCLUDES ===================================================*/
#include "dti.h"      /* functionality of the dti library */
#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_cmd.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_sm.h"
#include "psa_gppp.h"

#include "cmh.h"
#include "cmh_sm.h"
#include "cmh_gppp.h"
#include "gaci_srcc.h"
#include "psa_uart.h"

#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
#include "wap_aci.h"
#include "psa_tcpip.h"

#include "psa_cc.h"
#include "cmh_cc.h"
#include "psa_sat.h"
#include "cmh_sat.h"

#include "dcm_f.h"
#endif /* (CO_UDP_IP) || defined (FF_GPF_TCPIP) */

/*==== CONSTANTS ==================================================*/


/*==== TYPES ======================================================*/


/*==== EXPORT =====================================================*/

/*==== VARIABLES ==================================================*/

/*==== FUNCTIONS ==================================================*/


static void dumpContextInfo(SHORT cid)
{
  TRACE_EVENT_P2("ERROR in context state: cid %d, state %d", 
                cid, pdp_context[cid-1].state);
  TRACE_EVENT_P3("dump: nsapi %d, srcID %d, connected entity %d", 
                  pdp_context[cid-1].nsapi, pdp_context[cid-1].owner,
                  pdp_context[cid-1].entity_id);
  if(smEntStat.curCmd NEQ AT_CMD_NONE)
  {
    TRACE_EVENT_P1("dump running command: %d", smEntStat.curCmd); 
  }
  TRACE_EVENT_P3("dump link_ids: new %d sn %d uart %d", 
      pdp_context[cid-1].link_id_new, pdp_context[cid-1].link_id_sn,
      pdp_context[cid-1].link_id_uart); 
}

#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
static BOOL is_ip_dti_id(T_DTI_ENTITY_ID dti_id)
{
  if(is_gpf_tcpip_call()) {
    GPF_TCPIP_STATEMENT(return dti_id EQ DTI_ENTITY_TCPIP);
  }
  else {
    return dti_id EQ DTI_ENTITY_IP;
  }
}
#endif

static void get_dns_address(char* dns1, char *dns2, UBYTE *pco, UBYTE len)
{
  ULONG tmp_dns1, tmp_dns2, gateway;
  utl_analyze_pco(pco,len, &tmp_dns1, &tmp_dns2, &gateway);

  sprintf(dns1, "%03u.%03u.%03u.%03u", (tmp_dns1 & 0xff000000) >> 24,
                                       (tmp_dns1 & 0x00ff0000) >> 16,
                                       (tmp_dns1 & 0x0000ff00) >> 8 ,
                                       (tmp_dns1 & 0x000000ff) );
  sprintf(dns2, "%03u.%03u.%03u.%03u", (tmp_dns2 & 0xff000000) >> 24,
                                       (tmp_dns2 & 0x00ff0000) >> 16,
                                       (tmp_dns2 & 0x0000ff00) >> 8 ,
                                       (tmp_dns2 & 0x000000ff) );
}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finished         ROUTINE : cmhSM_Activated              |
+-------------------------------------------------------------------+

  PURPOSE : confirms a successful context activation

*/
GLOBAL SHORT cmhSM_Activated ( T_SMREG_PDP_ACTIVATE_CNF *pdp_cnf )
{
  T_CGEREP_EVENT_REP_PARAM  event;
  char dns1[16], dns2[16];
  SHORT _cid = work_cids[cid_pointer] - 1;
  T_ACI_AT_CMD curCmd = smEntStat.curCmd;
  UBYTE ip[4];
  int i = 0;

  TRACE_FUNCTION ("cmhSM_Activated()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( get_state_working_cid() )
  {
    case( CS_ACTIVATING ):

      R_AT( RAT_CGACT, smEntStat.entOwn )(pdp_context[_cid].link_id_new);

      set_state_working_cid( CS_ACTIVATED );

      dti_cntrl_entity_connected( pdp_context[_cid].link_id_new, DTI_ENTITY_SNDCP, DTI_OK );
      pdp_context[_cid].link_id_sn = pdp_context[_cid].link_id_new;
      pdp_context[_cid].link_id_new = DTI_LINK_ID_NOTPRESENT;

      sprintf(pdp_context[_cid].allocated_pdp_addr, "%03hd.%03hd.%03hd.%03hd",
                pdp_cnf->pdp_address.buff[0],
                pdp_cnf->pdp_address.buff[1],
                pdp_cnf->pdp_address.buff[2],
                pdp_cnf->pdp_address.buff[3] );

      cmhSM_set_PCO((SHORT)(_cid + 1), PCO_NETWORK,
                                &pdp_cnf->sdu.buf[pdp_cnf->sdu.o_buf >> 3],
                                (UBYTE) (pdp_cnf->sdu.l_buf >> 3));

      get_dns_address(dns1, dns2,
                      (UBYTE*)pdp_context[_cid].network_pco.pco,
                      pdp_context[_cid].network_pco.len);

      TRACE_EVENT_P3("PDP Address: %s, DNS1: %s, DNS2: %s",
                     pdp_context[_cid].allocated_pdp_addr,dns1,dns2);

#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
      /* if WAP/TCPIP over GPRS is in progress, request WAP configuration */
      if ( is_ip_dti_id(pdp_context[_cid].entity_id) )
      {
        psaTCPIP_Configure(NULL, pdp_context[_cid].allocated_pdp_addr,
                           NULL, (UBYTE*)dns1, (UBYTE*)dns2, 1500, 
                           cmhSM_IP_activate_cb );
      }
#endif /* (CO_UDP_IP) || defined (FF_GPF_TCPIP) */

      /*
       *  do we need one more context activation
       */
      if ( FALSE EQ cmhSM_next_work_cid( curCmd ) )
      {
        if( AT_CMD_CGACT EQ curCmd)
        {
          gaci_RAT_caller ( RAT_OK, (SHORT) (_cid + 1), (UBYTE) curCmd, 0 );

          /* log result */
          cmh_logRslt ( pdp_context[_cid].owner, RAT_OK, curCmd, -1, -1, -1 );
        }
      }
      break;

    case( CS_ESTABLISH_2 ):
    /*
     *---------------------------------------------------------------
     * inform PPP
     *---------------------------------------------------------------
     */
      cmhSM_set_PCO((SHORT)(_cid + 1), PCO_NETWORK,
                                &pdp_cnf->sdu.buf[pdp_cnf->sdu.o_buf >> 3],
                                (UBYTE) (pdp_cnf->sdu.l_buf >> 3));

      sprintf(pdp_context[_cid].allocated_pdp_addr, "%03hd.%03hd.%03hd.%03hd",
                pdp_cnf->pdp_address.buff[0],
                pdp_cnf->pdp_address.buff[1],
                pdp_cnf->pdp_address.buff[2],
                pdp_cnf->pdp_address.buff[3] );
      
      cmhSM_pdp_address_to_ip(&pdp_context[_cid].allocated_pdp_addr, ip);

      psaGPPP_PDP_Activate(pdp_cnf->ppp_hc, pdp_cnf->msid, ip,
                                          &pdp_cnf->sdu.buf[pdp_cnf->sdu.o_buf >> 3], 
                                          (UBYTE) (pdp_cnf->sdu.l_buf >> 3));

      set_state_working_cid( CS_ESTABLISH_3 );

      dti_cntrl_entity_connected( pdp_context[_cid].link_id_new, DTI_ENTITY_SNDCP, DTI_OK );

      pdp_context[_cid].link_id_sn = pdp_context[_cid].link_id_new;
      pdp_context[_cid].link_id_new = DTI_LINK_ID_NOTPRESENT;

      break;
      
    default:
      return -1;
  }
  
  /*
  *   %CGEV - GPRS event reporting
  */
  strcpy(event.act.pdp_type, pdp_context[_cid].con.pdp_type);
  strcpy(event.act.pdp_addr, pdp_context[_cid].allocated_pdp_addr);
  event.act.cid      = _cid + 1;
  
  if (smShrdPrm.direc == DIREC_MO)
  {
    for( i = 0; i < CMD_SRC_MAX; i++ )
    {
        R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_ME_ACT, &event );
    }
  }
  else
  {
    for( i = 0; i < CMD_SRC_MAX; i++ )
    {
        R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_NW_ACT, &event );
    }
  }

  return 0;
}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finished         ROUTINE :                              |
+-------------------------------------------------------------------+

  PURPOSE : 

*/

LOCAL void cp_pdp_rej_prim(T_SMREG_PDP_ACTIVATE_REJ * pdp_activate_rej,
                           T_PPP_PDP_ACTIVATE_REJ *activate_result)
{
 
  activate_result->ppp_cause = pdp_activate_rej->smreg_cause;

}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finished         ROUTINE : cmhSM_NoActivate             |
+-------------------------------------------------------------------+

  PURPOSE : indicates a context activation failed

*/
GLOBAL SHORT cmhSM_NoActivate ( void )
{
  T_CGEREP_EVENT_REP_PARAM  event;
  T_CONTEXT_STATE   state;
  T_DTI_CONN_LINK_ID link_id;
  int i = 0;
 
  TRACE_FUNCTION ("cmhSM_NoActivate()");
/*
 *-------------------------------------------------------------------
 * Set error cause for SIM owner
 *-------------------------------------------------------------------
 */
#ifdef FF_SAT_E
  gaci_SAT_err(smShrdPrm.pdp_rej->smreg_cause);
#endif /* FF_SAT_E */
/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( state = get_state_working_cid() )
  {
    case CS_UNDEFINED:
    case CS_DEFINED:
    case CS_ESTABLISH_1:
    case CS_ESTABLISH_3:
    case CS_ACTIVATED:
    case CS_WAITS_FOR_ACTIVATING:
    case CS_DATA_LINK:
    case CS_DEACTIVATE_NORMAL:
    case CS_CONTEXT_REACTIVATION_1:
    case CS_CONTEXT_REACTIVATION_2:
    case CS_BREAKDOWN_LINK_ERROR:
    case CS_BREAKDOWN_LINK_NORMAL:
      dumpContextInfo(work_cids[cid_pointer]);
      return 0;
    case CS_ACTIVATING:
      link_id = cmhSM_get_link_id_SNDCP_peer(work_cids[cid_pointer], SNDCP_PEER_NORMAL);

      switch(pdp_context[work_cids[cid_pointer] - 1].entity_id)
      {
        case DTI_ENTITY_PKTIO:
        case DTI_ENTITY_PSI:          
          set_state_working_cid( CS_DEACTIVATE_NORMAL);
          dti_cntrl_close_dpath_from_dti_id (EXTRACT_DTI_ID(link_id));
/*          gaci_RAT_caller(RAT_NO_CARRIER, work_cids[cid_pointer], AT_CMD_CGDATA, 0); */
          break;
#if defined (CO_UDP_IP) OR defined (FF_GPF_TCPIP)
        case DTI_ENTITY_IP:
        GPF_TCPIP_STATEMENT(case DTI_ENTITY_TCPIP:)
          set_state_working_cid( CS_DEFINED);
          dti_cntrl_close_dpath_from_dti_id (EXTRACT_DTI_ID(link_id));
          /* tell WAP ACI that contextactivation was rejected */
          psaTCPIP_Deactivate(cmhSM_IP_activate_cb);
          dti_cntrl_entity_disconnected( link_id, DTI_ENTITY_SNDCP );
          break;
#endif /* WAP OR FF_SAT_E OR FF_GPF_TCPIP */          
        default:
          /* in this case is SMREG_PDP_ACTIVATE_REJ the same as SMREG_DEACTIVATE_CNF */

          /* set parameter for SMREG_DEACTIVATE_CNF */
          smShrdPrm.nsapi_set = 1 << smShrdPrm.pdp_rej->smreg_nsapi;
          cmhSM_Deactivated(); /* SMREG_DEACTIVATE_CNF */
     
          /* the last expected primitive from SM */
          smEntStat.curCmd = AT_CMD_NONE;
          return 0;
      }

     /*
      *   GPRS event reporting
      */
      strcpy(event.act.pdp_type, pdp_context[work_cids[cid_pointer] - 1].con.pdp_type);
      strcpy(event.act.pdp_addr, pdp_context[work_cids[cid_pointer] - 1].allocated_pdp_addr);
      event.act.cid = work_cids[cid_pointer];
      for( i = 0; i < CMD_SRC_MAX; i++ )
      {
        R_AT( RAT_CGEREP, i ) ( CGEREP_EVENT_ME_DEACT, &event );
        R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_ME_DEACT, &event );
      }

      cmhSM_GiveNSapiFree(work_cids[cid_pointer]);
      cmhSM_contextDeactivated();  
      break;
    case CS_ESTABLISH_2:
    case CS_ABORT_ESTABLISH:
      /* in this case is SMREG_PDP_ACTIVATE_REJ the same as SMREG_DEACTIVATE_CNF */

      /* set parameter for SMREG_DEACTIVATE_CNF */
      smShrdPrm.nsapi_set = 1 << smShrdPrm.pdp_rej->smreg_nsapi;

      cmhSM_Deactivated(); /* SMREG_DEACTIVATE_CNF */
     
      /* the last expected primitive from SM */
      smEntStat.curCmd = AT_CMD_NONE;

      if ( state NEQ CS_ESTABLISH_2)
      {
        return 0;
      }

     /*
     *---------------------------------------------------------------
     * inform PPP
     *---------------------------------------------------------------
     */
      {
        PALLOC(act_rej_temp,PPP_PDP_ACTIVATE_REJ); /* ppass*/
        cp_pdp_rej_prim(smShrdPrm.pdp_rej,act_rej_temp);
        gpppShrdPrm.setPrm[gpppEntStat.entOwn].pdp_rej = act_rej_temp;
      }

      if( psaGPPP_PDP_Reject() < 0 )
      {
        TRACE_EVENT( "FATAL RETURN psaPPP_PDP_Reject in +CGDATA" );
        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
        return -1 ;
      }

      set_state_working_cid( CS_ABORT_ESTABLISH );
      break;
    default:
      return -1;
  }

  return 0;
}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finished         ROUTINE : cmhSM_NetActivate            |
+-------------------------------------------------------------------+

  PURPOSE : indicates a network asked for a PDP context activation

*/
GLOBAL void cmhSM_NetActivate ( void )
{
  T_CGEREP_EVENT_REP_PARAM  event;
  SHORT i = 0,                            /* holds index  counter */
        context_reactivation = 0, cid;

  TRACE_FUNCTION ("cmhSM_NetActivate()");

  /*
   *  in first only one requested context activation is provided
   *  and the request will be rejected if an other context will be
   *  activated
   */

  /*
   *  it's no check to CC neccesary, because this is no class A mobile
   */

  if ( TRUE EQ cmhSM_is_smreg_ti_used( smShrdPrm.act_ind.smreg_ti, &cid ) )
    context_reactivation = 1;

  /*
   *  no PDP context is during the setup
   */
  if ( work_cids[cid_pointer] EQ INVALID_CID                      &&
       gprs_ct_index < MAX_GPRS_CALL_TABLE_ENTRIES                &&
       ( TRUE EQ srcc_reserve_sources( SRCC_PPPS_SNDCP_LINK, 1 )  ||
         context_reactivation EQ 1)                                   )
  {
/*
 *-------------------------------------------------------------------
 * ring for call, if no call is in use
 *-------------------------------------------------------------------
 */

#ifdef AT_INTERPRETER
    /* V.24 Ring Indicator Line */
    /* io_setRngInd ( IO_RS_ON, CRING_TYP_NotPresent, CRING_TYP_NotPresent dummy parameters here, need real ones when used); */
#endif

    /* fill gprs call table */
    memcpy(&gprs_call_table[gprs_ct_index].sm_ind, &smShrdPrm.act_ind, sizeof(T_SMREG_PDP_ACTIVATE_IND));

    /* no context reactivation */
    if ( context_reactivation NEQ 1 )
    {
      gprs_call_table[gprs_ct_index].reactivation = GCTT_NORMAL;
      *gprs_call_table[gprs_ct_index].L2P = 0;
      gprs_call_table[gprs_ct_index].cid = INVALID_CID;
      gprs_ct_index++;

      for( i = 0 ; i < CMD_SRC_MAX; i++ )
      {
        R_AT( RAT_CRING, i )  ( CRING_MOD_Gprs, CRING_TYP_GPRS, CRING_TYP_NotPresent );
      }
    }
    else
    { /* context reactivation */
      gprs_call_table[gprs_ct_index].reactivation = GCTT_REACTIVATION ;
      strcpy(gprs_call_table[gprs_ct_index].L2P, "PPP");
      gprs_call_table[gprs_ct_index].cid    = cid;
      gprs_ct_index++;
    }

  }
  else
  /*
   *  one or more PDP contexts are during the setup
   */
  {
    psaSM_PDP_No_activate(smShrdPrm.act_ind.smreg_ti, SMREG_RC_INSUF_RES);

   /*
    *   GPRS event reporting
    */
    cmhSM_pdp_typ_to_string(smShrdPrm.act_ind.pdp_type, event.reject.pdp_type);
    memcpy(&event.reject.pdp_addr,
           &smShrdPrm.act_ind.pdp_address.buff,
           smShrdPrm.act_ind.pdp_address.c_buff);
    for( i = 0; i < CMD_SRC_MAX; i++ )
    {
      R_AT( RAT_CGEREP, i ) ( CGEREP_EVENT_REJECT, &event );
      R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_REJECT, &event );
    }
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finnished        ROUTINE : cmhSM_Deactivated            |
+-------------------------------------------------------------------+

  PURPOSE : confirms a successful PDP context deactivation

*/
GLOBAL void cmhSM_Deactivated ( void )
{
  T_CGEREP_EVENT_REP_PARAM  event;
  T_CONTEXT_STATE           state;
  SHORT                     cid, 
                            i, 
                            reactivation = 0,
                            rat_id = RAT_MAX;
  UBYTE                     cme_err = CME_ERR_GPRSUnspec, /* error number */
                            cmdBuf = smEntStat.curCmd;    /* buffers current command */
  USHORT                    temp_nsapiSet = smShrdPrm.nsapi_set;
  T_DTI_CONN_LINK_ID        dti_id_sn;
  UBYTE srcId = srcId_cb;
  
  TRACE_FUNCTION ("cmhSM_Deactivated()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */

  while ( CS_INVALID_STATE NEQ (state = get_state_over_nsapi_set( &smShrdPrm.nsapi_set, &cid )) )
  {
    dti_id_sn = cmhSM_get_link_id_SNDCP_peer( cid, SNDCP_PEER_NORMAL );

    switch ( state )
    {
      case CS_UNDEFINED:
      case CS_DEFINED:
      case CS_WAITS_FOR_ACTIVATING:
      case CS_ESTABLISH_1:
      case CS_ESTABLISH_3:
      case CS_ACTIVATED:
      case CS_DATA_LINK:
      default:
        dumpContextInfo(cid);
        continue;
      case CS_ESTABLISH_2:
        set_state_over_cid ( cid, CS_ABORT_ESTABLISH );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        break;
      case CS_ABORT_ESTABLISH:
      case CS_BREAKDOWN_LINK_ERROR:
        TRACE_EVENT("state: CS_BREAKDOWN_LINK_ERROR");
        set_state_over_cid ( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_disconnect_cid(cid, GC_TYPE_DATA_LINK);
        if(ati_user_output_cfg[srcId].CMEE_stat EQ CMEE_MOD_Disable)
          rat_id = RAT_NO_CARRIER;
        else
          rat_id = RAT_CME;
        break;
      case CS_BREAKDOWN_LINK_NORMAL:
        TRACE_EVENT("state: CS_BREAKDOWN_LINK_NORMAL");
        set_state_over_cid ( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_disconnect_cid(cid, GC_TYPE_DATA_LINK);
        rat_id = RAT_NO_CARRIER;
        break;
      case CS_DEACTIVATE_NORMAL:
        TRACE_EVENT("state: CS_DEACTIVATE_NORMAL") ;
        set_state_over_cid ( cid, CS_DEFINED );
#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
        if ( is_ip_dti_id(pdp_context[cid-1].entity_id) )
        {
          /* tell WAP ACI that contextactivation was rejected */
          psaTCPIP_Deactivate(cmhSM_IP_activate_cb);
          dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        }
        else
#endif /* CO_UDP_IP || FF_GPF_TCPIP */
        {
          dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
          cmhSM_disconnect_cid(cid, GC_TYPE_NULL);
        }
        break;
      case CS_ACTIVATING:
        TRACE_EVENT("state: CS_ACTIVATING");
        set_state_over_cid ( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        if(pdp_context[cid - 1].entity_id EQ DTI_ENTITY_NULL)
        {       
          rat_id = RAT_CME;
        }
        cmhSM_disconnect_cid(cid, GC_TYPE_NULL);
        break;
      case CS_CONTEXT_REACTIVATION_1:
        TRACE_EVENT("state: CD_CONTEXT_REACTIVATION_1");
        set_state_over_cid(cid, CS_CONTEXT_REACTIVATION_2);
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        smEntStat.curCmd = AT_CMD_NONE;
        cmhSM_GiveNSapiFree(cid);
        continue;
      case CS_CONTEXT_REACTIVATION_2:
        TRACE_EVENT("state: CD_CONTEXT_REACTIVATION_2");
        set_state_over_cid ( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_disconnect_cid(cid, GC_TYPE_DATA_LINK);
        smEntStat.curCmd = AT_CMD_NONE;
        rat_id = RAT_NO_CARRIER;
        reactivation = 1;
        break;
    }

    if ( reactivation EQ 0 )
    {
      if ( smEntStat.entOwn EQ get_owner_over_cid(cid) )
        switch( smEntStat.curCmd )
        {
          case( AT_CMD_CGDATA ):
          case( AT_CMD_CGACT ):
            smEntStat.curCmd = AT_CMD_NONE;
            cid_pointer  = 0;
            *work_cids = 0;
        }
    }

   /*
    *   GPRS event reporting
    */
    strcpy(event.act.pdp_type, pdp_context[cid - 1].con.pdp_type);
    strcpy(event.act.pdp_addr, pdp_context[cid - 1].allocated_pdp_addr);
    event.act.cid      = cid;
    for( i = 0; i < CMD_SRC_MAX; i++ )
    {
      R_AT( RAT_CGEREP, i ) ( CGEREP_EVENT_ME_DEACT, &event );
      R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_ME_DEACT, &event );
    }

    cmhSM_GiveNSapiFree(cid);

    if ( rat_id NEQ RAT_MAX )
    {
      gaci_RAT_caller ( rat_id, cid, cmdBuf, cme_err );

      rat_id = RAT_MAX;
      cid_pointer  = 0;
      *work_cids = 0;

      cmhSM_context_reactivation();
    }
  }

  cmhSM_context_deactivated(temp_nsapiSet);
  cmhSM_contextDeactivated();
}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finnished        ROUTINE : cmhSM_NetDeactivate          |
+-------------------------------------------------------------------+

  PURPOSE : indicates a PDP context deactivation

*/
GLOBAL void cmhSM_NetDeactivate ( void )
{
  T_CGEREP_EVENT_REP_PARAM  event;
  T_CONTEXT_STATE           state;
  SHORT                     cid, 
                            i = 0, 
                            inform_ppp = 1, 
                            rat_id = RAT_MAX;
  UBYTE                     cme_err = CME_ERR_Unknown, /* error number */
                            cmdBuf = AT_CMD_NONE;      /* buffers current command */
  USHORT                    temp_nsapiSet = smShrdPrm.nsapi_set;
  T_DTI_CONN_LINK_ID        dti_id_sn;
  UBYTE srcId = srcId_cb;
  
  TRACE_FUNCTION ("cmhSM_NetDeactivate()");

  while ( CS_INVALID_STATE NEQ (state = get_state_over_nsapi_set( &smShrdPrm.nsapi_set, &cid )) )
  {
    dti_id_sn = cmhSM_get_link_id_SNDCP_peer( cid, SNDCP_PEER_NORMAL );

    switch ( state )
    {
      case CS_UNDEFINED:
      case CS_DEFINED:
      case CS_ESTABLISH_1:
      case CS_WAITS_FOR_ACTIVATING:
        continue;
      case CS_ESTABLISH_2:
      case CS_ESTABLISH_3:
        set_state_over_cid( cid, CS_ABORT_ESTABLISH );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        break;
      case CS_ABORT_ESTABLISH:
        set_state_over_cid( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_disconnect_cid(cid, GC_TYPE_DATA_LINK);
        inform_ppp = 0;
        if(ati_user_output_cfg[srcId].CMEE_stat EQ CMEE_MOD_Disable)
          rat_id = RAT_NO_CARRIER;
        else
          rat_id = RAT_CME;
        break;
      case CS_BREAKDOWN_LINK_ERROR:
        set_state_over_cid( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_disconnect_cid(cid, GC_TYPE_DATA_LINK);
        if(ati_user_output_cfg[srcId].CMEE_stat EQ CMEE_MOD_Disable)
          rat_id = RAT_NO_CARRIER;
        else
          rat_id = RAT_CME;
        inform_ppp = 0;
        break;
      case CS_BREAKDOWN_LINK_NORMAL:
        set_state_over_cid( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_disconnect_cid(cid, GC_TYPE_DATA_LINK);
        rat_id = RAT_NO_CARRIER;
        inform_ppp = 0;
        break;
      case CS_DATA_LINK:
        set_state_over_cid( cid, CS_BREAKDOWN_LINK_NORMAL );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        break;
      case CS_ACTIVATED:
        inform_ppp = 0;
        set_state_over_cid( cid, CS_DEFINED );
#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
        if ( is_ip_dti_id(pdp_context[cid-1].entity_id) )
        {
          /* tell WAP ACI that contextactivation was rejected */
          psaTCPIP_Deactivate(cmhSM_IP_activate_cb);
          dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        }
        else
#endif /* CO_UDP_IP || FF_GPF_TCPIP */
        {
          dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
          cmhSM_disconnect_cid(cid, GC_TYPE_NULL);
        }
        break;
      case CS_DEACTIVATE_NORMAL:
        inform_ppp = 0;
        set_state_over_cid( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
        if ( is_ip_dti_id(pdp_context[cid-1].entity_id) )
        {
          /* tell WAP ACI that contextactivation was rejected */
          psaTCPIP_Deactivate(cmhSM_IP_activate_cb);
        }
        else
#endif /* CO_UDP_IP || FF_GPF_TCPIP */
        {
          cmhSM_disconnect_cid(cid, GC_TYPE_NULL);
        }
        break;
      case CS_ACTIVATING:
        inform_ppp = 0;
        set_state_over_cid( cid, CS_DEFINED );
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
#if defined (CO_UDP_IP) || defined (FF_GPF_TCPIP)
        if ( is_ip_dti_id(pdp_context[cid-1].entity_id) )
        {
          /* tell WAP ACI that contextactivation was rejected */
          psaTCPIP_Deactivate(cmhSM_IP_activate_cb);
        }
        else
#endif /* CO_UDP_IP OR FF_GPF_TCPIP */
        {
          cmhSM_disconnect_cid(cid, GC_TYPE_NULL);
        }
        if(pdp_context[cid - 1].entity_id EQ DTI_ENTITY_NULL)
        {
          rat_id = RAT_CME;
        }
        break;
      case CS_CONTEXT_REACTIVATION_1:
        set_state_over_cid(cid, CS_CONTEXT_REACTIVATION_2);
        cmhSM_stop_context_reactivation();
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        cmhSM_GiveNSapiFree(cid);
        continue;
      case CS_CONTEXT_REACTIVATION_2:
        set_state_over_cid( cid, CS_DEFINED );
        cmhSM_stop_context_reactivation();
        dti_cntrl_entity_disconnected( dti_id_sn, DTI_ENTITY_SNDCP );
        rat_id = RAT_NO_CARRIER;
        inform_ppp = 0;
        break;
    }

    if ( inform_ppp )
    {
    /*
     *---------------------------------------------------------------
     * inform PPP
     *---------------------------------------------------------------
     */  
      psaGPPP_Terminate( PPP_LOWER_LAYER_UP );
    }

    if ( smEntStat.entOwn EQ get_owner_over_cid(cid) )
      switch( smEntStat.curCmd )
      {
        case( AT_CMD_CGDATA ):
        case( AT_CMD_CGACT ):
          smEntStat.curCmd = AT_CMD_NONE;
          cid_pointer  = 0;
          *work_cids = 0;
      }

   /*
    *   GPRS event reporting
    */
    strcpy(event.act.pdp_type, pdp_context[cid - 1].con.pdp_type);
    strcpy(event.act.pdp_addr, pdp_context[cid - 1].allocated_pdp_addr);
    event.act.cid      = cid;
    for( i = 0; i < CMD_SRC_MAX; i++ )
    {
      R_AT( RAT_CGEREP, i ) ( CGEREP_EVENT_NW_DEACT, &event ); 
      R_AT( RAT_P_CGEV, i ) ( CGEREP_EVENT_NW_DEACT, &event );
    }
    
    cmhSM_GiveNSapiFree  (cid);

    if ( rat_id NEQ RAT_MAX )
    {
      gaci_RAT_caller ( rat_id, cid, cmdBuf, cme_err );

      cid_pointer  = 0;
      *work_cids = 0;
      rat_id = RAT_MAX;
    }
  }

  cmhSM_context_deactivated(temp_nsapiSet);
  cmhSM_contextDeactivated();

  /* inform SAT if needed */
#if defined (FF_SAT_E)
  cmhSAT_OpChnGPRSDeact();
#endif 
  
}

/*
+-------------------------------------------------------------------+
| PROJECT : GPRS (8441)      MODULE  : CMH_SMR                      |
| STATE   : finnished        ROUTINE : cmhSM_NetModify              |
+-------------------------------------------------------------------+

  PURPOSE : indicates a network initiated PDP context modification

*/
GLOBAL void cmhSM_NetModify ( USHORT nsapi_set, T_smreg_qos *smreg_qos )
{
  SHORT   cid, i = 0;

  TRACE_FUNCTION ("cmhSM_NetModify()");

  while ( CS_INVALID_STATE NEQ get_state_over_nsapi_set( &nsapi_set, &cid ) )
    {
      pdp_context[cid - 1].qos.preced    = smreg_qos->preced;
      pdp_context[cid - 1].qos.delay     = smreg_qos->delay;
      pdp_context[cid - 1].qos.relclass  = smreg_qos->relclass;
      pdp_context[cid - 1].qos.peak      = smreg_qos->peak;
      pdp_context[cid - 1].qos.mean      = smreg_qos->mean;

      for( i = 0 ; i < CMD_SRC_MAX; i++ )
      {
        R_AT( RAT_QOS_MOD, i ) ( cid, smreg_qos ); 
      }
    }
}

#endif /* GPRS */
/*==== EOF ========================================================*/