view src/g23m-aci/aci/cmh_simr.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 53929b40109c
children
line wrap: on
line source

/*
+-----------------------------------------------------------------------------
|  Project :  GSM-PS (6147)
|  Modul   :  CMH_SIMR
+-----------------------------------------------------------------------------
|  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
|             the subscriber identity module.
+-----------------------------------------------------------------------------
*/

#ifndef CMH_SIMR_C
#define CMH_SIMR_C
#endif

#include "aci_all.h"
/*==== INCLUDES ===================================================*/
#include "aci_mem.h"

#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_cmd.h"
#include "pcm.h"

#ifdef FAX_AND_DATA
#include "aci_fd.h"
#endif    /* of #ifdef FAX_AND_DATA */

#ifndef _SIMULATION_
#include "ffs/ffs.h"
#include "ffs_coat.h"
#endif

#ifdef DTI
#include "dti.h"      /* functionality of the dti library */
#include "dti_conn_mng.h"
#include "dti_cntrl_mng.h"
#endif /* DTI */

#include "phb.h"
#include "ksd.h"
#include "aci.h"
#include "psa.h"
#include "psa_sim.h"
#include "psa_cc.h"
#include "psa_sat.h"
#include "psa_mm.h"
#include "cmh.h"
#include "cmh_sim.h"
#include "cmh_mm.h"
#include "cmh_phb.h"

#include "aci_ext_pers.h"
#include "aci_slock.h"
#include "psa_sms.h"

#ifdef SIM_PERS
#include "general.h" // included for compilation error UNIT8 in sec_drv.h
#include "sec_drv.h"
#endif

#ifdef GPRS
  #include "gaci.h"
  #include "gaci_cmh.h"
  #include "psa_gmm.h"
  #include "cmh_gmm.h"
#endif

#include "p_mmcm.h"
#include "m_cc.h"

#include "aoc.h"

#ifdef DTI
#include "wap_aci.h"
#include "psa_tcpip.h"
#include "psa_l2r.h"
#endif

#ifdef SIM_PERS
EXTERN  T_ACI_SIM_CONFIG aci_slock_sim_config;     /* SIM configuration, initialised by a T_SIM_MMI_INSERT_IND */
EXTERN T_SEC_DRV_CONFIGURATION *cfg_data ;
#endif

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


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


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


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

/*==== FUNCTIONS ==================================================*/
LOCAL void cmhSIM_ProcessEvents ( T_ACI_AT_CMD at_cmd_id );
LOCAL void cmhSIM_Compare_CNUMMsisdnIdx ( void );
LOCAL void cmhSIM_SndError( T_ACI_CMD_SRC ownBuf,
                            T_ACI_AT_CMD cmdBuf,
                            T_ACI_CME_ERR cme_err );

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_SIMSync               |
+-------------------------------------------------------------------+

  PURPOSE : SIM data synchronized

*/

GLOBAL void cmhSIM_SIMSync ( void )
{
  TRACE_FUNCTION ("cmhSIM_SIMSync()");

  /* process event */
  switch( simEntStat.curCmd )
  {
    case( AT_CMD_CFUN ):
      if (mmEntStat.curCmd NEQ AT_CMD_CFUN)     /* Has MM already deregistered? */
      {
        R_AT( RAT_OK, simEntStat.entOwn )
          ( AT_CMD_CFUN );

        /* log result */
        cmh_logRslt ( simEntStat.entOwn, RAT_OK, AT_CMD_CFUN,
                          -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );
      }
      /*lint -fallthrough*/
    case( AT_CMD_COPS ):
    case( AT_CMD_P_COPS ):

      simEntStat.curCmd = AT_CMD_NONE;
      break;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : clck_fdn_accepted()          |
+-------------------------------------------------------------------+

  PURPOSE : PIN2 status allows CLCK changing the status concerning FDN.

*/

LOCAL void clck_fdn_accepted ( void )
{
  switch( simShrdPrm.setPrm[simEntStat.entOwn].actProc )
  {
    case( SIM_FDN_ENABLE ):
      if(  simShrdPrm.crdFun EQ SIM_ADN_ENABLED )
      {
        simShrdPrm.crdFun = SIM_FDN_ENABLED;
      }
      if(  simShrdPrm.crdFun EQ SIM_ADN_BDN_ENABLED )
      {
        simShrdPrm.crdFun = SIM_FDN_BDN_ENABLED;
      }

      pb_switch_adn_fdn( FDN_ENABLE, simShrdPrm.classFDN ); /* inform PHB */
      break;

    case( SIM_FDN_DISABLE ):
      if(  simShrdPrm.crdFun EQ SIM_FDN_ENABLED )
      {
        simShrdPrm.crdFun = SIM_ADN_ENABLED;
      }
      if(  simShrdPrm.crdFun EQ SIM_FDN_BDN_ENABLED )
      {
        simShrdPrm.crdFun = SIM_ADN_BDN_ENABLED;
      }
      pb_switch_adn_fdn( FDN_DISABLE, simShrdPrm.classFDN ); /* inform PHB */
      break;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhsim_simactivated_clck     |
+-------------------------------------------------------------------+
  PURPOSE : SIM activated after AT+CLCK
*/

LOCAL void cmhsim_simactivated_clck( void )
{
  T_ACI_CME_ERR err = CME_ERR_Unknown;
   
  TRACE_FUNCTION ("cmhsim_simactivated_clck()");

  simEntStat.curCmd = AT_CMD_NONE;

  switch( simShrdPrm.rslt )
  {
    case( SIM_NO_ERROR ):
      clck_fdn_accepted();

      R_AT( RAT_OK, simEntStat.entOwn )
        ( AT_CMD_CLCK );
      cmh_logRslt ( simEntStat.entOwn, RAT_OK, AT_CMD_CLCK, -1,
	  	                     BS_SPEED_NotPresent,CME_ERR_NotPresent );
      return;

    case( SIM_CAUSE_PIN2_EXPECT ):
      TRACE_EVENT_P1("simShrdPrm.pn2Stat: %d", simShrdPrm.pn2Stat);

      if ( simShrdPrm.pn2Stat EQ PS_PIN2 )
      {
        if ( ( simShrdPrm.setPrm[simEntStat.entOwn].curPIN[0] NEQ 0x00 )           AND
             ( simShrdPrm.setPrm[simEntStat.entOwn].curPIN[0] NEQ NOT_PRESENT_CHAR ) )
        {
          /* if PIN2 is required and a pin is given, then check pin with PIN2 */
          simEntStat.curCmd = AT_CMD_CLCK; /* further processing */

          simShrdPrm.setPrm[simEntStat.entOwn].PINType = PHASE_2_PIN_2;
          psaSIM_VerifyPIN();  /* verify PIN */
          return;
        }
        else
        {
          /* if PIN2 is required and no pin is given, then send cme_err with PIN2
             required message code */
          if (  simShrdPrm.PINStat EQ PS_RDY )
          {
            simShrdPrm.PINStat = PS_PIN2;
          }
          err = CME_ERR_SimPin2Req;
        }
      }
      else
      {
        err = CME_ERR_WrongPasswd;
      }
      break;

   /*case( SIM_CAUSE_PIN1_EXPECT ):
   case( SIM_CAUSE_PUK1_EXPECT ):*/

/* Should be CME_ERR_SimPuk2Req, and it is done 
                         in the default case 
 case( SIM_CAUSE_PIN2_BLOCKED):
   case( SIM_CAUSE_PUK2_EXPECT ):
      err = CME_ERR_WrongPasswd;
      break;*/

   default:
      err = cmhSIM_GetCmeFromSim( simShrdPrm.rslt );
      break;
  }

  R_AT( RAT_CME, simEntStat.entOwn )
        ( AT_CMD_CLCK, err );
  cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CLCK,
                -1, BS_SPEED_NotPresent, err );

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhsim_simactivated_start    |
+-------------------------------------------------------------------+
  PURPOSE : SIM activated after AT+CFUN, +CPIN, +CIMI and %NRG
*/
LOCAL void simactivated_cpinresult( T_ACI_CPIN_RSLT cpin_result )
{
  R_AT( RAT_CPIN, simEntStat.entOwn )
    ( cpin_result );
  R_AT( RAT_OK, simEntStat.entOwn )
    ( AT_CMD_CPIN );
  cmh_logRslt ( simEntStat.entOwn, RAT_OK, AT_CMD_CPIN,
                -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );
}

LOCAL void simactivated_errorresult( T_ACI_CME_ERR error_result, T_ACI_AT_CMD cmdBuf )
{
  R_AT( RAT_CME, simEntStat.entOwn )
  ( cmdBuf, error_result );

  if( cmdBuf NEQ AT_CMD_CIMI )
  {
    cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                  -1, BS_SPEED_NotPresent, error_result );
  }
}

LOCAL void cmhsim_simactivated_start( void )
{
  T_ACI_AT_CMD cmdBuf = simEntStat.curCmd;  /* buffers current command */

  TRACE_FUNCTION ("cmhsim_simactivated_start()");

  simEntStat.curCmd = AT_CMD_NONE;

  switch( simShrdPrm.SIMStat )
  {
    case( SS_INV   ):
      simactivated_errorresult( CME_ERR_SimWrong, cmdBuf );
      return;

    case( SS_URCHB ):
      simactivated_errorresult( CME_ERR_SimNotIns, cmdBuf );
      return;

    case( NO_VLD_SS ):
      simactivated_errorresult( CME_ERR_NotPresent, cmdBuf );
      return;

    case( SS_OK   ):
      switch( simShrdPrm.PINStat )
      {
        case( PS_PIN1 ):
          if( cmdBuf EQ AT_CMD_CPIN )
          {
            simactivated_cpinresult( CPIN_RSLT_SimPinReq );
          }
          else
          {
            simactivated_errorresult( CME_ERR_SimPinReq, cmdBuf );
          }
          break;

        case( PS_PIN2 ):
          if( cmdBuf EQ AT_CMD_CPIN )
          {
            simactivated_cpinresult( CPIN_RSLT_SimPin2Req );
          }
          else
          {
            simactivated_errorresult( CME_ERR_SimPin2Req, cmdBuf );
          }
          break;

        case( PS_RDY ):
          /* wait for SIM insert indication to complete command */
          simEntStat.curCmd = cmdBuf;
          break;
      }
      break;

    case( SS_BLKD  ):

      switch( simShrdPrm.PINStat )
      {
        case( PS_PUK1 ):
          if( cmdBuf EQ AT_CMD_CPIN )
          {
            simactivated_cpinresult( CPIN_RSLT_SimPukReq );
          }
          else
          {
            simactivated_errorresult( CME_ERR_SimPukReq, cmdBuf );
          }
          break;

          case( PS_PUK2 ):
          if( cmdBuf EQ AT_CMD_CPIN )
          {
            simactivated_cpinresult( CPIN_RSLT_SimPuk2Req );
          }
          else
          {
            simactivated_errorresult( CME_ERR_SimPuk2Req, cmdBuf );
          }
          break;
      }
      break;

  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_SIMActivated          |
+-------------------------------------------------------------------+

  PURPOSE : SIM activated

*/

GLOBAL void cmhSIM_SIMActivated ( void )
{
  T_ACI_CMD_SRC idx;

  TRACE_FUNCTION ("cmhSIM_SIMActivated()");

  /* check for command context */
  switch( simEntStat.curCmd )
  {
    case( AT_CMD_CFUN ):
    case( AT_CMD_CPIN ):
    case( AT_CMD_CIMI ):
    case( AT_CMD_NRG  ):
    case( AT_CMD_SIMRST):
      /* process event for +CFUN, +CPIN, +CIMI and for %NRG command */
      cmhsim_simactivated_start( );
      break;

    case( AT_CMD_CLCK ):
      /* process event for +CLCK command */
      cmhsim_simactivated_clck( );
      break;

    case( AT_CMD_NONE ):
      /* process event spontaneous insertion */
      if (simShrdPrm.rslt EQ SIM_NO_ERROR)
      {
        ; /* do nothing right now since the %SIMINS: -1 must be
           syncronized with SIM_MMI_INSERT_IND which will come later! */
      }
      else
      {
        for( idx = CMD_SRC_LCL; idx < CMD_SRC_MAX; idx++ )
        {
          R_AT( RAT_SIMINS, idx )(cmhSIM_GetCmeFromSim (simShrdPrm.rslt));
        }
      }
      break;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_SIMInserted           |
+-------------------------------------------------------------------+

  PURPOSE : SIM inserted

*/

GLOBAL void cmhSIM_SIMInserted ( void )
{
  USHORT cmdBuf;                 /* buffers current command */
  CHAR  imsiBuf[MAX_IMSI_LEN+1];  /* buffer IMSI representation +1 for '\0'*/
  T_ACI_CME_ERR err_code = CME_ERR_NotPresent; /* code holding the correct error code calculated */
  #ifdef SIM_PERS
  T_ACI_CPIN_RSLT code = CPIN_RSLT_NotPresent;
  #endif
  BOOL return_rat_ok = 1;  /* return ok? */

  TRACE_FUNCTION ("cmhSIM_SIMInserted()");

  /* Check if the SIM is functional and the IMSI value is valid*/
  if ( simShrdPrm.crdFun       EQ SIM_NO_OPERATION OR
       simShrdPrm.imsi.c_field EQ 0 )
  {
    simShrdPrm.SIMStat = SS_INV;
    err_code = CME_ERR_SimWrong;
  }
 cmdBuf = simEntStat.curCmd;
  switch( cmdBuf )
  {
    case( AT_CMD_CFUN ):
    case( AT_CMD_CPIN ):
    case( AT_CMD_PVRF ):
    case( AT_CMD_SIMRST):
    case( KSD_CMD_UBLK):
      /*
        *----------------------------------------------------------------
        * process event for +CFUN, +CPIN, %PVRF commands and for the 
          SIM reset condition
        *----------------------------------------------------------------
        */

      simEntStat.curCmd = AT_CMD_NONE;
#ifdef SIM_PERS
      if((aci_slock_sim_config.sim_type EQ SIM_TYPEAPPROVAL) AND AciSLockShrd.blocked)
      {
        simShrdPrm.SIMStat = SS_INV;
   err_code = CME_ERR_SimWrong;
      }
     if(cfg_data EQ NULL)
     {
       simShrdPrm.SIMStat = SS_INV;
       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_NoMEPD );
       err_code = CME_ERR_Unknown;
       aci_slock_send_RAT(cmdBuf,err_code); 
       simShrdPrm.PINQuery = 0;
       AciSLockShrd.cpin_query = SEND_CPIN_REQ_CODE_NONE; 
       return;
     }
#endif

      if( err_code EQ CME_ERR_SimWrong )
      {
        R_AT( RAT_CME, simEntStat.entOwn ) ((T_ACI_AT_CMD) cmdBuf, err_code );
        cmh_logRslt ( simEntStat.entOwn, RAT_CME, (T_ACI_AT_CMD)cmdBuf, -1, BS_SPEED_NotPresent, err_code );
        simShrdPrm.PINQuery = 0;
#ifdef SIM_PERS
        AciSLockShrd.cpin_query = SEND_CPIN_REQ_CODE_NONE;
#endif
        return;
      }

#ifdef SIM_PERS
    /* check for personalisation locking. If SIM was detected as not correct, do signal AT_CPIN */

      if ( AciSLockShrd.blocked)
      {
         return_rat_ok = 0;
         if(AciSLockShrd.cpin_query EQ SEND_CPIN_REQ_CODE_NONE)
         {
           /* @GBR: Alternativly CME_ERR_SimWrong might be returned, but this way is telling the MMI mor specific, what went wrong. */

           aci_set_cme_error_code_and_logRslt( cmdBuf );
         }
        else
        {  
          if(AciSLockShrd.cpin_query EQ SEND_CPIN_REQ_CODE_RAT )
          {
              aci_set_cpin_code(AciSLockShrd.current_lock,&code);
              R_AT( RAT_CPIN, simEntStat.entOwn )
                ( code );
          }
           AciSLockShrd.cpin_query  = SEND_CPIN_REQ_CODE_NONE;	
        }
      }

#endif
      if ( (cmdBuf EQ AT_CMD_CPIN) AND (simShrdPrm.PINQuery EQ 1) ) /* Case when PIN is disabled and CFUN=0 */
      {
        R_AT( RAT_CPIN, simEntStat.entOwn )
          ( CPIN_RSLT_SimReady );
        simShrdPrm.PINQuery = 0;
      }

#if defined (GPRS) AND defined (DTI)
      gprs_sim_inserted();
#endif  /* GPRS */

      if (return_rat_ok EQ 1) /* @gbr: only send ok, if everhing went okay. The +CFUN might not be ready here, so don't send something! */
      {

      R_AT( RAT_OK, simEntStat.entOwn ) ((T_ACI_AT_CMD) cmdBuf );
      cmh_logRslt ( simEntStat.entOwn, RAT_OK,(T_ACI_AT_CMD) cmdBuf, -1, BS_SPEED_NotPresent, CME_ERR_NotPresent );
#ifdef SIM_PERS
      AciSLockShrd.cpin_query  = SEND_CPIN_REQ_CODE_NONE;
#endif
     }
      break;

    case( AT_CMD_CIMI ):
   /*
    *----------------------------------------------------------------
    * process event for +CIMI command
    *----------------------------------------------------------------
    */
      

      if( err_code EQ CME_ERR_SimWrong )
      {
        R_AT( RAT_CME, simEntStat.entOwn ) ( AT_CMD_CIMI, err_code );
        cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CIMI, -1, BS_SPEED_NotPresent, err_code );
        return;
      }

      R_AT( RAT_CIMI, simEntStat.entOwn )
          ( psaSIM_cnvrtIMSI2ASCII( imsiBuf ));

      simEntStat.curCmd = AT_CMD_NONE;

      R_AT( RAT_OK, simEntStat.entOwn )
        ( AT_CMD_CIMI );
      break;

    case( AT_CMD_NRG ):
   /*
    *----------------------------------------------------------------
    * process event for %NRG
    *----------------------------------------------------------------
    */
      if( err_code EQ CME_ERR_SimWrong )
      {
        simEntStat.curCmd = AT_CMD_NONE;
        mmEntStat.curCmd  = AT_CMD_NONE;
        R_AT( RAT_CME, simEntStat.entOwn ) ( (T_ACI_AT_CMD)cmdBuf, err_code );
        cmh_logRslt ( simEntStat.entOwn, RAT_CME, (T_ACI_AT_CMD)cmdBuf, -1, BS_SPEED_NotPresent, err_code );
        return;
      }

      switch( cmhPrm[simShrdPrm.owner].mmCmdPrm.NRGregMode )
      {
        case( NRG_RGMD_Auto ):

          mmShrdPrm.regMode = MODE_AUTO;

          simEntStat.curCmd = AT_CMD_NONE;
          mmEntStat.curCmd  = AT_CMD_NRG;
          mmShrdPrm.owner = simShrdPrm.owner;
          mmEntStat.entOwn  = (T_ACI_CMD_SRC)simShrdPrm.owner;

#if defined (GPRS) AND defined (DTI)
          (void)psaG_MM_CMD_REG ();  /* register to network */
#else
          (void)psaMM_Registrate (); /* register to network */
#endif

          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Search);
          break;

        case( NRG_RGMD_Manual ):

          mmShrdPrm.regMode = MODE_MAN;

          simEntStat.curCmd = AT_CMD_NONE;
          mmEntStat.curCmd  = AT_CMD_NRG;
          mmShrdPrm.owner = simShrdPrm.owner;
          mmEntStat.entOwn  = (T_ACI_CMD_SRC) simShrdPrm.owner;

#if defined (GPRS) && defined (DTI) 
          psaG_MM_CMD_NET_SEL ( ); /* register to network */
#else
          psaMM_NetSel (); /* register to network */
#endif

          cmhMM_Ntfy_NtwRegistrationStatus(CREG_STAT_Search);
          break;
      }
      break;

    case( AT_CMD_NONE ):
      {
        T_ACI_CMD_SRC idx;
//TISH, patch for ASTec31853
//start
/*modified for Roaming issue*/
		TRACE_EVENT("reset mm reg stat");
    	mmShrdPrm.regStat = NO_VLD_RS;
//end		
        /* process event spontaneous insertion */
        for( idx = CMD_SRC_LCL; idx < CMD_SRC_MAX; idx++ )
        {
          R_AT( RAT_SIMINS, idx )( err_code );
        }
      }
      break;

  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_SIMRemoved            |
+-------------------------------------------------------------------+

  PURPOSE : SIM removed

*/

GLOBAL void cmhSIM_SIMRemoved ( void )
{
  T_ACI_AT_CMD cmdBuf;             /* buffers command */
  T_ACI_CMD_SRC idx;
  T_ACI_CME_ERR cme_error;  /* CME error code */
  T_ACI_SIMREM_TYPE srt;    /* type of SIM remove */

  TRACE_FUNCTION ("cmhSIM_SIMRemoved()");

  if (simEntStat.curCmd NEQ AT_CMD_NONE)
  {
    cmdBuf = simEntStat.curCmd;
    simEntStat.curCmd = AT_CMD_NONE;

    if (simShrdPrm.rslt EQ SIM_NO_ERROR)
      cme_error = CME_ERR_SimBusy;
    else
      cme_error = cmhSIM_GetCmeFromSim (simShrdPrm.rslt);

    R_AT( RAT_CME, simEntStat.entOwn )
          ( cmdBuf, cme_error );
    cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                  -1, BS_SPEED_NotPresent, cme_error );
  }
  EfPLMNselStat = EF_STAT_UNKNWN;
  /*
   *----------------------------------------------------------------
   * send unsolicited result
   *----------------------------------------------------------------
   */
  TRACE_EVENT_P1("Result of SIM remove indication: %x", simShrdPrm.rslt);
  switch (simShrdPrm.rslt)
  {
    case SIM_NO_ERROR:
      /* In this case the AT command state is set to SIM RESET */
      /* NO, don't do this!
         This line would prevent a %SIMIND: 11 and instead leads to
         "+CME ERROR: SIM PIN required" without any command context which is wrong */
      /* simEntStat.curCmd = AT_CMD_SIMRST; */
      srt = SIMREM_RESET;
      break;
    case SIM_CAUSE_DRV_TEMPFAIL:
      srt = SIMREM_RETRY;
      break;
    default:
      srt = SIMREM_FAILURE;
      break;
  }

  for( idx = CMD_SRC_LCL; idx < CMD_SRC_MAX; idx++ )
  {
    R_AT( RAT_SIMREM, idx )(srt);
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_PINVerified           |
+-------------------------------------------------------------------+

  PURPOSE : SIM verified

*/
LOCAL void pin_verified_clck (USHORT sim_result)
{
  TRACE_FUNCTION ("pin_verified_clck()");

  switch(sim_result)
  {
    case( SIM_NO_ERROR ):
      /* now do it ! */

      /* Check if we want to do FDN Lock or ALS Lock */
      switch (simShrdPrm.setPrm[simShrdPrm.owner].actProc)
      {
        case SIM_FDN_ENABLE:
        case SIM_FDN_DISABLE:
          /* FDN Lock */
          if( psaSIM_ActivateSIM() < 0 )   /* activate SIM card */
          {
            simEntStat.curCmd = AT_CMD_NONE;

            R_AT( RAT_CME, simEntStat.entOwn )
                  ( AT_CMD_CLCK, CME_ERR_Unknown );
            cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CLCK,
                          -1, BS_SPEED_NotPresent, CME_ERR_Unknown );
          }
          break;

        case SIM_ALS_LOCK:
        case SIM_ALS_UNLOCK:
          /* ALS Lock to PIN2 */
          if (simShrdPrm.setPrm[simShrdPrm.owner].actProc EQ SIM_ALS_LOCK)
          {
            ALSlock = cmhPrm[simShrdPrm.owner].ccCmdPrm.ALSmode;
            /* pull all sources to the current ALSmode, otherwise a lock won't make sense */
            {
              int i;
              for (i=0; i<OWN_SRC_MAX; i++)
                cmhPrm[i].ccCmdPrm.ALSmode = ALSlock;
                /* and lock them all */
            }
  #ifndef _SIMULATION_
            /* write Lock to FFS */
            /* Implements Measure#32: Row 1071 */
            FFS_fwrite(gsm_com_alslock_path, &ALSlock, sizeof(ALSlock));
  #endif
          }
          else
          /* unlock ALS */
          {
            ALSlock = ALS_MOD_NOTPRESENT;
  #ifndef _SIMULATION_
            /* remove lock from FFS */
            /* Implements Measure#32: Row 1071 */
            FFS_remove(gsm_com_alslock_path);
  #endif
          }

          simEntStat.curCmd = AT_CMD_NONE;

          R_AT( RAT_OK, simEntStat.entOwn )
            ( AT_CMD_CLCK );
          cmh_logRslt ( simEntStat.entOwn, RAT_OK, AT_CMD_CLCK, -1, BS_SPEED_NotPresent,CME_ERR_NotPresent);
          break;

      }
      break; /* SIM_NO_ERROR */

    case( SIM_CAUSE_PIN1_EXPECT ):
    case( SIM_CAUSE_PIN2_EXPECT ):
    case( SIM_CAUSE_PIN1_BLOCKED ):
    case( SIM_CAUSE_PUK1_EXPECT ):
    case( SIM_CAUSE_PIN2_BLOCKED ):
    case( SIM_CAUSE_PUK2_EXPECT ):
      simEntStat.curCmd = AT_CMD_NONE;

      R_AT( RAT_CME, simEntStat.entOwn )
            ( AT_CMD_CLCK, cmhSIM_GetCmeFromSim ( sim_result ) /*CME_ERR_WrongPasswd*/ );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CLCK,
                    -1,BS_SPEED_NotPresent, CME_ERR_WrongPasswd );
      break;

    default:
      simEntStat.curCmd = AT_CMD_NONE;
      R_AT( RAT_CME, simEntStat.entOwn )
            ( AT_CMD_CLCK, CME_ERR_SimFail );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CLCK,
                    -1, BS_SPEED_NotPresent, CME_ERR_SimFail );
      break;
  }
}

GLOBAL void cmhSIM_PINVerified ( void )
{
  T_ACI_AT_CMD cmdBuf;         /* buffers command */
  T_PHB_CMD_PRM * pPHBCmdPrm; /* points to PHB command parameters */

  TRACE_FUNCTION ("cmhSIM_PINVerified()");

  pPHBCmdPrm = &cmhPrm[simShrdPrm.owner].phbCmdPrm;

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( simEntStat.curCmd )
  {
    case( AT_CMD_CLCK ):
     /* process event for +CLCK command */
      pin_verified_clck( simShrdPrm.rslt );
      return;

    case( AT_CMD_CPIN ):
    case( AT_CMD_PVRF ):
     /*
      *----------------------------------------------------------------
      * process event for +CPIN and %PVRF command
      *----------------------------------------------------------------
      */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):

          /* if verified PIN was PIN 2 or PIN 1 was already entered */
          if( simShrdPrm.setPrm[simEntStat.entOwn].PINType EQ
              PHASE_2_PIN_2 OR
              simShrdPrm.crdPhs NEQ 0xFF )
          {
            cmdBuf = simEntStat.curCmd;
            simEntStat.curCmd = AT_CMD_NONE;

            R_AT( RAT_OK, simEntStat.entOwn )
            ( cmdBuf );
            cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, BS_SPEED_NotPresent,CME_ERR_NotPresent);
          }
          /* otherwise wait for SIM insert indication to complete command  */
          break;

        case( SIM_CAUSE_PIN1_EXPECT ):
        case( SIM_CAUSE_PIN2_EXPECT ):
        case( SIM_CAUSE_PUK1_EXPECT ):
        case( SIM_CAUSE_PUK2_EXPECT ): 
          cmdBuf = simEntStat.curCmd;
          simEntStat.curCmd = AT_CMD_NONE;

          R_AT( RAT_CME, simEntStat.entOwn )
                ( cmdBuf, CME_ERR_WrongPasswd );
          cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                        -1, BS_SPEED_NotPresent, CME_ERR_WrongPasswd );
          break;
        case( SIM_CAUSE_PIN1_BLOCKED):       
          cmdBuf = simEntStat.curCmd;
          simEntStat.curCmd = AT_CMD_NONE;

          R_AT( RAT_CME, simEntStat.entOwn )
                ( cmdBuf, CME_ERR_SimPukReq );
          cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                        -1, BS_SPEED_NotPresent, CME_ERR_SimPukReq );
          break;
        case( SIM_CAUSE_PIN2_BLOCKED):
          cmdBuf = simEntStat.curCmd;
          simEntStat.curCmd = AT_CMD_NONE;

          R_AT( RAT_CME, simEntStat.entOwn )
                ( cmdBuf, CME_ERR_SimPuk2Req );
          cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                        -1,BS_SPEED_NotPresent, CME_ERR_SimPuk2Req );
          break;
        default:
          cmdBuf = simEntStat.curCmd;
          simEntStat.curCmd = AT_CMD_NONE;
          R_AT( RAT_CME, simEntStat.entOwn )
                ( cmdBuf, CME_ERR_SimFail );
          break;
      }
      break;

      /* Implements Measure 106 */
    case( AT_CMD_CAMM ):
    case( AT_CMD_CPUC ):
    case( AT_CMD_CACM ):
      cmhSIM_ProcessEvents( simEntStat.curCmd );
      break;
     /*----------------------------------------------------------* 
      * The below code is for CPBW SIM verification response     *
      *----------------------------------------------------------*/

    case( AT_CMD_CPBS ):
     /*
      *----------------------------------------------------------------
      * process event for +CPBW command
      *----------------------------------------------------------------
      */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):

        /*-----------------------------------------------* 
         * if verified PIN was PIN 2 was already entered *
         *-----------------------------------------------*/

         cmdBuf = simEntStat.curCmd;
         simEntStat.curCmd = AT_CMD_NONE;

         pPHBCmdPrm->cmhStor = (T_ACI_PB_STOR)pPHBCmdPrm->temp_cmhStor;
         pPHBCmdPrm->phbStor = pPHBCmdPrm->temp_phbStor;

         R_AT( RAT_OK, simEntStat.entOwn )
              ( cmdBuf );

         cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );         

        /*---------------------------------------------------------------*
         * otherwise wait for SIM insert indication to complete command  *
         *---------------------------------------------------------------*/

         break;

        case( SIM_CAUSE_PUK2_EXPECT ):
        case( SIM_CAUSE_PIN2_BLOCKED):
        case( SIM_CAUSE_PIN2_EXPECT ):
          
         cmdBuf = simEntStat.curCmd;
         simEntStat.curCmd = AT_CMD_NONE;

         R_AT( RAT_CME, simEntStat.entOwn )
                ( cmdBuf, CME_ERR_WrongPasswd );
         cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                       -1, BS_SPEED_NotPresent, CME_ERR_WrongPasswd );
         break;

        default:
         cmdBuf = simEntStat.curCmd;
         simEntStat.curCmd = AT_CMD_NONE;
         R_AT( RAT_CME, simEntStat.entOwn )
               ( cmdBuf, CME_ERR_SimFail );
         break;
      }
      break;

    default:

      simEntStat.curCmd = AT_CMD_NONE;
      R_AT( RAT_CME, simEntStat.entOwn )
        ( AT_CMD_CPIN, CME_ERR_Unknown );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CPIN,
                    -1,BS_SPEED_NotPresent, CME_ERR_Unknown );
     break;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_PINChanged            |
+-------------------------------------------------------------------+

  PURPOSE : SIM changed

*/

GLOBAL void cmhSIM_PINChanged ( void )
{
  T_ACI_CME_ERR err;
  USHORT         cmdBuf = simEntStat.curCmd;

  TRACE_FUNCTION ("cmhSIM_PINChanged()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( cmdBuf )
  {
    case( AT_CMD_CPWD ):
    /*lint -e{408} */ 
    case( KSD_CMD_PWD ):  /* KSD_CMD_* extends AT_CMD_* */
     /*
      *----------------------------------------------------------------
      * process event for +CPWD and KSD PWD command
      *----------------------------------------------------------------
      */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):

          simEntStat.curCmd = AT_CMD_NONE;

          R_AT( RAT_OK, simEntStat.entOwn )
            ((T_ACI_AT_CMD) cmdBuf );
          cmh_logRslt ( simEntStat.entOwn, RAT_OK, (T_ACI_AT_CMD)cmdBuf, -1, BS_SPEED_NotPresent, CME_ERR_NotPresent );
          return;

/* why not use a meaningful CME error code?
        case( SIM_CAUSE_PUK1_EXPECT ):
        case( SIM_CAUSE_PUK2_EXPECT ): */
        case( SIM_CAUSE_PIN1_EXPECT ):
        case( SIM_CAUSE_PIN2_EXPECT ):
          err = CME_ERR_WrongPasswd;
          break;

        default:
          err = cmhSIM_GetCmeFromSim ( simShrdPrm.rslt );
          break;
      }

      simEntStat.curCmd = AT_CMD_NONE;

      R_AT( RAT_CME, simEntStat.entOwn )
            ( (T_ACI_AT_CMD)cmdBuf, err );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME, (T_ACI_AT_CMD)cmdBuf,
                    -1, BS_SPEED_NotPresent, err );
      break;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_CardUnblocked         |
+-------------------------------------------------------------------+

  PURPOSE : Card unblocked

*/

GLOBAL void cmhSIM_CardUnblocked ( void )
{
  USHORT cmdBuf =simEntStat.curCmd ;
  T_ACI_CME_ERR err;

  TRACE_FUNCTION ("cmhSIM_CardUnblocked()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( cmdBuf )
  {
    case( AT_CMD_CPIN ):
    case( AT_CMD_PVRF ):
    /*lint -e{408} */ 
    case( KSD_CMD_UBLK ):
     /*
      *----------------------------------------------------------------
      * process event for +CPIN, %PVRF and KSD UBLK command
      *----------------------------------------------------------------
      */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):

          if(simShrdPrm.crdPhs NEQ 0xFF)/* If SIM insert indication is already received*/
          {
            simEntStat.curCmd = AT_CMD_NONE;

            R_AT( RAT_OK, simEntStat.entOwn )
              ( (T_ACI_AT_CMD)cmdBuf );
            cmh_logRslt ( simEntStat.entOwn, RAT_OK,(T_ACI_AT_CMD) cmdBuf, -1, BS_SPEED_NotPresent, CME_ERR_NotPresent );
          }/* else wait till SIM insert indication is received*/
          return;

/* why not use a meaningful CME error code?
        case( SIM_CAUSE_PUK1_EXPECT ):
        case( SIM_CAUSE_PUK2_EXPECT ): */
        case( SIM_CAUSE_PIN1_EXPECT ):
        case( SIM_CAUSE_PIN2_EXPECT ):
          err = CME_ERR_WrongPasswd;
          break;

        default:
          err = cmhSIM_GetCmeFromSim ( simShrdPrm.rslt );
          break;
      }

       simEntStat.curCmd = AT_CMD_NONE;

      R_AT( RAT_CME, simEntStat.entOwn )
            ( (T_ACI_AT_CMD)cmdBuf, err );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME,(T_ACI_AT_CMD) cmdBuf,
                    -1, BS_SPEED_NotPresent, err );
      break;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_SIMResponseData       |
+-------------------------------------------------------------------+

  PURPOSE : SIM response data

*/

GLOBAL void cmhSIM_SIMResponseData( T_SIM_TRNS_RSP_PRM* rsp )
{
  T_ACI_AT_CMD cmdBuf;            /* buffers command       */
  T_ACI_CMD_SRC ownBuf;    /* buffers current owner */
  UBYTE *rspData;

  TRACE_FUNCTION ("cmhSIM_SIMResponseData()");

  cmdBuf = simEntStat.curCmd;
  simEntStat.curCmd = AT_CMD_NONE;

  ownBuf = simEntStat.entOwn;
  simShrdPrm.owner = (T_OWN)CMD_SRC_NONE;
  simEntStat.entOwn = CMD_SRC_NONE;

  /*
   *-------------------------------------------------------------------
   * check for command context
   *-------------------------------------------------------------------
   */
  switch( cmdBuf )
  {
    case( AT_CMD_CRSM ):
      if (simShrdPrm.rslt NEQ SIM_NO_ERROR       AND 
          GET_CAUSE_DEFBY(simShrdPrm.rslt) EQ DEFBY_CONDAT ) 
      {
     /*
      *----------------------------------------------------------------
      * error event for +CRSM
      *----------------------------------------------------------------
      */
        R_AT( RAT_CME, ownBuf )
          (
            cmdBuf,
            cmhSIM_GetCmeFromSim ( simShrdPrm.rslt )
          );
      }
      else
      {
     /*
      *----------------------------------------------------------------
      * process event for +CRSM
      *----------------------------------------------------------------
      */
        R_AT( RAT_CRSM, ownBuf )
          ( rsp->sw1, rsp->sw2, rsp->rspLen, ((rsp->rspLen)?rsp->rsp:NULL));

        R_AT( RAT_OK, ownBuf )
          ( cmdBuf );
      }
      break;

    case( AT_CMD_CSIM ):
     /*
      *----------------------------------------------------------------
      * error event for +CSIM
      *----------------------------------------------------------------
      */
      if (simShrdPrm.rslt NEQ SIM_NO_ERROR) 
      {
        R_AT( RAT_CME, ownBuf )
          (
            cmdBuf,
            cmhSIM_GetCmeFromSim ( simShrdPrm.rslt )
          );

        return;
      }
     /*
      *----------------------------------------------------------------
      * process event for +CSIM
      *----------------------------------------------------------------
      */
      ACI_MALLOC(rspData, MAX_SIM_CMD+2);  /* alloc 2 byte more for sw1 and sw2 */
      memcpy (rspData, rsp->rsp, rsp->rspLen);
      rspData[rsp->rspLen++] = rsp->sw1;
      rspData[rsp->rspLen++] = rsp->sw2;

      R_AT( RAT_CSIM, ownBuf )
        ( rsp->rspLen, rspData);

      ACI_MFREE(rspData);

      R_AT( RAT_OK, ownBuf )
        ( cmdBuf );
      break;
    
    default:
      TRACE_EVENT("wrong command context (+CRSM or +CSIM expected)");
      break;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_CnfMsisdn         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF MSISDN from SIM.
*/
GLOBAL void cmhSIM_CnfMsisdn ( SHORT table_id )
{
  T_SIM_CMD_PRM* pSIMCmdPrm; /* points to SIM command parameters  */
  T_ACI_AT_CMD   cmdBuf;     /* buffers current command           */
  T_ACI_CMD_SRC  ownBuf;     /* buffers current owner             */

  UBYTE*  ptr;               /* pointer to decoded data           */
  UBYTE   alphaLen;          /* max. length of alpha identifier   */
  UBYTE*  pExchData;         /* points to exchange data buffer    */
  UBYTE   dataLen;           /* holds length of data */

  TRACE_FUNCTION ("cmhSIM_CnfMsisdn()");

  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  pExchData  = simShrdPrm.atb[table_id].exchData;
  dataLen    = simShrdPrm.atb[table_id].dataLen;


  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( pExchData EQ NULL                   OR
           dataLen   <  ACI_MIN_SIZE_EF_MSISDN    )
      {
        /* Implements Measure 7, 17, 24, 35 */
        cmhSIM_SndError( ownBuf, cmdBuf, CME_ERR_Unknown );
      }
      else
      {
        ptr      = pExchData;
        alphaLen = dataLen - ACI_MIN_SIZE_EF_MSISDN;

        /*
         *-----------------------------------------------------------
         * process parameter <lenEfMsisdn>
         *-----------------------------------------------------------
         */
        CNUMLenEfMsisdn = dataLen;

        /*
         *-----------------------------------------------------------
         * process parameter <cnumMaxRec>
         *-----------------------------------------------------------
         */
        if ( pSIMCmdPrm -> CNUMActRec EQ 1 )
          CNUMMaxRec = simShrdPrm.atb[table_id].recMax;

        /*
         *-----------------------------------------------------------
         * process parameter <alpha>
         *-----------------------------------------------------------
         */
        cmhPHB_getTagNt ( ptr,
                          alphaLen,
                          CNUMMsisdn[CNUMMsisdnIdx].alpha,
                          MAX_ALPHA_LEN );

        ptr += alphaLen;

        /*
         *-----------------------------------------------------------
         * process parameter <number>
         *-----------------------------------------------------------
         */
        cmhPHB_getAdrStr ( CNUMMsisdn[CNUMMsisdnIdx].number,
                           MAX_PHB_NUM_LEN - 1,
                           ptr + 2,
                           *ptr );

        /*
         *-----------------------------------------------------------
         * validate entry of MSISDN list
         *-----------------------------------------------------------
         */
        /* VO patch 14.03.01
         * move validate entry to after decoding alpha and number
         * and set the vldFlag only when the alpha or the number exists. */
        if ( strlen(CNUMMsisdn[CNUMMsisdnIdx].number) OR
             strlen(CNUMMsisdn[CNUMMsisdnIdx].alpha)     )
        {
          CNUMMsisdn[CNUMMsisdnIdx].vldFlag = TRUE;
          pSIMCmdPrm -> CNUMOutput++;
        }

        /*
         *-----------------------------------------------------------
         * process parameter <type>
         *-----------------------------------------------------------
         */
        cmhPHB_toaDmrg ( *( ptr + 1 ),
                         &CNUMMsisdn[CNUMMsisdnIdx].type );

        ptr += 12;

        /*
         *-----------------------------------------------------------
         * invalidate parameter <speed>, <service>, <itc>
         *-----------------------------------------------------------
         */
        CNUMMsisdn[CNUMMsisdnIdx].speed   = BS_SPEED_NotPresent;
        CNUMMsisdn[CNUMMsisdnIdx].service = CNUM_SERV_NotPresent;
        CNUMMsisdn[CNUMMsisdnIdx].itc     = CNUM_ITC_NotPresent;

        if ( *ptr NEQ 0xFF )
        {
          /*
           *---------------------------------------------------------
           * bearer capability EF present
           *---------------------------------------------------------
           */
          if ( cmhSIM_ReqCcp ( ownBuf, *ptr++ ) NEQ AT_EXCT )
          {
            /* Implements Measure 7, 17, 24, 35 */
            cmhSIM_SndError( ownBuf, cmdBuf, CME_ERR_Unknown );
          }
        }
        else
        {
          /* Implements Measure 200 */

          if ( CNUMMsisdn[CNUMMsisdnIdx].vldFlag EQ FALSE )
          {
            CNUMMsisdnIdx--;
          }

          cmhSIM_Compare_CNUMMsisdnIdx();
        }
      }

      break;
    }

    default:
    {
      /* Implements Measure 7, 17, 24, 35 */
      cmhSIM_SndError( ownBuf, cmdBuf,
                   cmhSIM_GetCmeFromSim (simShrdPrm.atb[table_id].errCode) );
      break;
    }

  }

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR           |
| STATE   : code                        ROUTINE : cmhSIM_CnfCcp      |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF CCP from SIM.
*/
GLOBAL void cmhSIM_CnfCcp ( SHORT table_id )
{
  T_ACI_AT_CMD   cmdBuf;      /* buffers current command          */
  T_ACI_CMD_SRC  ownBuf;      /* buffers current owner            */

  T_U_CALL_CONF* callCnf;     /* call confirm message             */
  T_M_CC_bearer_cap*  bearCap;     /* bearer capability                */
  UBYTE*         pExchData;   /* points to exchange data buffer   */
  UBYTE          dataLen;     /* holds length of data */

  TRACE_FUNCTION ("cmhSIM_CnfCcp()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  dataLen    = simShrdPrm.atb[table_id].dataLen;
  pExchData  = simShrdPrm.atb[table_id].exchData;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( pExchData EQ   NULL            OR
           dataLen   NEQ  ACI_SIZE_EF_CCP    )
      {
        /* Implements Measure 7, 17, 24, 35 */
        cmhSIM_SndError( ownBuf, cmdBuf, CME_ERR_Unknown );
      }
      else
      {
        /*
         *-----------------------------------------------------------
         * extracting the relevant data from bearer capability IE
         *-----------------------------------------------------------
         */
        UBYTE bearCapLen = pExchData[0];

        if (bearCapLen <= 13 )   /* do not decode empty or invalid entries,
                                    see 11.11/10.5.4.1 max 14 bytes */
        {
          /*lint -e415 -e416 -e669 (Waring: creation of out of bound ptr or data overrun)*/
          PALLOC_MSG ( msg, MMCM_DATA_REQ, U_CALL_CONF);

          msg -> sdu.l_buf  = bearCapLen * 0x08;
          msg -> sdu.o_buf  = 0x08;
          msg -> sdu.buf[0] = 0x83;
          msg -> sdu.buf[1] = U_CALL_CONF;

          memcpy ( &msg -> sdu.buf[2],
                   pExchData,
                   bearCapLen+1);
          /*lint +e415 +e416 +e669 (Waring: creation of out of bound ptr or data overrun)*/
          /*
           *-----------------------------------------------------------
           * use of CCD for decoding of bearer capability
           *-----------------------------------------------------------
           */
          CCD_START;

          memset (_decodedMsg, 0, sizeof (_decodedMsg));

          if ( ccd_decodeMsg ( CCDENT_CC,
                               UPLINK,
                               (T_MSGBUF *) &msg->sdu,
                               (UBYTE    *) _decodedMsg,
                               NOT_PRESENT_8BIT) EQ ccdOK
               AND

               _decodedMsg[0] EQ U_CALL_CONF )
          {
            callCnf = ( T_U_CALL_CONF * )&_decodedMsg[0];

            if ( callCnf -> v_bearer_cap )
            {
              bearCap = &callCnf -> bearer_cap;

              /*
               *-------------------------------------------------------
               * process parameter <speed> of MSISDN
               *-------------------------------------------------------
               */
              if ( bearCap -> v_user_rate )
              {
                CNUMMsisdn[CNUMMsisdnIdx].speed =
                           cmhSIM_GetUserRate ( bearCap -> user_rate );
              }

              /*
               *-------------------------------------------------------
               * process parameter <itc> and <service> of MSISDN
               *-------------------------------------------------------
               */
              if ( bearCap -> v_trans_cap )
              {
                CNUMMsisdn[CNUMMsisdnIdx].itc =
                                cmhSIM_GetItc ( bearCap -> trans_cap );
              }

              if ( bearCap -> v_user_inf_l2_prot                AND
                   bearCap -> user_inf_l2_prot   EQ M_CC_L2_X25      AND
                   bearCap -> v_sync_async                      AND
                   bearCap -> sync_async         EQ M_CC_SYNCHRONOUS     )
              {
                CNUMMsisdn[CNUMMsisdnIdx].service =
                                                 CNUM_SERV_PacketSynch;
              }
              else if
                 (   bearCap -> v_sig_access_prot
                     AND
                   ( bearCap -> sig_access_prot EQ M_CC_SIAP_X28_INDIV_NUI OR
                     bearCap -> sig_access_prot EQ M_CC_SIAP_X28_UNIV_NUI  OR
                     bearCap -> sig_access_prot EQ M_CC_SIAP_X28_NON_DEDIC
                   )

                     AND
                     bearCap -> v_sync_async
                     AND
                     bearCap -> sync_async        EQ M_CC_ASYNCHRONOUS
                 )
              {
                CNUMMsisdn[CNUMMsisdnIdx].service =
                                                   CNUM_SERV_PadAsynch;
              }
              else if ( bearCap -> v_sync_async )
              {
                CNUMMsisdn[CNUMMsisdnIdx].service =
                        cmhSIM_GetSrvFromSync ( bearCap -> sync_async );

              }
              else if ( bearCap -> v_trans_cap )
              {
                CNUMMsisdn[CNUMMsisdnIdx].service =
                         cmhSIM_GetSrvFromItc ( bearCap -> trans_cap );
              }
            }
          }
          CCD_END;

          PFREE ( msg );
        }

        /*
         *-----------------------------------------------------------
         * tmpActRec is used to prevent conflicts with global
         * variable pSIMCmdPrm -> CNUMActRec
         *-----------------------------------------------------------
         */
        /* Implements Measure 200 */
        cmhSIM_Compare_CNUMMsisdnIdx();
      }

      break;
    }

    default:
    {
      /* Implements Measure 7, 17, 24, 35 */
      cmhSIM_SndError( ownBuf, cmdBuf, 
                       cmhSIM_GetCmeFromSim(simShrdPrm.atb[table_id].errCode));
      break;
    }

  }

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR           |
| STATE   : code                        ROUTINE : cmhSIM_RdCnfPlmnSel|
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF PLMN SEL from SIM.
*/
GLOBAL void cmhSIM_RdCnfPlmnSel ( SHORT table_id )
{
  T_SIM_CMD_PRM * pSIMCmdPrm; /* points to SIM command parameters  */
  T_ACI_AT_CMD    cmdBuf;     /* buffers current command           */
  T_ACI_CMD_SRC   ownBuf;     /* buffers current owner             */
  T_ACI_CPOL_LST  CPOLPlmnSelLst;   /* PLMN SEL list               */
  T_ACI_RETURN    ret;
  SHORT           lastIdx;    /* holds last index */
  SHORT           usdNtry;    /* holds number of used entries */

  TRACE_FUNCTION ("cmhSIM_RdCnfPlmnSel()");

  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;


  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( simShrdPrm.atb[table_id].exchData EQ NULL  OR
           simShrdPrm.atb[table_id].dataLen <  ACI_MIN_SIZE_EF_PLMN_SEL)
      {
        pSIMCmdPrm->CPOLact = CPOL_ACT_None;
        /* Implements Measure 7, 17, 24, 35 */
        cmhSIM_SndError( ownBuf, cmdBuf, CME_ERR_Unknown );
        break;
      }

      EfPLMNselStat = EF_STAT_READ;
      CPOLSimEfDataLen = simShrdPrm.atb[table_id].dataLen;

      if( pSIMCmdPrm->CPOLmode EQ CPOL_MOD_CompactList )
      {
        cmhSIM_CmpctPlmnSel( simShrdPrm.atb[table_id].dataLen,
                             simShrdPrm.atb[table_id].exchData );
      }

      /*
       *-----------------------------------------------------------
       * what is to do ?
       *-----------------------------------------------------------
       */
      switch( pSIMCmdPrm->CPOLact )
      {
        /*
         *-----------------------------------------------------------
         * read out PLMN SEL list
         *-----------------------------------------------------------
         */
        case( CPOL_ACT_Read ):

          /* fill in buffer */
          lastIdx = cmhSIM_FillPlmnSelList(pSIMCmdPrm->CPOLidx,
                                           pSIMCmdPrm->CPOLfrmt,
                                           &CPOLPlmnSelLst[0],
                                           simShrdPrm.atb[table_id].dataLen,
                                           (UBYTE *)simShrdPrm.atb[table_id].exchData);
          /* notify about PLMN SEL list */
          simEntStat.curCmd = AT_CMD_NONE;
          simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
          simEntStat.entOwn =  CMD_SRC_NONE;

          R_AT( RAT_CPOL, ownBuf ) ( ACI_NumParmNotPresent,
                                     lastIdx,
                                     &CPOLPlmnSelLst[0],
                                     ACI_NumParmNotPresent );

          R_AT( RAT_OK, ownBuf )( AT_CMD_CPOL );
          break;

        /*
         *-----------------------------------------------------------
         * write PLMN SEL list
         *-----------------------------------------------------------
         */
        case( CPOL_ACT_Write ):

          if( pSIMCmdPrm->CPOLidx EQ NOT_PRESENT_8BIT )

            ret = cmhSIM_FndEmptyPlmnSel( simEntStat.entOwn,
                                          pSIMCmdPrm->CPOLplmn );
          else

            ret = cmhSIM_UpdPlmnSel( simEntStat.entOwn,
                                     pSIMCmdPrm->CPOLidx,
                                     pSIMCmdPrm->CPOLplmn,
                                     pSIMCmdPrm->CPOLmode);
          if( ret EQ AT_FAIL )
          {
            pSIMCmdPrm->CPOLact = CPOL_ACT_None;
            /* Implements Measure 7, 17, 24, 35 */

            /* T_ACI_CME_ERR is used for TypeCast as the 
             * ACI_ERR_DESC_NR() will retrun ULONG and the function expects
             * T_ACI_CME_ERR and there will no major harm as well.
             */
            cmhSIM_SndError( simEntStat.entOwn, AT_CMD_CPOL,
                             (T_ACI_CME_ERR) ACI_ERR_DESC_NR( aciErrDesc ));
          }
          break;

        /*
         *-----------------------------------------------------------
         * delete PLMN SEL entry
         *-----------------------------------------------------------
         */
        case( CPOL_ACT_Delete ):

          if( pSIMCmdPrm->CPOLidx2 EQ NOT_PRESENT_8BIT )

            ret = cmhSIM_DelPlmnSel( simEntStat.entOwn,
                                     pSIMCmdPrm->CPOLidx,
                                     pSIMCmdPrm->CPOLmode );
          else

            ret = cmhSIM_ChgPlmnSel( simEntStat.entOwn,
                                     pSIMCmdPrm->CPOLidx,
                                     pSIMCmdPrm->CPOLidx2 );

          if( ret EQ AT_FAIL )
          {
            pSIMCmdPrm->CPOLact = CPOL_ACT_None;
            /* Implements Measure 7, 17, 24, 35 */

            /* T_ACI_CME_ERR is used for TypeCast as the ACI_ERR_DESC_NR() 
             * will retrun ULONG and the function expects T_ACI_CME_ERR 
             * and there will no major harm as well
             */
            cmhSIM_SndError( simEntStat.entOwn, AT_CMD_CPOL, 
                             (T_ACI_CME_ERR) ACI_ERR_DESC_NR( aciErrDesc ));
          }
          break;

        /*
         *-----------------------------------------------------------
         * test PLMN SEL entry number
         *-----------------------------------------------------------
         */
        case( CPOL_ACT_Test ):

          /* notify about PLMN SEL entry number */
          simEntStat.curCmd = AT_CMD_NONE;
          simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
          simEntStat.entOwn =  CMD_SRC_NONE;

          lastIdx = CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY;
          usdNtry = cmhSIM_UsdPlmnSelNtry( CPOLSimEfDataLen,
                                           (UBYTE *)simShrdPrm.atb[table_id].exchData );

          R_AT( RAT_CPOL, ownBuf ) ( ACI_NumParmNotPresent,
                                     lastIdx,
                                     NULL,
                                     usdNtry );

          R_AT( RAT_OK, ownBuf )( AT_CMD_CPOL );
          break;
      }
      break;
    }

    case ( SIM_CAUSE_UNKN_FILE_ID ):
      EfPLMNselStat = EF_STAT_NOT_AVAIL;
      /*lint -fallthrough*/
      /*lint -fallthrough*/
    default:
    {
      pSIMCmdPrm->CPOLact = CPOL_ACT_None;
      /* Implements Measure 7, 17, 24, 35 */
      cmhSIM_SndError( ownBuf, cmdBuf, 
                       cmhSIM_GetCmeFromSim(simShrdPrm.atb[table_id].errCode));
      break;
    }

  }

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR           |
| STATE   : code                        ROUTINE : cmhSIM_WrCnfPlmnSel|
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of writing
            EF PLMN SEL to SIM.
*/
GLOBAL void cmhSIM_WrCnfPlmnSel ( SHORT table_id )
{
  T_SIM_CMD_PRM * pSIMCmdPrm; /* points to SIM command parameters  */
  UBYTE ownBuf;

  TRACE_FUNCTION ("cmhSIM_WrCnfPlmnSel()");

  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  ownBuf = simEntStat.entOwn;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    /* successful PLMN SEL list update */
    case ( SIM_NO_ERROR ):
    {
      pSIMCmdPrm->CPOLact = CPOL_ACT_None;
      simEntStat.curCmd = AT_CMD_NONE;
      simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
      simEntStat.entOwn = CMD_SRC_NONE;

      R_AT( RAT_OK, (T_ACI_CMD_SRC)ownBuf )( AT_CMD_CPOL );
      break;
    }
    case SIM_CAUSE_ACCESS_PROHIBIT:
    {
      pSIMCmdPrm->CPOLact = CPOL_ACT_None;
      /* Implements Measure 7, 17, 24, 35 */
      cmhSIM_SndError((T_ACI_CMD_SRC)ownBuf, AT_CMD_CPOL, CME_ERR_OpNotAllow );
      break;
    }

    /* unsuccessful PLMN SEL list update */
    default:
    {
      pSIMCmdPrm->CPOLact = CPOL_ACT_None;
      /* Implements Measure 7, 17, 24, 35 */
      cmhSIM_SndError((T_ACI_CMD_SRC)ownBuf, AT_CMD_CPOL, 
                       cmhSIM_GetCmeFromSim(simShrdPrm.atb[table_id].errCode));
      break;
    }
  }

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR           |
| STATE   : code                        ROUTINE : cmhSIM_RdCnfLangELP|
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            from the SIM (EF ELP).
*/
GLOBAL void cmhSIM_RdCnfLangELP ( SHORT table_id )
{
  T_SIM_CMD_PRM *pSIMCmdPrm; /* points to SIM command parameters */
  T_PHB_CMD_PRM *pPHBCmdPrm; /* points to PHB command parameter  */

  T_ACI_AT_CMD  cmdBuf;     /* buffers current command           */
  T_ACI_CMD_SRC ownBuf;     /* buffers current owner             */
  CHAR          Clang_buffer[3]={0};/* Current language          */
  T_ACI_LAN_SUP clng;
  EF_CLNG       lng;
  BOOL          Suplng = FALSE;
  T_ACI_LAN_SUP LngPCMsupLst[MAX_LAN];
  SHORT         lastIdx;
  T_ACI_RETURN    ret ;

  TRACE_FUNCTION ("cmhSIM_RdCnfLangELP()");

  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  pPHBCmdPrm = &cmhPrm[ownBuf].phbCmdPrm;
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
  simEntStat.curCmd = AT_CMD_NONE;

  clng.str = Clang_buffer;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
     /*
      *-------------------------------------------------------------
      * check basic consistency of read data
      *-------------------------------------------------------------
      */
      if ( simShrdPrm.atb[table_id].exchData EQ NULL  OR
           simShrdPrm.atb[table_id].dataLen <  ACI_MIN_SIZE_EF_LAN)

      {
        pSIMCmdPrm->CLANact = CLAN_ACT_None;
        simShrdPrm.owner    = (T_OWN)CMD_SRC_NONE;
        simEntStat.entOwn   = CMD_SRC_NONE;

        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
        return;
      }

      memcpy(clng.str, (UBYTE *)simShrdPrm.atb[table_id].exchData, CLAN_CODE_LEN);
      ret=getSupLangFromPCM(&LngPCMsupLst[0], &lastIdx);
      if (ret EQ AT_FAIL)
      {
        return;
      }
      Suplng=checkSuppLang(&LngPCMsupLst[0],lastIdx, &clng);
      simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
      simEntStat.entOwn = CMD_SRC_NONE;

     /*
      *---------------------------------------------------------------------
      * check if the language,which was read from EF ELP is supported in PCM
      *---------------------------------------------------------------------
      */
      if(Suplng)
      {
        switch( pSIMCmdPrm->CLANact )
        {
          case( CLAN_ACT_Read ):
            R_AT( RAT_CLAN, ownBuf ) (&clng);
            R_AT( RAT_OK, ownBuf )( AT_CMD_CLAN );
            break;
          case( CLAN_ACT_Write ):
            memcpy(lng.data,clng.str ,CLAN_CODE_LEN);
            /* Implements Measure#32 Row 1072 */
            pcm_WriteFile (( UBYTE* )ef_clng_id,SIZE_EF_CLNG,( UBYTE*) &lng);

            if (pPHBCmdPrm->CLAEmode EQ CLAE_MOD_Enable)
              R_AT( RAT_CLAE, ownBuf ) (&clng);

          R_AT( RAT_OK, ownBuf )( AT_CMD_CLAN );
          break;
       }
      }
      else
     /*
      *-------------------------------------------------------------
      * read the EF LP if the language is not supported in PCM
      *-------------------------------------------------------------
      */
       /* Implements Measure 150 and 159 */
       cmhSIM_ReqLanguage_LP_or_ELP ( ownBuf, SIM_LP );
       break;

     /*
      *-------------------------------------------------------------
      * read the EF LP if the EF ELP not available
      *-------------------------------------------------------------
      */
    case ( SIM_CAUSE_UNKN_FILE_ID ):
       /* Implements Measure 150 and 159 */
       cmhSIM_ReqLanguage_LP_or_ELP ( ownBuf, SIM_LP );
      break;

    default:
      pSIMCmdPrm->CLANact = CLAN_ACT_None;
      simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
      simEntStat.entOwn = CMD_SRC_NONE;

      R_AT( RAT_CME, ownBuf) ( AT_CMD_CLAN, CME_ERR_Unknown );
      break;

  }

}


/*
+------------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR               |
| STATE   : code                        ROUTINE : cmhSIM_RdCnfLangPrfELP |
+------------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            from the SIM (EF ELP) for SAT feature LS.
*/
GLOBAL void cmhSIM_RdCnfLangPrfELP ( SHORT table_id )
{
  
  T_ACI_SAT_TERM_RESP resp_data;
  CHAR           Clang_buffer[3]={0};/* Current language          */
  T_ACI_LAN_SUP  clng;
  BOOL           Suplng = FALSE;
  T_ACI_LAN_SUP  LngPCMsupLst[MAX_LAN];
  SHORT          lastIdx;
  T_ACI_RETURN    ret ;
  

  TRACE_FUNCTION ("cmhSIM_RdCnfLangPrfELP()");
  
  psaSAT_InitTrmResp( &resp_data );
  
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;

  clng.str = Clang_buffer;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
     /*
      *-------------------------------------------------------------
      * check basic consistency of read data
      *-------------------------------------------------------------
      */
      if ( simShrdPrm.atb[table_id].exchData EQ NULL  OR
           simShrdPrm.atb[table_id].dataLen <  ACI_MIN_SIZE_EF_LAN)

      {
        psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
        return;
      }

      memcpy(clng.str, (UBYTE *)simShrdPrm.atb[table_id].exchData, CLAN_CODE_LEN);
      ret=getSupLangFromPCM(&LngPCMsupLst[0], &lastIdx);
      if (ret EQ AT_FAIL)
      {
        psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
        return;
      }
      
      Suplng=checkSuppLang(&LngPCMsupLst[0],lastIdx, &clng);

      
     /*
      *---------------------------------------------------------------------
      * check if the language,which was read from EF ELP is supported in PCM
      *---------------------------------------------------------------------
      */
      if(Suplng)
      {
        /* Send Terminal resp*/
        memcpy(&resp_data.lang, (UBYTE *)simShrdPrm.atb[table_id].exchData, CLAN_CODE_LEN);
        psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );

      }
      else
      {
        /*
        *-------------------------------------------------------------
        * read the EF LP if the language is not supported in PCM
        *-------------------------------------------------------------
        */
        /* Implements Measure 119 */
        if ( cmhSIM_ReqLanguagePrf_LP_or_ELP( SIM_LP, ACI_MAX_LAN_LP_NTRY,
                                              CLANSimEfDataLP,
                                              cmhSIM_RdCnfLangPrfLP ) EQ FALSE )
        {
          psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
        }
      }
      break;

     /*
      *-------------------------------------------------------------
      * read the EF LP if the EF ELP not available
      *-------------------------------------------------------------
      */
    case ( SIM_CAUSE_UNKN_FILE_ID ):
        /* Implements Measure 119 */
        if (cmhSIM_ReqLanguagePrf_LP_or_ELP ( SIM_LP, ACI_MAX_LAN_LP_NTRY,
                                              CLANSimEfDataLP,
                                              cmhSIM_RdCnfLangPrfLP ) EQ FALSE )
      {
        psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
      }
      break;

    default:
      psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
      break;

  }
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR           |
| STATE   : code                        ROUTINE : cmhSIM_RdCnfLangLP |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF LP from SIM.
*/
GLOBAL void cmhSIM_RdCnfLangLP ( SHORT table_id )
{
  T_SIM_CMD_PRM * pSIMCmdPrm; /* points to SIM command parameters  */
  T_PHB_CMD_PRM * pPHBCmdPrm; /* points to PHB command parameter */
  T_ACI_AT_CMD    cmdBuf;     /* buffers current command           */
  T_ACI_CMD_SRC   ownBuf;     /* buffers current owner             */
  T_ACI_LAN_SUP   clng;
  EF_CLNG lng;
  BOOL Suplng=    FALSE;
  SHORT           lastIdx;
  T_ACI_LAN_SUP LngPCMsupLst[MAX_LAN];


  TRACE_FUNCTION ("cmhSIM_RdCnfLangLP()");

  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  pPHBCmdPrm = &cmhPrm[ownBuf].phbCmdPrm;
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
  simEntStat.curCmd = AT_CMD_NONE;

  clng.lng=(T_ACI_CLAN_LNG)simShrdPrm.atb[table_id].exchData[0];

  getSupLangFromPCM(&LngPCMsupLst[0], &lastIdx);
  Suplng=checkSuppLangInLP(&LngPCMsupLst[0],lastIdx, &clng);
  
  if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR AND
       Suplng                                            )
  {
    simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
    simEntStat.entOwn = CMD_SRC_NONE;
   /*
    *-------------------------------------------------------------
    *    check basic consistency of read data
    *-------------------------------------------------------------
    */
    if ( simShrdPrm.atb[table_id].exchData EQ NULL  OR
         simShrdPrm.atb[table_id].dataLen <  ACI_LEN_LAN_LP_NTRY)

     {
        simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
        simEntStat.entOwn = CMD_SRC_NONE;
        pSIMCmdPrm->CLANact = CLAN_ACT_None;
        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
        return;
      }

#ifdef SIM_TOOLKIT
      if (simShrdPrm.fuRef >= 0)
      {
        psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCCESS);
      }
#endif

      /*
      *-----------------------------------------------------
      *    read the supported laguage or write it PCM
      *-----------------------------------------------------
      */
      switch( pSIMCmdPrm->CLANact )
      {
        case( CLAN_ACT_Read ):
          R_AT( RAT_CLAN, ownBuf ) (&clng);
          R_AT( RAT_OK, ownBuf )( AT_CMD_CLAN );
          break;
         case( CLAN_ACT_Write ):
           memcpy(lng.data,(UBYTE *) clng.str,CLAN_CODE_LEN);
           /* Implements Measure#32 Row 1072 */
           pcm_WriteFile (( UBYTE* )ef_clng_id,SIZE_EF_CLNG,( UBYTE*) &lng);
           if (pPHBCmdPrm->CLAEmode EQ CLAE_MOD_Enable)
           {  R_AT( RAT_CLAE, ownBuf ) (&clng);}

          R_AT( RAT_OK, ownBuf )( AT_CMD_CLAN );
          break;

       }
  }
  else
  {

#ifdef SIM_TOOLKIT
    if (simShrdPrm.fuRef >= 0)
    {
      psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_ERROR);
    }
#endif
   /*
    *---------------------------------------------------------------
    *          Preferred language is not supported in MS
    *---------------------------------------------------------------
    */
    if ( simShrdPrm.atb[table_id].errCode EQ SIM_CAUSE_UNKN_FILE_ID OR
         !Suplng                                                      )
    {
      TRACE_FUNCTION ("preferred language not supported");    

      switch( pSIMCmdPrm->CLANact )
      {
        case( CLAN_ACT_Read ):
          R_AT( RAT_CLAN, ownBuf ) (&LngPCMsupLst[0]);
          R_AT( RAT_OK, ownBuf )( AT_CMD_CLAN );
        break;
        case( CLAN_ACT_Write ):      /* Preferred Language not supported,so not change CLAN */
          R_AT( RAT_OK, ownBuf )( AT_CMD_CLAN );          
        break;
      }
    }
    else
    {
      pSIMCmdPrm->CLANact = CLAN_ACT_None;
      simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
      simEntStat.entOwn = CMD_SRC_NONE;
      R_AT( RAT_CME, ownBuf) ( AT_CMD_CLAN, CME_ERR_Unknown );
    }
  }
}


/*
+-----------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR              |
| STATE   : code                        ROUTINE : cmhSIM_RdCnfLangPrfLP |
+-----------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF LP from SIM for SAT feature LS.
*/
GLOBAL void cmhSIM_RdCnfLangPrfLP ( SHORT table_id )
{
  
  T_ACI_SAT_TERM_RESP resp_data;
  T_ACI_LAN_SUP   clng;
  BOOL Suplng=    FALSE;
  SHORT           lastIdx;
  T_ACI_LAN_SUP   lngPCMsupLst[MAX_LAN];
  T_ACI_RETURN    ret;

  TRACE_FUNCTION ("cmhSIM_RdCnfLangPrfLP()");

  psaSAT_InitTrmResp( &resp_data );
  
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;

  clng.lng=(T_ACI_CLAN_LNG)simShrdPrm.atb[table_id].exchData[0];
  ret = getSupLangFromPCM(&lngPCMsupLst[0], &lastIdx);
  if(ret EQ AT_FAIL)
  {
    psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
    return;
  }

  Suplng=checkSuppLangInLP(&lngPCMsupLst[0],lastIdx, &clng);

  if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR AND
       Suplng )
  {
   /*
    *-------------------------------------------------------------
    *    check basic consistency of read data
    *-------------------------------------------------------------
    */
    if ( simShrdPrm.atb[table_id].exchData EQ NULL  OR
         simShrdPrm.atb[table_id].dataLen <  ACI_LEN_LAN_LP_NTRY)

    {
      psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
      return;
    }

#ifdef SIM_TOOLKIT
    if (simShrdPrm.fuRef >= 0)
    {
      psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_SUCCESS);
    }
#endif

   /*
    *-----------------------------------------------------
    *    Send the Terminal Response
    *-----------------------------------------------------
    */
    memcpy(&resp_data.lang, clng.str, CLAN_CODE_LEN);
    psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );
  }
  else
  {

#ifdef SIM_TOOLKIT
    if (simShrdPrm.fuRef >= 0)
    {
      psaSAT_FUConfirm (simShrdPrm.fuRef, SIM_FU_ERROR);
    }
#endif
   /*
    *---------------------------------------------------------------
    *          read default language from ME
    *---------------------------------------------------------------
    */

    if ( simShrdPrm.atb[table_id].errCode EQ SIM_CAUSE_UNKN_FILE_ID OR
         !Suplng )
    {
      TRACE_FUNCTION ("default language is selected");
      memcpy(&resp_data.lang, &lngPCMsupLst[0].str, CLAN_CODE_LEN);
      psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );
            
    }
    else
    {
      psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
    }

  }

}


/*
+--------------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)             MODULE  : CMH_SIMR                  |
| STATE   : code                       ROUTINE : SIM_ENT_CSDconnect_dti_cb |
+--------------------------------------------------------------------------+

  PURPOSE : Callback for connection between SIM and TRA/L2R for CSD.

*/
#ifdef FF_SAT_E
#ifdef DTI
GLOBAL BOOL SIM_ENT_CSDconnect_dti_cb(UBYTE dti_id, T_DTI_CONN_STATE result_type)
{
  TRACE_FUNCTION("SIM_ENT_CSDconnect_dti_cb");

  switch( result_type)
  {
    case DTI_CONN_STATE_DISCONNECTING:
      break;
    case DTI_CONN_STATE_DISCONNECTED:
      /* wap_state is set to IPA_Deactivated in psaTCPIP_config_dispatch() */
      if (wap_state EQ UDPA_Deactivation)
      {
        wap_state = IPA_Deactivation;
        psaUDPIP_config_dispatch();
      }
      dti_cntrl_erase_entry(dti_id);
      dti_cntrl_clear_conn_parms(dti_id);
      if (simShrdPrm.sat_class_e_dti_id EQ dti_id)
      {
        simShrdPrm.sat_class_e_dti_id = DTI_DTI_ID_NOTPRESENT;
        TRACE_EVENT("sat_class_e_dti_id reset");
      }
      break;
    case DTI_CONN_STATE_CONNECTING:
      break;
    case DTI_CONN_STATE_CONNECTED:
      /* the SIM-SNDCP connection has been established, now send SIM_BIP_CONFIG
       * request to SIM */ 
      psaSIM_Bip_Config_Req();
      
      break;
    case DTI_CONN_STATE_ERROR:
      /* connection not possible: disconnect UDP, L2R or TRA */ 
      TRACE_EVENT("SIM_ENT_CSDconnect_dti_cb connection not possible: disconnect UDP,L2R or TRA");
      dti_cntrl_close_dpath_from_dti_id( dti_id );
      break;
    case DTI_CONN_STATE_UNKNOWN:
    default:
      TRACE_EVENT("SIM_ENT_CSDconnect_dti_cb call with not awaited value");
      break;
  }
  return TRUE;
}
#endif /* DTI */

#if defined (GPRS) AND defined (DTI)
/*
+---------------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMR                  |
| STATE   : code                        ROUTINE : SIM_SNDCP_connect_dti_cb  |
+---------------------------------------------------------------------------+

  PURPOSE : Callback for connection between SIM and SNDCP.

*/
GLOBAL BOOL SIM_SNDCP_connect_dti_cb(UBYTE dti_id, T_DTI_CONN_STATE result_type)
{
  TRACE_FUNCTION("SIM_SNDCP_connect_dti_cb");

  switch( result_type)
  {
    case DTI_CONN_STATE_DISCONNECTING:
      break;
    case DTI_CONN_STATE_DISCONNECTED:
      dti_cntrl_erase_entry(dti_id);
      if (simShrdPrm.sat_class_e_dti_id EQ dti_id)
      {
        simShrdPrm.sat_class_e_dti_id = DTI_DTI_ID_NOTPRESENT;
        TRACE_EVENT("sat_class_e_dti_id reset");
      }
      break;
    case DTI_CONN_STATE_CONNECTING:
      break;
    case DTI_CONN_STATE_CONNECTED:
      /* the SIM-SNDCP connection has been established, now send SIM_BIP_CONFIG
       * request to SIM */ 
      psaSIM_Bip_Config_Req();
      break;
    case DTI_CONN_STATE_ERROR:
      /* connection not possible: disconnect SNDCP */
      dti_cntrl_close_dpath_from_dti_id( dti_id );
      break;
    case DTI_CONN_STATE_UNKNOWN:
    default:
      TRACE_EVENT("SIM_SNDCP_connect_dti_cb call with not awaited value");
      break;
  }
  return TRUE;
}


/*
+--------------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)             MODULE  : CMH_SIMR                  |
| STATE   : code                       ROUTINE : SIM_ENT_GPRSconnect_dti_cb|
+--------------------------------------------------------------------------+

  PURPOSE : Callback for connection between SIM and UDP/SNDCP for GPRS.

*/

GLOBAL BOOL SIM_ENT_GPRSconnect_dti_cb(UBYTE dti_id, T_DTI_CONN_STATE result_type)
{
  TRACE_FUNCTION("SIM_ENT_GPRSconnect_dti_cb");

  switch( result_type)
  {
    case DTI_CONN_STATE_DISCONNECTING:
      break;
    case DTI_CONN_STATE_DISCONNECTED:
      dti_cntrl_erase_entry(dti_id);
      if (simShrdPrm.sat_class_e_dti_id EQ dti_id)
      {
        simShrdPrm.sat_class_e_dti_id = DTI_DTI_ID_NOTPRESENT;
        TRACE_EVENT("sat_class_e_dti_id reset");
      }
      break;
    case DTI_CONN_STATE_CONNECTING:
    case DTI_CONN_STATE_CONNECTED:
      break;
    case DTI_CONN_STATE_ERROR:
      /* connection not possible: disconnect UDP or SNDCP */
      TRACE_EVENT("SIM_ENT_GPRSconnect_dti_cb connection not possible: disconnect UDP or SNDCP");
      dti_cntrl_close_dpath_from_dti_id( dti_id );
      break;
    case DTI_CONN_STATE_UNKNOWN:
    default:
      TRACE_EVENT("SIM_ENT_GPRSconnect_dti_cb call with not awaited value");
      break;
  }
  return TRUE;
}

#endif /* GPRS */

#endif /* FF_SAT_E */

#ifdef FF_DUAL_SIM

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)    MODULE  : CMH_SIMR                     |
|                            ROUTINE : cmhSIM_SIMSelected           |
+-------------------------------------------------------------------+

  PURPOSE : Informs the upper layer the result of the SIM Selection process.

*/
GLOBAL void cmhSIM_SIMSelected ( void )
{
  T_ACI_AT_CMD cmdBuf;
  T_ACI_CME_ERR err;

  TRACE_FUNCTION("cmhSIM_SIMSelected()");

  switch(simEntStat.curCmd)
  {
    case(AT_CMD_SIM):

      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):

          simEntStat.curCmd = AT_CMD_NONE;

          R_AT( RAT_OK, simEntStat.entOwn )
              ( AT_CMD_SIM );
          cmh_logRslt ( simEntStat.entOwn, RAT_OK, AT_CMD_SIM,
		  	     -1, BS_SPEED_NotPresent,CME_ERR_NotPresent);
          return;

        default:
          err = cmhSIM_GetCmeFromSim ( simShrdPrm.rslt );
          break;
      }

      cmdBuf = simEntStat.curCmd;
      simEntStat.curCmd = AT_CMD_NONE;

      R_AT( RAT_CME, simEntStat.entOwn )
            ( cmdBuf, err );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                    -1, BS_SPEED_NotPresent, err );
      break;
  }
}
#endif /*FF_DUAL_SIM*/

#ifdef FF_CPHS_REL4
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_RdCnfCfis         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF CFIS from SIM.
*/
GLOBAL void cmhSIM_RdCnfCfis ( SHORT table_id )
{
  T_ACI_AT_CMD    cmdBuf;    /* buffers current command          */
  T_ACI_CMD_SRC   ownBuf;    /* buffers current owner            */
  T_ACI_CFIS_CFU  cfisData;  /* CFIS data                        */ 

  UBYTE   *pExchData;        /* points to exchange data buffer   */
  UBYTE   dataLen;           /* holds length of data             */
  UBYTE   CFISmaxRcd;        /* holds no. of records in EF-CFIS  */

  TRACE_FUNCTION ("cmhSIM_RdCnfCfis()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  pExchData  = simShrdPrm.atb[table_id].exchData;
  dataLen    = simShrdPrm.atb[table_id].dataLen;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( pExchData EQ NULL        OR
           dataLen < ACI_SIZE_EF_CFIS  OR *pExchData EQ 0xFF)
      {
        simEntStat.curCmd = AT_CMD_NONE;
        simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
      }
      else
      {
        /*
         *-----------------------------------------------------------
         * process parameter <msp>
         *-----------------------------------------------------------
         */
        cfisData.mspId = *pExchData;

       /*
        *-----------------------------------------------------------
        * process parameter <cfustat>
        *-----------------------------------------------------------
        */
        cfisData.cfuStat = *(pExchData+1);

       /*
        *-----------------------------------------------------------
        * process parameter <type>
        *-----------------------------------------------------------
        */
        cmhPHB_toaDmrg ( *( pExchData + 3 ),
                         &cfisData.type );

       /*
        *-----------------------------------------------------------
        * process parameter <number>
        *-----------------------------------------------------------
        */
        cmhPHB_getAdrStr ( cfisData.number ,
                           MAX_PHB_NUM_LEN - 1,
                           pExchData + 4,
                           *(pExchData+2) );
        
        CFISmaxRcd = simShrdPrm.atb[table_id].recMax;

        R_AT( RAT_P_CFIS, ownBuf ) ( &cfisData );

        if( CFISIndex )
        {
          if( CFISIndex NEQ CFISmaxRcd )
          {
            CFISIndex++;
            if ( cmhSIM_ReadRecordEF (ownBuf, AT_CMD_P_CFIS, SIM_CFIS,
                     CFISIndex, NOT_PRESENT_8BIT, NULL, cmhSIM_RdCnfCfis) NEQ AT_EXCT )
            {
              simEntStat.curCmd = AT_CMD_NONE;
              simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

              R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
            }
          }
          else
          {
            CFISIndex=0;
          }
        }
        if( CFISIndex EQ 0 )
        {
          simEntStat.curCmd = AT_CMD_NONE;
          simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;
          R_AT( RAT_OK, ownBuf ) ( cmdBuf );
        }
      }
      break;
    }
    default:
    {
      simEntStat.curCmd = AT_CMD_NONE;
      simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

      R_AT( RAT_CME, ownBuf )
        (
          cmdBuf,
          cmhSIM_GetCmeFromSim ( simShrdPrm.atb[table_id].errCode )
        );
      break;
    }
  }
simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_WrCnfCfis         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of writing data
            into EF-CFIS in SIM.
*/
GLOBAL void cmhSIM_WrCnfCfis ( SHORT table_id )
{

  T_ACI_AT_CMD  cmdBuf;       /* buffers current command     */
  T_ACI_CMD_SRC ownBuf;       /* buffers current owner       */

  TRACE_FUNCTION ("cmhSIM_WrCnfCfis ()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  simEntStat.curCmd = AT_CMD_NONE;
  simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

  if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)
  {
    R_AT( RAT_OK, ownBuf ) ( cmdBuf );
  }
  else
  {
    R_AT( RAT_CME, ownBuf )  /* unsuccessful SIM write */
    (
      cmdBuf,
      cmhSIM_GetCmeFromSim (  simShrdPrm.atb[table_id].errCode )
    );
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_RdCnfMbi          |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF-MBI from SIM.
*/
GLOBAL void cmhSIM_RdCnfMbi ( SHORT table_id )
{
  T_ACI_AT_CMD    cmdBuf;    /* buffers current command          */
  T_ACI_CMD_SRC   ownBuf;    /* buffers current owner            */
  T_ACI_MBI       mbiData;   /* MBT  data                        */ 

  UBYTE   *pExchData;        /* points to exchange data buffer   */
  UBYTE   dataLen;           /* holds length of data             */
  UBYTE   MBImaxRcd;         /* holds no. of records in EF-MBI   */


  TRACE_FUNCTION ("cmhSIM_RdCnfMbi()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  simEntStat.curCmd = AT_CMD_NONE;
  simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;
  pExchData  = simShrdPrm.atb[table_id].exchData;
  dataLen    = simShrdPrm.atb[table_id].dataLen;
  MBImaxRcd = simShrdPrm.atb[table_id].recMax;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( pExchData EQ NULL        OR
           dataLen < ACI_SIZE_EF_MBI )
      {
        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
      }
      else
      {
        mbiData.mbdn_id_voice = *pExchData;
        mbiData.mbdn_id_fax   = *( pExchData + 1 );
        mbiData.mbdn_id_email = *( pExchData + 2 );
        mbiData.mbdn_id_other = *( pExchData + 3 );

        R_AT( RAT_P_MBI, ownBuf ) ( &mbiData );

        if( MBI_Index )
        {
          if( MBI_Index NEQ MBImaxRcd )
          {
            MBI_Index++;
            if ( cmhSIM_ReadRecordEF (ownBuf, AT_CMD_P_MBI, SIM_MBI,
                     MBI_Index, NOT_PRESENT_8BIT, NULL, cmhSIM_RdCnfMbi) NEQ AT_EXCT )
            {
              R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
            }
          }
          else
          {
            MBI_Index = 0;
          }
        }
        if( MBI_Index EQ 0 )
        {
          R_AT( RAT_OK, ownBuf ) ( cmdBuf );
        }
      }
      break;
    }
    default:
    {
      R_AT( RAT_CME, ownBuf )
        (
          cmdBuf,
          cmhSIM_GetCmeFromSim ( simShrdPrm.atb[table_id].errCode )
        );
      break;
    }
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_RdCnfMbdn         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF-MBDN from SIM.
*/
GLOBAL void cmhSIM_RdCnfMbdn ( SHORT table_id )
{
  T_ACI_AT_CMD    cmdBuf;    /* buffers current command          */
  T_ACI_CMD_SRC   ownBuf;    /* buffers current owner            */
  T_ACI_MBDN      mbdnData;  /* MBDN data                        */ 

  UBYTE   *pExchData;        /* points to exchange data buffer   */
  UBYTE   dataLen;           /* holds length of data             */
  UBYTE   alphaLen;          /* max. length of alpha identifier   */

  TRACE_FUNCTION ("cmhSIM_RdCnfMbdn()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  pExchData  = simShrdPrm.atb[table_id].exchData;
  dataLen    = simShrdPrm.atb[table_id].dataLen;
  simEntStat.curCmd = AT_CMD_NONE;
  simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( pExchData EQ NULL        OR
           dataLen < ACI_SIZE_EF_MBDN )
      {
        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
      }
      else
      {
        alphaLen = dataLen - ACI_MIN_SIZE_EF_MSISDN;
        /*
         *-----------------------------------------------------------
         * process parameter <alpha>
         *-----------------------------------------------------------
        */
        cmhPHB_getTagNt ( pExchData,
                          alphaLen,
                          mbdnData.alpha,
                          MAX_ALPHA_LEN );

        pExchData += alphaLen;
       /*
        *-----------------------------------------------------------
        * process parameter <type>
        *-----------------------------------------------------------
        */
        cmhPHB_toaDmrg ( *( pExchData + 1 ),
                         &mbdnData.type );

       /*
        *-----------------------------------------------------------
        * process parameter <number>
        *-----------------------------------------------------------
        */
        cmhPHB_getAdrStr ( mbdnData.number ,
                           MAX_MB_NUM_LEN - 1,
                           pExchData + 2,
                           *pExchData );

        R_AT( RAT_P_MBDN, ownBuf ) ( &mbdnData );
        R_AT( RAT_OK, ownBuf ) ( cmdBuf );
      }
      break;
    }
    default:
    {
      R_AT( RAT_CME, ownBuf )
        (
          cmdBuf,
          cmhSIM_GetCmeFromSim ( simShrdPrm.atb[table_id].errCode )
        );
      break;
    }
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_WrCnfMbdn         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of writing data
            into EF-MBDN in SIM.
*/
GLOBAL void cmhSIM_WrCnfMbdn ( SHORT table_id )
{

  T_ACI_AT_CMD  cmdBuf;       /* buffers current command     */
  T_ACI_CMD_SRC ownBuf;       /* buffers current owner       */

  TRACE_FUNCTION ("cmhSIM_WrCnfMbdn ()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  simEntStat.curCmd = AT_CMD_NONE;
  simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

  if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)
  {
    R_AT( RAT_OK, ownBuf ) ( cmdBuf );
  }
  else
  {
    R_AT( RAT_CME, ownBuf )  /* unsuccessful SIM write */
    (
      cmdBuf,
      cmhSIM_GetCmeFromSim (  simShrdPrm.atb[table_id].errCode )
    );
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_RdCnfMwis         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of reading
            EF MWIS from SIM.
*/
GLOBAL void cmhSIM_RdCnfMwis ( SHORT table_id )
{
  T_ACI_AT_CMD    cmdBuf;    /* buffers current command          */
  T_ACI_CMD_SRC   ownBuf;    /* buffers current owner            */
  T_ACI_MWIS_MWI  mwisData;  /* MWIS data                        */

  UBYTE   *pExchData;        /* points to exchange data buffer   */
  UBYTE   dataLen;           /* holds length of data             */
  UBYTE   MWISmaxRcd;        /* holds no. of records in EF-MWIS  */

  TRACE_FUNCTION ("cmhSIM_RdCnfMwis()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  pExchData  = simShrdPrm.atb[table_id].exchData;
  dataLen    = simShrdPrm.atb[table_id].dataLen;

  switch ( simShrdPrm.atb[table_id].errCode )
  {
    case ( SIM_NO_ERROR ):
    {
      /*
       *-------------------------------------------------------------
       * check basic consistency of read data
       *-------------------------------------------------------------
       */
      if ( pExchData EQ NULL        OR
           dataLen < ACI_SIZE_EF_MWIS  OR *pExchData EQ 0x00)
      {
        simEntStat.curCmd = AT_CMD_NONE;
        simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
      }
      else
      {
        /*
         *-----------------------------------------------------------
         * process parameter <mwisStat>
         *-----------------------------------------------------------
         */
        mwisData.mwiStat = *pExchData;

       /*
        *-----------------------------------------------------------
        * process parameter <mwis_count_voice>
        *-----------------------------------------------------------
        */
        mwisData.mwis_count_voice = *(pExchData+1);

       /*
        *-----------------------------------------------------------
        * process parameter <mwis_count_fax>
        *-----------------------------------------------------------
        */
        mwisData.mwis_count_fax = *(pExchData+2);

       /*
        *-----------------------------------------------------------
        * process parameter <mwis_count_email>
        *-----------------------------------------------------------
        */
        mwisData.mwis_count_email = *(pExchData+3);

       /*
        *-----------------------------------------------------------
        * process parameter <mwis_count_other>
        *-----------------------------------------------------------
        */
        mwisData.mwis_count_other = *(pExchData+4);

        MWISmaxRcd = simShrdPrm.atb[table_id].recMax;

        R_AT( RAT_P_MWIS, ownBuf ) ( &mwisData );

        if( MWISIndex )
        {
          if( MWISIndex NEQ MWISmaxRcd )
          {
            MWISIndex++;
            if ( cmhSIM_ReadRecordEF (ownBuf, AT_CMD_P_MWIS, SIM_MWIS,
                 MWISIndex, NOT_PRESENT_8BIT, NULL, cmhSIM_RdCnfMwis) NEQ AT_EXCT )
            {
              simEntStat.curCmd = AT_CMD_NONE;
              simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

              R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
            }
          }
          else
          {
            MWISIndex=0;
          }
        }
        if( MWISIndex EQ 0 )
        {
          simEntStat.curCmd = AT_CMD_NONE;
          simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;
          R_AT( RAT_OK, ownBuf ) ( cmdBuf );
        }
      }
      break;
    }
    default:
    {
      simEntStat.curCmd = AT_CMD_NONE;
      simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

      R_AT( RAT_CME, ownBuf )
        (
          cmdBuf,
          cmhSIM_GetCmeFromSim ( simShrdPrm.atb[table_id].errCode )
        );
      break;
    }
  }
simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMR                 |
|                                 ROUTINE : cmhSIM_WrCnfMwis         |
+--------------------------------------------------------------------+

  PURPOSE : This function handles the confirmation of writing data
            into EF-MWIS in SIM.
*/
GLOBAL void cmhSIM_WrCnfMwis ( SHORT table_id )
{

  T_ACI_AT_CMD  cmdBuf;       /* buffers current command     */
  T_ACI_CMD_SRC ownBuf;       /* buffers current owner       */
  U8 i = 0;
  T_ACI_MWIS_MWI  mwisData;   /* MWIS data                   */

  TRACE_FUNCTION ("cmhSIM_WrCnfMwis ()");

  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;
  simEntStat.curCmd = AT_CMD_NONE;
  simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

  if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)
  {
    if( cmdBuf NEQ AT_CMD_P_MWIS )
    {
      memcpy(&mwisData,&smsShrdPrm.MWISdata,sizeof(T_ACI_MWIS_MWI));
      for(i; i < CMD_SRC_MAX; i++)
      {
        R_AT( RAT_P_MWI, i)(1,&mwisData);
      }
    }
    else
    {
      R_AT( RAT_OK, ownBuf ) ( cmdBuf );
    }
  }
  else
  {
    R_AT( RAT_CME, ownBuf )  /* unsuccessful SIM write */
    (
      cmdBuf,
      cmhSIM_GetCmeFromSim (  simShrdPrm.atb[table_id].errCode )
    );
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}
#endif /* FF_CPHS_REL4 */

/* Implements Measure 97 */
/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_CardUnblocked_PINChanged
+------------------------------------------------------------------------------
|  Purpose     : This function can check whether the Card is Unblocked
|                or PIN is Changed.
|                When this function will be called for checking whether
|                the PIN is changed then the argument PINChanged will be
|                TRUE otherwise it will be FALSE
|
|  Parameters  : PINChanged - TRUE or FALSE
|
|  Return      : void
+------------------------------------------------------------------------------
*/

GLOBAL void cmhSIM_CardUnblocked_PINChanged ( BOOL PINChanged )
{
  UBYTE cmdBuf;
  T_ACI_CME_ERR err;

  TRACE_FUNCTION ( "cmhSIM_CardUnblocked_PINChanged()" );

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

  switch( simEntStat.curCmd )
  {
    case( AT_CMD_CPIN ):
    case( AT_CMD_PVRF ):
      /*lint -e{408}*/
    case( KSD_CMD_UBLK ):
    case( AT_CMD_CPWD ):
      /*lint -e{408}*/
    case( KSD_CMD_PWD ):
      /*
       *----------------------------------------------------------------
       * process event for +CPIN, %PVRF and KSD UBLK command
       * also
       * process event for +CPWD and KSD PWD command
       *----------------------------------------------------------------
       */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):
          if( (PINChanged EQ TRUE) OR (simShrdPrm.crdPhs NEQ 0xFF) )
          {
            cmdBuf = simEntStat.curCmd;
            simEntStat.curCmd = AT_CMD_NONE;

            R_AT( RAT_OK, simEntStat.entOwn )
              ( cmdBuf );
            cmh_logRslt ( simEntStat.entOwn, RAT_OK, (T_ACI_AT_CMD)cmdBuf, -1, BS_SPEED_NotPresent, CME_ERR_NotPresent );
          }
          return;

        case( SIM_CAUSE_PIN1_EXPECT ):
        case( SIM_CAUSE_PIN2_EXPECT ):
          err = CME_ERR_WrongPasswd;
          break;

        default:
          err = cmhSIM_GetCmeFromSim ( simShrdPrm.rslt );
          break;
      }

      cmdBuf = simEntStat.curCmd;
      simEntStat.curCmd = AT_CMD_NONE;

      R_AT( RAT_CME, simEntStat.entOwn )
            ( cmdBuf, err );

      cmh_logRslt ( simEntStat.entOwn, RAT_CME, (T_ACI_AT_CMD)cmdBuf,
                    -1, BS_SPEED_NotPresent, err );
      break;
  }
}

/* Implements Measure 106 */
/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_ProcessEvents
|------------------------------------------------------------------------------
|  Purpose     : Process Events for +CAMM, +CPUC, +CACM commands.
|
|  Parameters  : at_cmd_id - AT command identifier
|
|  Return      : void
+------------------------------------------------------------------------------
*/

LOCAL void cmhSIM_ProcessEvents ( T_ACI_AT_CMD at_cmd_id )
{
  TRACE_FUNCTION ( "cmhSIM_ProcessEvents()" );

  simEntStat.curCmd = AT_CMD_NONE;

  if( simShrdPrm.rslt EQ SIM_NO_ERROR )
  {
    /*
     * Try it again
     */
    switch ( at_cmd_id )
    {
      case ( AT_CMD_CAMM ):
        aoc_update_sim_datafield ( SECOND_UPDATE, ACT_WR_DAT,
                                   SIM_ACMMAX, aoc_update_acmmax_cb );
        break;

      case ( AT_CMD_CPUC ):
        aoc_update_puct (SECOND_UPDATE, 0L);
        break;

      case ( AT_CMD_CACM ):
        aoc_update_sim_datafield ( SECOND_UPDATE, ACT_WR_REC,
                                   SIM_ACM, aoc_update_acm_cb );
        break;
    }
  }
  else
  {
    R_AT( RAT_CME, simEntStat.entOwn )
          ( at_cmd_id, CME_ERR_WrongPasswd );
  }
}

/* Implements Measure 183 */
/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_PINEnabledDisabled
|------------------------------------------------------------------------------
|  Purpose     : SIM Enabled or Disabled
|
|  Parameters  : void
|
|  Return      : void
+------------------------------------------------------------------------------
*/

GLOBAL void cmhSIM_PINEnabledDisabled ( void )
{
  T_ACI_CME_ERR err;

  TRACE_FUNCTION ( "cmhSIM_PINEnabledDisabled()" );

  /*
   *-------------------------------------------------------------------
   * check for command context
   *-------------------------------------------------------------------
   */
  if( simEntStat.curCmd EQ AT_CMD_CLCK )
  {
    /*
     *----------------------------------------------------------------
     * process event for +CLCK command
     *----------------------------------------------------------------
     */
    switch( simShrdPrm.rslt )
    {
      case( SIM_NO_ERROR ):

        simEntStat.curCmd = AT_CMD_NONE;

        R_AT( RAT_OK, simEntStat.entOwn )
              ( AT_CMD_CLCK );
        cmh_logRslt ( simEntStat.entOwn, RAT_OK, AT_CMD_CLCK, -1, BS_SPEED_NotPresent, CME_ERR_NotPresent );
        return;

      case( SIM_CAUSE_PIN1_EXPECT ):
      case( SIM_CAUSE_PIN1_BLOCKED ):
        err = CME_ERR_WrongPasswd;
        break;

      default:
        err = cmhSIM_GetCmeFromSim ( simShrdPrm.rslt );
        break;
    }

    simEntStat.curCmd = AT_CMD_NONE;

    R_AT( RAT_CME, simEntStat.entOwn )
          ( AT_CMD_CLCK, err );
    cmh_logRslt ( simEntStat.entOwn, RAT_CME, AT_CMD_CLCK,
                  -1, BS_SPEED_NotPresent, err );      
  }
}

/* Implements Measure 200 */
/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_Compare_CNUMMsisdnIdx
|------------------------------------------------------------------------------
|  Purpose     : Comapres CNUMMsisdnIdx
|
|  Parameters  : void
|
|  Return      : void
+------------------------------------------------------------------------------
*/

LOCAL void cmhSIM_Compare_CNUMMsisdnIdx ( void )
{
  T_SIM_CMD_PRM* pSIMCmdPrm;
  T_ACI_AT_CMD   cmdBuf;
  T_ACI_CMD_SRC  ownBuf;

  TRACE_FUNCTION ( "cmhSIM_Compare_CNUMMsisdnIdx()" );
  
  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  cmdBuf     = simEntStat.curCmd;
  ownBuf     = simEntStat.entOwn;

  if ( (CNUMMsisdnIdx EQ MAX_MSISDN - 1) OR 
       ((pSIMCmdPrm -> CNUMActRec) EQ CNUMMaxRec) )
  {
    simEntStat.curCmd = AT_CMD_NONE;
    simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
    simEntStat.entOwn = CMD_SRC_NONE;

    R_AT( RAT_CNUM, ownBuf ) ( &CNUMMsisdn[0], CNUMMaxRec );

    if ( (pSIMCmdPrm -> CNUMActRec) EQ CNUMMaxRec )
    {
      if (pSIMCmdPrm -> CNUMOutput)
      {
        R_AT( RAT_OK, ownBuf ) ( cmdBuf );
      }
      else
      {
        R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_NotFound );
      }
    }
  }
  else
  {
    CNUMMsisdnIdx++;
    pSIMCmdPrm -> CNUMActRec++;

    if ( cmhSIM_ReqMsisdn ( ownBuf, pSIMCmdPrm -> CNUMActRec ) NEQ AT_EXCT )
    {
      cmhSIM_SndError( ownBuf, cmdBuf, CME_ERR_Unknown );
    }
  }

}

/* Implements Measure 7, 17, 24, 35 */
/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_SndError
|------------------------------------------------------------------------------
|  Purpose     : Reports Error
|
|  Parameters  : ownBuf  - AT Command Source Identifier 
|                cmdBuf  - AT Command Identifier
|                cme_err - +CME ERROR parameter
|
|  Return      : void
+------------------------------------------------------------------------------
*/
LOCAL void cmhSIM_SndError( T_ACI_CMD_SRC  ownBuf, T_ACI_AT_CMD   cmdBuf,
                            T_ACI_CME_ERR  cme_err )
{
  TRACE_FUNCTION ( "cmhSIM_SndError()" );

  simEntStat.curCmd = AT_CMD_NONE;
  simShrdPrm.owner  = (T_OWN)CMD_SRC_NONE;
  simEntStat.entOwn = CMD_SRC_NONE;

  R_AT( RAT_CME, ownBuf ) ( cmdBuf, cme_err );

}

/*==== EOF ========================================================*/