view src/aci2/aci/cmh_simr.c @ 701:35e7f9d0379f

targets: add TARGET_HAS_BUZZER to c11x, c139 and dsample This new target config preprocessor symbol was introduced in Tourmaline in connection with the new approach to playing buzzer melodies via PWT, properly omitting the responsible code on targets where BU output controls the vibrator instead. That code is not present in Magnetite and we have no plans to backport it here, but target header files should be kept consistent between the two trees, especially given that we plan to support FC Venus target in Magnetite.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 26 Mar 2022 19:51:34 +0000
parents 93999a60b835
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"

#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_mmcc.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 ==================================================*/

/*
+-------------------------------------------------------------------+
| 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, -1, -1 );
      }
      /*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;
  T_SIM_SET_PRM *sim_set_prm;

  TRACE_FUNCTION ("cmhsim_simactivated_clck()");

  simEntStat.curCmd = AT_CMD_NONE;
  sim_set_prm = &simShrdPrm.setPrm[simEntStat.entOwn];

  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, -1, -1 );
      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, -1, 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, -1, -1 );
}

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

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

LOCAL void cmhsim_simactivated_start( void )
{
  UBYTE 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 = 0; 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 )
{
  UBYTE 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 */
  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;
  }

  switch( simEntStat.curCmd )
  {
    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
        *----------------------------------------------------------------
        */

      cmdBuf = simEntStat.curCmd;
      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;
       err_code = CME_ERR_Unknown;
       R_AT( RAT_CME, simEntStat.entOwn ) ( cmdBuf, err_code );
       cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf, -1, -1, err_code );
       simShrdPrm.PINQuery = 0;
       return;
     }
#endif

      if( err_code EQ CME_ERR_SimWrong )
      {
        R_AT( RAT_CME, simEntStat.entOwn ) ( cmdBuf, err_code );
        cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf, -1, -1, err_code );
        simShrdPrm.PINQuery = 0;
        return;
      }

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

      if ( AciSLockShrd.blocked)
      {
        /* @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(AciSLockShrd.current_lock,&err_code);

          return_rat_ok = 0;
          R_AT( RAT_CME, simEntStat.entOwn )
             ( cmdBuf, err_code );
          cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf, -1, -1, err_code );
      }

#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 ) ( cmdBuf );
      cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, -1, -1 );
     }
      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, -1, 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
    *----------------------------------------------------------------
    */
      cmdBuf = simEntStat.curCmd;
      if( err_code EQ CME_ERR_SimWrong )
      {
        simEntStat.curCmd = AT_CMD_NONE;
        mmEntStat.curCmd  = AT_CMD_NONE;
        R_AT( RAT_CME, simEntStat.entOwn ) ( cmdBuf, err_code );
        cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf, -1, -1, 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;
          mmEntStat.entOwn  = mmShrdPrm.owner = 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;
          mmEntStat.entOwn  = mmShrdPrm.owner = 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;
        /* process event spontaneous insertion */
        for( idx = 0; 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 )
{
  UBYTE 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, -1, 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 = 0; 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, -1, 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_MAX; i++)
                cmhPrm[i].ccCmdPrm.ALSmode = ALSlock;
                /* and lock them all */
            }
  #ifndef _SIMULATION_
            /* write Lock to FFS */
            FFS_fwrite("/gsm/com/ALSlock", &ALSlock, sizeof(ALSlock));
  #endif
          }
          else
          /* unlock ALS */
          {
            ALSlock = ALS_MOD_NOTPRESENT;
  #ifndef _SIMULATION_
            /* remove lock from FFS */
            FFS_remove("/gsm/com/ALSlock");
  #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, -1, -1 );
          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, -1, 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, -1, CME_ERR_SimFail );
      break;
  }
}

GLOBAL void cmhSIM_PINVerified ( void )
{
  UBYTE 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, -1, -1 );
          }
          /* 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, -1, 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, -1, 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, -1, 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;

    case( AT_CMD_CAMM ):
      /*
       *----------------------------------------------------------------
       * process event for +CAMM command
       *----------------------------------------------------------------
       */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):
          /*
           * Try it again
           */
          simEntStat.curCmd = AT_CMD_NONE;
          aoc_update_acmmax (SECOND_UPDATE, 0L);
          break;

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

    case( AT_CMD_CPUC ):
      /*
       *----------------------------------------------------------------
       * process event for +CPUC command
       *----------------------------------------------------------------
       */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):
          /*
           * Try it again
           */
          simEntStat.curCmd = AT_CMD_NONE;
          aoc_update_puct (SECOND_UPDATE, 0L);
          break;

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

    case( AT_CMD_CACM ):
      /*
       *----------------------------------------------------------------
       * process event for +CACM command
       *----------------------------------------------------------------
       */
      switch( simShrdPrm.rslt )
      {
        case( SIM_NO_ERROR ):
          /*
           * Try it again
           */
          simEntStat.curCmd = AT_CMD_NONE;
          aoc_update_acm (SECOND_UPDATE, 0L);
          break;

        default:
          simEntStat.curCmd = AT_CMD_NONE;
          R_AT( RAT_CME, simEntStat.entOwn )
                ( AT_CMD_CACM, CME_ERR_WrongPasswd );
          break;
      }
      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 = pPHBCmdPrm->temp_cmhStor;
         pPHBCmdPrm->phbStor = pPHBCmdPrm->temp_phbStor;

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

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

        /*---------------------------------------------------------------*
         * 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, -1, 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, -1, 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;
  UBYTE         cmdBuf;

  TRACE_FUNCTION ("cmhSIM_PINChanged()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( simEntStat.curCmd )
  {
    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 ):

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

          R_AT( RAT_OK, simEntStat.entOwn )
            ( cmdBuf );
          cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, -1, -1 );
          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;
      }

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

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

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

  PURPOSE : SIM enabled

*/

GLOBAL void cmhSIM_PINEnabled ( void )
{
  T_ACI_CME_ERR err;

  TRACE_FUNCTION ("cmhSIM_PINEnabled()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( simEntStat.curCmd )
  {
    case( 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, -1, -1 );
          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, -1, err );
      break;
  }
}

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

  PURPOSE : SIM disabled

*/

GLOBAL void cmhSIM_PINDisabled ( void )
{
  T_ACI_CME_ERR err;

  TRACE_FUNCTION ("cmhSIM_PINDisabled()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( simEntStat.curCmd )
  {
    case( 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, -1, -1 );
          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, -1, err );
      break;
  }
}

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

  PURPOSE : Card unblocked

*/

GLOBAL void cmhSIM_CardUnblocked ( void )
{
  UBYTE cmdBuf;
  T_ACI_CME_ERR err;

  TRACE_FUNCTION ("cmhSIM_CardUnblocked()");

/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( simEntStat.curCmd )
  {
    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*/
          {
            cmdBuf = simEntStat.curCmd;
            simEntStat.curCmd = AT_CMD_NONE;

            R_AT( RAT_OK, simEntStat.entOwn )
              ( cmdBuf );
            cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, -1, -1 );
          }/* 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;
      }

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

      R_AT( RAT_CME, simEntStat.entOwn )
            ( cmdBuf, err );
      cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf,
                    -1, -1, 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 )
{
  UBYTE 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;
  simEntStat.entOwn = simShrdPrm.owner = OWN_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   tmpActRec;         /* actual record number              */
  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    )
      {
        simEntStat.curCmd = AT_CMD_NONE;
        simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

        R_AT( RAT_CME, 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 )
          {
            simEntStat.curCmd = AT_CMD_NONE;
            simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

            R_AT( RAT_CME, ownBuf ) ( cmdBuf, CME_ERR_Unknown );
          }
        }
        else
        {
          /*
           *---------------------------------------------------------
           * tmpActRec is used to prevent conflicts with global
           * variable pSIMCmdPrm -> CNUMActRec
           *---------------------------------------------------------
           */
          tmpActRec = pSIMCmdPrm -> CNUMActRec;

          /*
           *---------------------------------------------------------
           * bearer capability EF abscent
           *---------------------------------------------------------
           */
          /* VO patch 14.03.01 - check vldFlag when it isn't TRUE decrease CNUMMsisdnIdx.
           * read the next entry and write the entry in the CNUMMsisdnIdx again          */
          if ( CNUMMsisdn[CNUMMsisdnIdx].vldFlag EQ FALSE )
            CNUMMsisdnIdx--;

          if ( CNUMMsisdnIdx EQ MAX_MSISDN - 1 OR
               tmpActRec     EQ CNUMMaxRec        )
          {
            simEntStat.curCmd = AT_CMD_NONE;
            simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

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

            if ( tmpActRec 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 )
            {
              simEntStat.curCmd = AT_CMD_NONE;
              simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

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

      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-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_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_U_CALL_CONF* callCnf;     /* call confirm message             */
  T_bearer_cap*  bearCap;     /* bearer capability                */
  UBYTE          tmpActRec;   /* actual record number             */
  UBYTE*         pExchData;   /* points to exchange data buffer   */
  UBYTE          dataLen;     /* holds length of data */

  TRACE_FUNCTION ("cmhSIM_CnfCcp()");

  pSIMCmdPrm = &cmhPrm[simEntStat.entOwn].simCmdPrm;
  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    )
      {
        simEntStat.curCmd = AT_CMD_NONE;
        simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

        R_AT( RAT_CME, 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 */
        {
          PALLOC_MSG ( msg, MMCC_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 );

          /*
           *-----------------------------------------------------------
           * 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 L2_X25      AND
                   bearCap -> v_sync_async                      AND
                   bearCap -> sync_async         EQ SYNCHRONOUS     )
              {
                CNUMMsisdn[CNUMMsisdnIdx].service =
                                                 CNUM_SERV_PacketSynch;
              }
              else if
                 (   bearCap -> v_sig_access_prot
                     AND
                   ( bearCap -> sig_access_prot EQ SIAP_X28_INDIV_NUI OR
                     bearCap -> sig_access_prot EQ SIAP_X28_UNIV_NUI  OR
                     bearCap -> sig_access_prot EQ SIAP_X28_NON_DEDIC
                   )
                     AND
                     bearCap -> v_sync_async
                     AND
                     bearCap -> sync_async        EQ 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
         *-----------------------------------------------------------
         */
        tmpActRec = pSIMCmdPrm -> CNUMActRec;

        if ( CNUMMsisdnIdx EQ MAX_MSISDN - 1 OR
             tmpActRec     EQ CNUMMaxRec        )
        {
          simEntStat.curCmd = AT_CMD_NONE;
          simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

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

          if ( tmpActRec 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 )
          {
            simEntStat.curCmd = AT_CMD_NONE;
            simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

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

      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-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;
        simEntStat.curCmd = AT_CMD_NONE;
        simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

        R_AT( RAT_CME, 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;
          simEntStat.entOwn = simShrdPrm.owner = OWN_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;
            simEntStat.curCmd = AT_CMD_NONE;
            simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

            R_AT( RAT_CME, simEntStat.entOwn )
              (
                AT_CMD_CPOL,
                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;
            simEntStat.curCmd = AT_CMD_NONE;
            simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

            R_AT( RAT_CME, simEntStat.entOwn )
              (
                AT_CMD_CPOL,
                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;
          simEntStat.entOwn = simShrdPrm.owner = OWN_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;
      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-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;
      simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

      R_AT( RAT_OK, ownBuf )( AT_CMD_CPOL );
      break;
    }
    case SIM_CAUSE_ACCESS_PROHIBIT:
    {
      pSIMCmdPrm->CPOLact = CPOL_ACT_None;
      simEntStat.curCmd = AT_CMD_NONE;
      simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

      R_AT( RAT_CME, ownBuf /*simEntStat.entOwn*/ )
        (
          AT_CMD_CPOL,
          CME_ERR_OpNotAllow
        );
      break;
    }

    /* unsuccessful PLMN SEL list update */
    default:
    {
      pSIMCmdPrm->CPOLact = CPOL_ACT_None;
      simEntStat.curCmd = AT_CMD_NONE;
      simEntStat.entOwn = simShrdPrm.owner = OWN_NONE;

      R_AT( RAT_CME, ownBuf /*simEntStat.entOwn*/ )
        (
          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;
  CHAR          *ef = EF_CLNG_ID;
  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;
        simEntStat.entOwn = simShrdPrm.owner = OWN_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);
      
      simEntStat.entOwn = simShrdPrm.owner = OWN_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);
            pcm_WriteFile (( UBYTE* )ef,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
      *-------------------------------------------------------------
      */
       cmhSIM_ReqLanguageLP (ownBuf );
       break;

     /*
      *-------------------------------------------------------------
      * read the EF LP if the EF ELP not available
      *-------------------------------------------------------------
      */
    case ( SIM_CAUSE_UNKN_FILE_ID ):
      cmhSIM_ReqLanguageLP (ownBuf );
      break;

    default:
      pSIMCmdPrm->CLANact = CLAN_ACT_None;
      simEntStat.entOwn = simShrdPrm.owner = OWN_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);

#ifdef _SIMULATION_
        memset(resp_data.lang, 0xA0, 2);
#endif

        psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );

      }
      else
      {
        /*
        *-------------------------------------------------------------
        * read the EF LP if the language is not supported in PCM
        *-------------------------------------------------------------
        */
        if (cmhSIM_ReqLanguagePrfLP () 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 ):
      if (cmhSIM_ReqLanguagePrfLP () 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;
  CHAR*           ef = EF_CLNG_ID;
  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=(UBYTE )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                                            )
  {
    
    simEntStat.entOwn = simShrdPrm.owner = OWN_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)

     {
        simEntStat.entOwn = simShrdPrm.owner = OWN_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);
           pcm_WriteFile (( UBYTE* )ef,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;
      simEntStat.entOwn = simShrdPrm.owner = OWN_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=(UBYTE )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, (UBYTE* )simShrdPrm.atb[table_id].exchData, CLAN_CODE_LEN);
#ifdef _SIMULATION_
    memset(resp_data.lang, 0xA0, 2);
#endif
    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);
#ifdef _SIMULATION_
      memset(resp_data.lang, 0xA0, 2);
#endif
      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 )
{
  UBYTE 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, -1, -1 );
          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, -1, err );
      break;
  }
}
#endif /*FF_DUAL_SIM*/

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