/*
+-----------------------------------------------------------------------------
|  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 ========================================================*/

