view src/aci2/aci/cmh_simf.c @ 362:4c3d05866531

FCHG: beginning of the new version
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 29 Dec 2017 07:06:06 +0000
parents 93999a60b835
children
line wrap: on
line source

/*  
+-----------------------------------------------------------------------------
|  Project :  GSM-PS (6147)
|  Modul   :  CMH_SIMF
+-----------------------------------------------------------------------------
|  Copyright 2002 Texas Instruments Berlin, AG
|                 All rights reserved.
|
|                 This file is confidential and a trade secret of Texas
|                 Instruments Berlin, AG
|                 The receipt of or possession of this file does not convey
|                 any rights to reproduce or disclose its contents or to
|                 manufacture, use, or sell anything it may describe, in
|                 whole, or in part, without the specific written consent of
|                 Texas Instruments Berlin, AG.
+-----------------------------------------------------------------------------
|  Purpose :  This module defines the functions used by the commad
|             handler for the subscriber identity module.
+-----------------------------------------------------------------------------
*/

#ifndef CMH_SIMF_C
#define CMH_SIMF_C
#endif

#include "aci_all.h"
/*==== INCLUDES ===================================================*/
#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_cmd.h"
#include "pcm.h"

#ifdef DTI
#include "dti.h"
#include "dti_conn_mng.h"
#endif

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

#include "aci.h"
#include "psa.h"
#include "psa_sim.h"
#include "psa_cc.h"
#include "psa_sat.h"
#include "psa_mm.h"
#include "psa_util.h"
#include "cmh.h"
#include "cmh_sim.h"
#include "cmh_mm.h"
#include "phb.h"
#ifdef SIM_PERS
#include "aci_ext_pers.h"
#include "aci_slock.h"
#include "general.h"  // inluded for UINT8 compilation error in sec_drv.h
#include "sec_drv.h"

 EXTERN  T_ACI_SIM_CONFIG aci_slock_sim_config;
 EXTERN T_SEC_DRV_CONFIGURATION *cfg_data;
#endif

EXTERN T_SIM_MMI_INSERT_IND *last_sim_mmi_insert_ind;
/* #include "m_cc.h" */

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

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

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

/*==== VARIABLES ==================================================*/
const UBYTE PLMNselEmpty[] = { 0xFF, 0xFF, 0xFF };
#ifdef SIM_PERS_OTA
UBYTE nw_ctrl_key[9], nw_subset_ctrl_key[9], sp_ctrl_key[9], corp_ctrl_key[9];
#define MAX_DCK_LEN 16 
#endif

/*==== FUNCTIONS ==================================================*/
void cmhSIM_Read_AD_cb(SHORT table_id);
void cmhSIM_Get_CSP_cb(SHORT table_id);
void cmhSIM_Read_CSP_cb(SHORT table_id);
#ifdef SIM_PERS_OTA
void cmhSIM_Read_DCK_cb(SHORT table_id);
void cmhSIM_Read_DCK_init_cb(SHORT table_id);
void cmhSIM_WriteDefaultValue_DCK_cb(SHORT table_id);
#endif
/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIM                 |
|                                 ROUTINE : cmhSIM_FillInPIN        |
+-------------------------------------------------------------------+

  PURPOSE : fill in the PIN into the PIN field of size length and
            stuff unused chars with 0xFF.

*/

GLOBAL void cmhSIM_FillInPIN ( CHAR * PINStr, CHAR * PINFld, UBYTE len )
{
  UBYTE idx;

  strncpy( PINFld, PINStr, len );

  for( idx = strlen( PINStr ); idx < len; idx++ )
  {
    PINFld[idx] = NOT_PRESENT_CHAR;
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIM                 |
|                                 ROUTINE : cmhSIM_GetHomePLMN      |
+-------------------------------------------------------------------+

  PURPOSE : Extract home PLMN out of the IMSI.

*/

GLOBAL void cmhSIM_GetHomePLMN ( SHORT * mccBuf, SHORT * mncBuf )
{
  UBYTE digit;        /* holds 4bit digit */
  UBYTE i;            /* holds counter */

  if( simShrdPrm.imsi.c_field EQ 0 )
  {
    /*
     * No SIM present
     */
    *mccBuf = *mncBuf = -1;
  }
  else
  {
    /*
     * SIM present
     */
    *mccBuf = *mncBuf = 0;

    /* Convert MCC and MNC. */
    for (i = 0; i < SIZE_MCC + SIZE_MNC; i++)
    {
      digit = (i & 1) ?
        (simShrdPrm.imsi.field[(i + 1)/2] & 0x0f) :
        (simShrdPrm.imsi.field[(i + 1)/2] & 0xf0) >> 4;
      if (i < SIZE_MCC)
        *mccBuf = (*mccBuf << 4) | digit;
      else
        *mncBuf = (*mncBuf << 4) | digit;
    }
    /* The only 3 digit mnc codes that are valid are the values between 310 and 316 */
    if ((*mccBuf >= 0x310) AND (*mccBuf <= 0x316)
        OR  simShrdPrm.mnc_len EQ 3)
    {
      /* used in the US - mcc = 0x310 */
    }
    /* Set the third digit of the MNC to 'F' if the SIM indicates a 2-digit MNC country */
    else /* if (simShrdPrm.mnc_len EQ 2) */
    {
      /* The MS digit of the mnc is not valid, so replace the LSB it with 0xF. */
      *mncBuf |= 0x00F;
    }
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MM                  |
|                                 ROUTINE : cmhSIM_plmn_equal_sim   |
+-------------------------------------------------------------------+

  PURPOSE : Return TRUE if the PLMN received equals the PLMN 
            stored on the SIM.
            This is not exactly the algorithm as shown for HPLMN 
            matching as shown in 03.22 Normative Annex A, this version
            here is more universal.            

*/

GLOBAL BOOL cmhSIM_plmn_equal_sim (SHORT bcch_mcc, SHORT bcch_mnc, 
                                   SHORT  sim_mcc, SHORT  sim_mnc)
{
  /*TRACE_FUNCTION ("cmhSIM_plmn_equal_sim()");*/

  /* Check MCC */
  if (sim_mcc NEQ bcch_mcc)
    return FALSE;

  /* Check first 2 MNC digits */
  if ((sim_mnc & 0xff0) NEQ (bcch_mnc & 0xff0))
    return FALSE;

  /* Check for full match */
  if ((sim_mnc & 0xf) EQ (bcch_mnc & 0xf))
    return TRUE;

  /* The 3rd digit of the MNC differs */
  if ((bcch_mcc >= 0x310) AND (bcch_mcc <= 0x316)
      OR simShrdPrm.mnc_len EQ 3)
  {
    /* 
     * The MCC is in the range 310..316, this means North America.
     * The zero suffix rule applies.
     */
    return ((((sim_mnc & 0xf) EQ 0xf) AND ((bcch_mnc & 0xf) EQ 0x0)) OR
            (((sim_mnc & 0xf) EQ 0x0) AND ((bcch_mnc & 0xf) EQ 0xf)));
  }
  return ((bcch_mnc & 0xf) EQ 0xf);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_MM                  |
|                                 ROUTINE : cmhSIM_plmn_is_hplmn    |
+-------------------------------------------------------------------+

  PURPOSE : Return TRUE if the PLMN received is the HPLMN, otherwise
            return FALSE.

*/

GLOBAL BOOL cmhSIM_plmn_is_hplmn (SHORT bcch_mcc, SHORT bcch_mnc)
{
  SHORT sim_mcc;              /* Holds the MCC of the HPLMN from the SIM */
  SHORT sim_mnc;              /* Holds the MNC of the HPLMN from the SIM */

  TRACE_FUNCTION ("cmhSIM_plmn_is_hplmn()");

  if(!cmhMM_GetActingHPLMN(&sim_mcc, &sim_mnc))/*Enhancement Acting HPLMN*/
  {
    /* Extract the HPLMN identification out of the IMSI digits. */
    cmhSIM_GetHomePLMN (&sim_mcc, &sim_mnc);
  }

  return cmhSIM_plmn_equal_sim (bcch_mcc, bcch_mnc, sim_mcc, sim_mnc);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIM                 |
|                                 ROUTINE : cmhSIM_GetCmeFromSim    |
+-------------------------------------------------------------------+

  PURPOSE : Mapping of SIM error code to ACI error code.

*/
GLOBAL T_ACI_CME_ERR cmhSIM_GetCmeFromSim ( USHORT errCode )
{
  switch ( errCode )
  {
    case SIM_NO_ERROR:
      return CME_ERR_NotPresent;

    case SIM_CAUSE_PIN1_EXPECT:
      return CME_ERR_SimPinReq;

    case SIM_CAUSE_PIN2_EXPECT:
      return CME_ERR_SimPin2Req;

    case SIM_CAUSE_PUK1_EXPECT:
      return CME_ERR_WrongPasswd;
    case SIM_CAUSE_PIN1_BLOCKED:
      return CME_ERR_SimPukReq;

    case SIM_CAUSE_PUK2_EXPECT:
      return CME_ERR_WrongPasswd;
    case SIM_CAUSE_PIN2_BLOCKED:
      return CME_ERR_SimPuk2Req;

    case SIM_CAUSE_PUK1_BLOCKED:
    case SIM_CAUSE_PUK2_BLOCKED:
      return CME_ERR_SimWrong;

    case SIM_CAUSE_NO_SELECT:
    case SIM_CAUSE_UNKN_FILE_ID:
      return CME_ERR_NotFound;

    case SIM_CAUSE_EF_INVALID:
      return CME_ERR_OpNotSupp;

    case SIM_CAUSE_ADDR_WRONG:
      return CME_ERR_InvIdx;

    case SIM_CAUSE_CMD_INCONSIST:
    case SIM_CAUSE_MAX_INCREASE:
    case SIM_CAUSE_CHV_NOTSET:
    case SIM_CAUSE_CHV_VALIDATED:
      return CME_ERR_OpNotAllow;

    case SIM_CAUSE_ACCESS_PROHIBIT:
      return CME_ERR_WrongPasswd;

    case SIM_CAUSE_CARD_REMOVED:
    case SIM_CAUSE_DRV_NOCARD:
      return CME_ERR_SimNotIns;

    case SIM_CAUSE_CLA_WRONG:
    case SIM_CAUSE_INS_WRONG:
    case SIM_CAUSE_P1P2_WRONG:
    case SIM_CAUSE_P3_WRONG:
    case SIM_CAUSE_PARAM_WRONG:
      return CME_ERR_PhoneFail;

    case SIM_CAUSE_SAT_BUSY:
      return CME_ERR_SimBusy;

    case SIM_CAUSE_DNL_ERROR:
      return CME_ERR_Unknown;

    case SIM_CAUSE_DRV_TEMPFAIL:
      return CME_ERR_SimFail;

    default:
      if (GET_CAUSE_DEFBY(errCode) EQ DEFBY_CONDAT AND
          GET_CAUSE_ORIGSIDE(errCode) EQ ORIGSIDE_MS)
      {
        return CME_ERR_Unknown;
      }
      return CME_ERR_Unknown;
  }
}

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

  PURPOSE :
*/
GLOBAL T_ACI_BS_SPEED cmhSIM_GetUserRate ( UBYTE userRate )
{
  switch( userRate )
  {
    case ( UR_0_3_KBIT        ): return BS_SPEED_300_V110;
    case ( UR_1_2_KBIT        ): return BS_SPEED_1200_V110;
    case ( UR_2_4_KBIT        ): return BS_SPEED_2400_V110;
    case ( UR_4_8_KBIT        ): return BS_SPEED_4800_V110;
    case ( UR_9_6_KBIT        ): return BS_SPEED_9600_V110;
    case ( UR_1_2_KBIT_V23    ): return BS_SPEED_1200_75_V23;
    case ( UR_12_0_KBIT_TRANS ):
    default:                     return BS_SPEED_NotPresent;
  }
}

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

  PURPOSE :
*/
GLOBAL T_ACI_CNUM_SERV cmhSIM_GetSrvFromSync ( UBYTE sync )
{
  switch( sync )
  {
    case ( ASYNCHRONOUS ): return CNUM_SERV_Asynch;
    case ( SYNCHRONOUS  ): return CNUM_SERV_Synch;
    default:               return CNUM_SERV_NotPresent;
  }
}

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

  PURPOSE :
*/
GLOBAL T_ACI_CNUM_SERV cmhSIM_GetSrvFromItc ( UBYTE itc )
{
  switch( itc )
  {
    case ( ITC_SPEECH      ): return CNUM_SERV_Voice;
    case ( ITC_FAX_GROUP_3 ): return CNUM_SERV_Fax;
    default:                  return CNUM_SERV_NotPresent;
  }
}

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

  PURPOSE :
*/
GLOBAL T_ACI_CNUM_ITC cmhSIM_GetItc ( UBYTE itc )
{
  switch( itc )
  {
    case ( ITC_DIGITAL_UNRESTRICTED ): return CNUM_ITC_Udi;
    case ( ITC_AUDIO                ): return CNUM_ITC_3_1_kHz;
    default:                           return CNUM_ITC_NotPresent;
  }
}

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

  PURPOSE : get MNC and MCC out of EF PLMNsel entry
*/

GLOBAL void cmhSIM_getMncMccFrmPLMNsel(const UBYTE *ntry,
                                             SHORT *mcc,
                                             SHORT *mnc )
{
  if (memcmp (ntry, PLMNselEmpty, sizeof(PLMNselEmpty)) EQ 0)
  {
    *mcc = *mnc = -1;
  }
  else
  {
    *mcc  = ( ntry[0]       & 0x0f) << 8;
    *mcc |= ((ntry[0] >> 4) & 0x0f) << 4;
    *mcc |= ( ntry[1]       & 0x0f);
    *mnc  = ( ntry[2]       & 0x0f) << 8;
    *mnc |= ((ntry[2] >> 4) & 0x0f) << 4;
    *mnc |= ((ntry[1] >> 4) & 0x0f);
  }
}

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

  PURPOSE : Code MNC and MCC according a EF PLMNsel entry
*/

GLOBAL BOOL cmhSIM_GetCodedPLMN( const CHAR *oper, T_ACI_CPOL_FRMT format,
                                 UBYTE *sim_plmn )
{
  T_OPER_ENTRY operDesc;     /* operator description */
  BOOL found;

  /* get MNC and MCC */
  switch( format )
  {
    case( CPOL_FRMT_Long ):
      found = cmhMM_FindName( &operDesc, oper, COPS_FRMT_Long );
      break;
    case( CPOL_FRMT_Short ):
      found = cmhMM_FindName( &operDesc, oper, COPS_FRMT_Short );
      break;
    case( CPOL_FRMT_Numeric ):
      found = cmhMM_FindNumeric( &operDesc, oper );
      break;
    default:
      return( FALSE );
  }

  if( !found )
    return( FALSE );

  /* code MCC and MNC */
  sim_plmn[0]  = (operDesc.mcc & 0xf00) >> 8;
  sim_plmn[0] |= (operDesc.mcc & 0x0f0)     ;
  sim_plmn[1]  = (operDesc.mcc & 0x00f)     ;
  sim_plmn[1] |= (operDesc.mnc & 0x00f) << 4;
  sim_plmn[2]  = (operDesc.mnc & 0xf00) >> 8;
  sim_plmn[2] |= (operDesc.mnc & 0x0f0)     ;

  return( TRUE );
}

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

  PURPOSE : Fills in the CPOL list out of EF PLMNsel and returns the
            last written index.
*/
GLOBAL SHORT cmhSIM_FillPlmnSelList ( UBYTE              index,
                                      T_ACI_CPOL_FRMT    frmt,
                                      T_ACI_CPOL_OPDESC* operLst,
                                      UBYTE              length,
                                      UBYTE*             pData   )
{
  BOOL  found;            /* cmhMM_FindXXX found an entry */
  UBYTE idx;              /* holds list index */
  SHORT off;              /* holds PLMNsel offset */
  SHORT lastIdx;          /* holds last index written to list */
  SHORT mcc;              /* holds mcc value */
  SHORT mnc;              /* holds mnc value */
  T_OPER_ENTRY OpDsc;     /* operator description */

/*
 *-----------------------------------------------------------------
 * calculate PLMNsel offset
 *-----------------------------------------------------------------
 */
  off = (index-1) * ACI_LEN_PLMN_SEL_NTRY;

/*
 *-----------------------------------------------------------------
 * fill the preferred operator list
 *-----------------------------------------------------------------
 */
  idx = 0;
  lastIdx = ACI_NumParmNotPresent;

  do
  {
    /* get mnc and mcc out of PLMNsel field */
    cmhSIM_getMncMccFrmPLMNsel( (pData+off), &mcc, & mnc );

    /* end of PLMNsel field */
    if( off >= length )
    {
      operLst[idx].index   = ACI_NumParmNotPresent;
      operLst[idx].format  = CPOL_FRMT_NotPresent;
      operLst[idx].oper[0] = 0x0;
      break;
    }

    /* valid entry */
    if( !(mcc < 0 AND mnc < 0) )
    {
      operLst[idx].index  = index;
      operLst[idx].format = frmt;

      found = cmhMM_FindPLMN( &OpDsc, mcc, mnc, NOT_PRESENT_16BIT, FALSE);

      switch( frmt )
      {
        case( CPOL_FRMT_Long ):
          if (OpDsc.pnn)
          {
            if (OpDsc.long_len)
            {
              switch (OpDsc.long_ext_dcs>>4 & 0x07)
              {
                case 0x00:
                  utl_cvtPnn7To8((UBYTE *)OpDsc.longName,
                                          OpDsc.long_len,
                                          OpDsc.long_ext_dcs,
                                 (UBYTE *)operLst[idx].oper);
                  break;
                case 0x01:
                  TRACE_ERROR ("ERROR: Unhandled UCS2");
                  break;
                default:
                  TRACE_ERROR ("ERROR: Unknown DCS");
                  break;
              }
            }
            else
            {
              operLst[idx].oper[0] = '\0';
            }
          }
          else
          {
            /* MAX_LONG_OPER_LEN <= MAX_ALPHA_OPER_LEN, no length check needed */
            strcpy( operLst[idx].oper, OpDsc.longName );
          } 
          break;

        case( CPOL_FRMT_Short ):
          if (OpDsc.pnn)
          {
            if (OpDsc.shrt_len)
            {
              switch (OpDsc.shrt_ext_dcs>>4 & 0x07)
              {
                case 0x00:
                  utl_cvtPnn7To8((UBYTE *)OpDsc.shrtName,
                                          OpDsc.shrt_len,
                                          OpDsc.shrt_ext_dcs,
                                 (UBYTE *)operLst[idx].oper);
                  break;
                case 0x01:
                  TRACE_ERROR ("ERROR: Unhandled UCS2");
                  break;
                default:
                  TRACE_ERROR ("ERROR: Unknown DCS");
                  break;
              }
            }
            else
            {
              operLst[idx].oper[0] = '\0';
            }
          }
          else
          {
            /* MAX_SHRT_OPER_LEN <= MAX_ALPHA_OPER_LEN, no length check needed */
            strcpy( operLst[idx].oper, OpDsc.shrtName );
          }
          break;

        case( CPOL_FRMT_Numeric ):
          if ((mnc & 0x00F) EQ 0xF)
            sprintf (operLst[idx].oper, "%03X%02X", mcc, (mnc & 0xff0) >> 4);
          else
            sprintf (operLst[idx].oper, "%03X%03X", mcc, mnc);
          break;
      }
      idx++;
      lastIdx = index;
    }

    off += ACI_LEN_PLMN_SEL_NTRY;
    index++;

  } while( idx < MAX_OPER );

  return( lastIdx );
}

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

  PURPOSE : Counts the used entries of the preferred PLMN list and
            returns the number of used entries.
*/
GLOBAL SHORT cmhSIM_UsdPlmnSelNtry ( UBYTE              length,
                                     UBYTE*             pData   )
{
  UBYTE idx;              /* holds list index */
  SHORT off;              /* holds PLMNsel offset */
  UBYTE maxNtry;          /* holds the maximum number of entries */
  SHORT used;             /* holds number of used entries */
  SHORT mcc;              /* holds mcc value */
  SHORT mnc;              /* holds mnc value */

/*
 *-----------------------------------------------------------------
 * count the used entries
 *-----------------------------------------------------------------
 */
  maxNtry = length / ACI_LEN_PLMN_SEL_NTRY;

  for( idx = 0, used = 0, off = 0;
       idx < maxNtry;
       idx++, off += ACI_LEN_PLMN_SEL_NTRY )
  {
    /* get mnc and mcc out of PLMNsel field */
    cmhSIM_getMncMccFrmPLMNsel( (pData+off), &mcc, & mnc );

    /* valid entry */
    if( !(mcc < 0 AND mnc < 0) )
    {
      used++;
    }
  }

  return( used );
}

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

  PURPOSE : Shoves entries of preferred PLMN list to remove empty
            entries of the list.
*/
GLOBAL void cmhSIM_CmpctPlmnSel ( UBYTE length, UBYTE* pData )
{
  UBYTE  maxNtry;          /* holds the maximum number of entries */
  UBYTE  lstIdx;           /* holds list index */
  UBYTE* dstNtry;          /* points to destination entry index */

/*
 *-----------------------------------------------------------------
 * compact the list
 *-----------------------------------------------------------------
 */
  lstIdx  = 0;
  dstNtry = pData;

  maxNtry = length / ACI_LEN_PLMN_SEL_NTRY;

  while( lstIdx < maxNtry )
  {
    if(memcmp( pData, PLMNselEmpty, sizeof(PLMNselEmpty)))
    {
      if( pData NEQ dstNtry )
      {
        memcpy( dstNtry, pData, ACI_LEN_PLMN_SEL_NTRY );
        memcpy( pData, PLMNselEmpty, ACI_LEN_PLMN_SEL_NTRY);
      }
      dstNtry += ACI_LEN_PLMN_SEL_NTRY;
    }
    lstIdx++;
    pData += ACI_LEN_PLMN_SEL_NTRY;
  }
}

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

  PURPOSE : This function starts reading of EF PLMN SEL from SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_ReqPlmnSel ( T_ACI_CMD_SRC srcId )
{
  T_ACI_RETURN ret       = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_ReqPlmnSel()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = SIM_PLMNSEL;
    simShrdPrm.atb[table_id].dataOff      = 0;
    /* length is variable */
    simShrdPrm.atb[table_id].dataLen      = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax       = ACI_LEN_PLMN_SEL_FLD;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = CPOLSimEfData;
    simShrdPrm.atb[table_id].rplyCB       = cmhSIM_RdCnfPlmnSel;

    simShrdPrm.aId = table_id;

    simEntStat.curCmd = AT_CMD_CPOL;
    simEntStat.entOwn = simShrdPrm.owner = srcId;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM in +CPOL");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}

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

  PURPOSE : This function updates the indexed EF PLMN SEL entry and
            writes the field to the SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_UpdPlmnSel ( T_ACI_CMD_SRC srcId,
                                        SHORT index,
                                        UBYTE *plmn,
                                        T_ACI_CPOL_MOD mode )
{
  SHORT off;      /* holds EF offset */
  SHORT cpyOff;   /* holds offset for copy operation */
  UBYTE maxIdx;   /* holds maximum number of index */

  TRACE_FUNCTION ("cmhSIM_UpdPlmnSel()");

/*
 *-----------------------------------------------------------------
 * update EF PLMNsel RAM copy
 *-----------------------------------------------------------------
 */
  maxIdx = CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY;

  off = (index-1) * ACI_LEN_PLMN_SEL_NTRY;

  if( mode EQ CPOL_MOD_Insert AND index < maxIdx )
  {
    cmhSIM_CmpctPlmnSel ( CPOLSimEfDataLen, CPOLSimEfData );

    cpyOff = (maxIdx-1) * ACI_LEN_PLMN_SEL_NTRY;

    cpyOff -= ACI_LEN_PLMN_SEL_NTRY;  /* need not copy since last index will fall out of list! */

    while( cpyOff >= off AND cpyOff >= 0 )
    {
      memcpy( CPOLSimEfData+cpyOff+ACI_LEN_PLMN_SEL_NTRY,
              CPOLSimEfData+cpyOff, ACI_LEN_PLMN_SEL_NTRY );

      cpyOff -= ACI_LEN_PLMN_SEL_NTRY;
    }
  }

  memcpy( CPOLSimEfData+off, plmn, ACI_LEN_PLMN_SEL_NTRY );

  return ( cmhSIM_WritePlmnSel( srcId ));
}

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

  PURPOSE : This function searches for an empty entry in EF PLMN SEL,
            fills it and writes the field to the SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_FndEmptyPlmnSel ( T_ACI_CMD_SRC srcId,
                                             UBYTE *plmn )
{
  UBYTE maxNtry;  /* holds maximum number of entries */
  SHORT off;      /* holds EF offset */

  TRACE_FUNCTION ("cmhSIM_FndEmptyPlmnSel()");

/*
 *-----------------------------------------------------------------
 * search for an empty entry, and update
 *-----------------------------------------------------------------
 */
  maxNtry = CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY;

  for( off = 0; maxNtry > 0; off += ACI_LEN_PLMN_SEL_NTRY, maxNtry-- )
  {
    if( !memcmp( CPOLSimEfData+off, PLMNselEmpty,
                 ACI_LEN_PLMN_SEL_NTRY ))
    {
      memcpy( CPOLSimEfData+off, plmn, ACI_LEN_PLMN_SEL_NTRY );

      return ( cmhSIM_WritePlmnSel( srcId ));
    }
  }

  ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFull );
  return( AT_FAIL );
}

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

  PURPOSE : This function updates the indexed EF PLMN SEL entry and
            writes the field to the SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_DelPlmnSel ( T_ACI_CMD_SRC srcId,
                                        SHORT index,
                                        T_ACI_CPOL_MOD mode )
{
  SHORT off;      /* holds EF offset */

  TRACE_FUNCTION ("cmhSIM_DelPlmnSel()");

/*
 *-----------------------------------------------------------------
 * delete entry in EF PLMNsel RAM copy
 *-----------------------------------------------------------------
 */

  off = (index-1) * ACI_LEN_PLMN_SEL_NTRY;

  memcpy( CPOLSimEfData+off, PLMNselEmpty, ACI_LEN_PLMN_SEL_NTRY );

  if( mode EQ CPOL_MOD_CompactList )

    cmhSIM_CmpctPlmnSel ( CPOLSimEfDataLen, CPOLSimEfData );

  return ( cmhSIM_WritePlmnSel( srcId ));
}

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

  PURPOSE : This function exchanges the indexed EF PLMN SEL entries and
            writes the field to the SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_ChgPlmnSel ( T_ACI_CMD_SRC srcId,
                                        SHORT index,
                                        SHORT index2 )
{
  SHORT off1, off2;                   /* holds EF offset */
  UBYTE plmn1[ACI_LEN_PLMN_SEL_NTRY]; /* buffers PLMN 1 */
  UBYTE plmn2[ACI_LEN_PLMN_SEL_NTRY]; /* buffers PLMN 2 */

  TRACE_FUNCTION ("cmhSIM_ChgPlmnSel()");

/*
 *-----------------------------------------------------------------
 * change entries in EF PLMNsel RAM copy
 *-----------------------------------------------------------------
 */

  off1 = (index-1)  * ACI_LEN_PLMN_SEL_NTRY;
  off2 = (index2-1) * ACI_LEN_PLMN_SEL_NTRY;

  memcpy( plmn1, CPOLSimEfData+off1, ACI_LEN_PLMN_SEL_NTRY );
  memcpy( plmn2, CPOLSimEfData+off2, ACI_LEN_PLMN_SEL_NTRY );

  memcpy( CPOLSimEfData+off1, plmn2, ACI_LEN_PLMN_SEL_NTRY );
  memcpy( CPOLSimEfData+off2, plmn1, ACI_LEN_PLMN_SEL_NTRY );

  return ( cmhSIM_WritePlmnSel( srcId ));
}

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

  PURPOSE : This function starts writing of EF PLMN SEL to SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_WritePlmnSel ( T_ACI_CMD_SRC srcId )
{
  T_ACI_RETURN ret = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_WritePlmnSel()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_WR_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = SIM_PLMNSEL;
    simShrdPrm.atb[table_id].dataOff      = 0;
    /* length is variable */
    simShrdPrm.atb[table_id].dataLen      = CPOLSimEfDataLen;
    simShrdPrm.atb[table_id].recMax       = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = CPOLSimEfData;
    simShrdPrm.atb[table_id].rplyCB       = cmhSIM_WrCnfPlmnSel;

    simShrdPrm.aId = table_id;

    simEntStat.curCmd = AT_CMD_CPOL;
    simEntStat.entOwn = simShrdPrm.owner = srcId;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM in +CPOL");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}

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

  PURPOSE : This function starts writing of a transparent EF to SIM.
            (SIM only busy with valid 'srcId')
*/
GLOBAL T_ACI_RETURN cmhSIM_WriteTranspEF (T_ACI_CMD_SRC srcId,
                                          T_ACI_AT_CMD  cmd,
                                          USHORT        datafield,
                                          USHORT        offset,
                                          UBYTE         datalen,
                                          UBYTE       * exchData,
                                          void      (*rplyCB)(SHORT))
{
  T_ACI_RETURN ret = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_WriteTranspEF()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_WR_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = datafield;
    simShrdPrm.atb[table_id].dataOff      = offset;
    simShrdPrm.atb[table_id].recNr        = 0;
    simShrdPrm.atb[table_id].dataLen      = datalen;
    simShrdPrm.atb[table_id].recMax       = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = exchData;
    simShrdPrm.atb[table_id].rplyCB       = rplyCB;

    simShrdPrm.aId = table_id;

    if (srcId NEQ CMD_SRC_NONE)
    {
      simEntStat.curCmd = cmd;
      simEntStat.entOwn = simShrdPrm.owner = srcId;
    }
    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}

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

  PURPOSE : This function starts reading of EF PLMN SEL from SIM.
            (SIM only busy with valid 'srcId')
*/
GLOBAL T_ACI_RETURN cmhSIM_ReadTranspEF ( T_ACI_CMD_SRC srcId,
                                          T_ACI_AT_CMD  cmd,
                                          USHORT        datafield,
                                          USHORT        offset,
                                          UBYTE         explen,
                                          UBYTE       * exchData,
                                          void      (*rplyCB)(SHORT))
{
  T_ACI_RETURN ret       = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_ReadTranspEF()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = datafield;
    simShrdPrm.atb[table_id].dataOff      = offset;
    simShrdPrm.atb[table_id].recNr        = 0;
    simShrdPrm.atb[table_id].dataLen      = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax       = explen;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = exchData;
    simShrdPrm.atb[table_id].rplyCB       = rplyCB;

    simShrdPrm.aId = table_id;

    if (srcId NEQ CMD_SRC_NONE)
    {
      simEntStat.curCmd = cmd;
      simEntStat.entOwn = simShrdPrm.owner = srcId;
    }
    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}

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

  PURPOSE : This function starts writing of a transparent EF to SIM.
            (SIM only busy with valid 'srcId')
*/
GLOBAL T_ACI_RETURN cmhSIM_WriteRecordEF (T_ACI_CMD_SRC srcId,
                                          T_ACI_AT_CMD  cmd,
                                          USHORT        datafield,
                                          UBYTE         record,
                                          UBYTE         datalen,
                                          UBYTE       * exchData,
                                          void      (*rplyCB)(SHORT))
{
  T_ACI_RETURN ret = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_WriteRecordEF()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_WR_REC;
    simShrdPrm.atb[table_id].reqDataFld   = datafield;
    simShrdPrm.atb[table_id].dataOff      = 0;
    simShrdPrm.atb[table_id].dataLen      = datalen;
    simShrdPrm.atb[table_id].recNr        = record;
    simShrdPrm.atb[table_id].recMax       = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = exchData;
    simShrdPrm.atb[table_id].rplyCB       = rplyCB;

    simShrdPrm.aId = table_id;

    if (srcId NEQ CMD_SRC_NONE)
    {
      simEntStat.curCmd = cmd;
      simEntStat.entOwn = simShrdPrm.owner = srcId;
    }
    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}

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

  PURPOSE : This function starts reading of EF PLMN SEL from SIM.
            (SIM only busy with valid 'srcId')
*/
GLOBAL T_ACI_RETURN cmhSIM_ReadRecordEF ( T_ACI_CMD_SRC srcId,
                                          T_ACI_AT_CMD  cmd,
                                          USHORT        datafield,
                                          UBYTE         record,
                                          UBYTE         explen,
                                          UBYTE       * exchData,
                                          void      (*rplyCB)(SHORT))
{
  T_ACI_RETURN ret       = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_ReadRecordEF()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_REC;
    simShrdPrm.atb[table_id].reqDataFld   = datafield;
    simShrdPrm.atb[table_id].dataOff      = 0;
    simShrdPrm.atb[table_id].recNr        = record;
    /* for CPHS (and this shall probably be extended to other SIM
    access operations) dataLen passed in SIM_READ_RECORD_REQ should
    be NOT_PRESENT_8BIT (to let the SIM entity handling this length:
    ACI does not know it anyway...). Yet size of received data should
    be checked when conf is received (to avoid crashes with exotic SIM cards */
#ifdef FF_CPHS
    if(cmd EQ AT_CMD_CPHS)
    {
      simShrdPrm.atb[table_id].check_dataLen = TRUE;
    }
#endif /* FF_CPHS */
    simShrdPrm.atb[table_id].dataLen      = explen;
    simShrdPrm.atb[table_id].recMax       = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = exchData;
    simShrdPrm.atb[table_id].rplyCB       = rplyCB;

    simShrdPrm.aId = table_id;

    if (srcId NEQ CMD_SRC_NONE)
    {
      simEntStat.curCmd = cmd;
      simEntStat.entOwn = simShrdPrm.owner = srcId;
    }
    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}

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

  PURPOSE : sync_notification: TRUE if notification through asynchrone callback
                               FALSE if notif. whithin synchrone context.

*/
#define GetSIMError (1)
#define CheckSimStatus (0)

LOCAL T_ACI_RETURN SimStatusError ( T_ACI_CMD_SRC srcBuf,
                                    T_ACI_AT_CMD  cmdBuf,
                                    UBYTE         sync_notification)
{
  T_ACI_CPIN_RSLT code = CPIN_RSLT_NotPresent;
  T_ACI_CME_ERR   err  = CME_ERR_NotPresent;

  /* trace if needed... TRACE_EVENT_P1("simShrdPrm.SIMStat: %d", simShrdPrm.SIMStat); */

  switch( simShrdPrm.SIMStat )
  {
    case( SS_OK ):
      if ( qAT_PlusCPIN(CMD_SRC_LCL, &code) EQ AT_CMPL )
      {
        switch ( code )
        {
          case CPIN_RSLT_PhSimPinReq:
            err = CME_ERR_PhSimPinReq;
            break;
          case CPIN_RSLT_SimPinReq:
            err = CME_ERR_SimPinReq;
            break;
          case CPIN_RSLT_SimPin2Req:
            err = CME_ERR_SimPin2Req;
            break;
          case(CPIN_RSLT_PhFSimPinReq): 
            err = CME_ERR_PhFSimPinReq;
            break;
          case(CPIN_RSLT_PhFSimPukReq): 
            err = CME_ERR_PhFSimPukReq;
            break;
          case(CPIN_RSLT_PhNetPinReq): 
            err = CME_ERR_NetworkPersPinReq;
            break;
          case(CPIN_RSLT_PhNetPukReq): 
            err = CME_ERR_NetworkPersPukReq;
            break;
          case(CPIN_RSLT_PhNetSubPinReq): 
            err = CME_ERR_NetworkSubsetPersPinReq;
            break;
          case(CPIN_RSLT_PhNetSubPukReq):
            err = CME_ERR_NetworkSubsetPersPukReq;
            break;
          case(CPIN_RSLT_PhSPPinReq): 
            err = CME_ERR_ProviderPersPinReq;
            break;
          case(CPIN_RSLT_PhSPPukReq): 
            err = CME_ERR_ProviderPersPukReq;
            break;
          case(CPIN_RSLT_PhCorpPinReq):
            err = CME_ERR_CorporatePersPinReq;
            break;
          case(CPIN_RSLT_PhCorpPukReq):
            err = CME_ERR_CorporatePersPukReq;
            break;

        }
      }
      break;

    case( SS_BLKD ):
      if ( qAT_PlusCPIN(CMD_SRC_LCL, &code) EQ AT_CMPL )
      {
        switch ( code )
        {
          case CPIN_RSLT_SimPukReq:
            err = CME_ERR_SimPukReq;
            break;
          case CPIN_RSLT_SimPuk2Req:
            err = CME_ERR_SimPuk2Req;
            break;
        }
      }
      break;

    case( SS_INV ):
      err = CME_ERR_SimWrong;
      break;

    case( SS_URCHB ):
      err = CME_ERR_SimFail;
      break;

    default:            /* unexpected result */
      break;
  }

  if( err EQ CME_ERR_NotPresent )
  {
    return ( AT_FAIL );
  }
  else
  {
    TRACE_EVENT_P1("err: %d", err);
  }

  switch( sync_notification )
  {
  case( GetSIMError ):
    R_AT( RAT_CME, srcBuf ) ( cmdBuf, err );
    break;

  case( CheckSimStatus ):
    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, err );
    break;
  }
  return( AT_CMPL );
}

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

  PURPOSE : This function is used to request the SIM error status.

*/
GLOBAL T_ACI_RETURN cmhSIM_GetSIMError ( T_ACI_CMD_SRC srcBuf,
                                         T_ACI_AT_CMD cmdBuf )
{
  TRACE_FUNCTION("cmhSIM_GetSIMError");

  return(SimStatusError( srcBuf, cmdBuf,  GetSIMError ));
}

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

  PURPOSE : This function is used to check the SIM pin status.

*/
GLOBAL T_ACI_RETURN cmhSIM_CheckSimPinStatus ( T_ACI_CMD_SRC srcBuf,
                                               T_ACI_AT_CMD cmdBuf )
{
  TRACE_FUNCTION("cmhSIM_CheckSimPinStatus");

  return(SimStatusError( srcBuf, cmdBuf,  CheckSimStatus ));
}

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

  PURPOSE : This function starts reading of ELP field from SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_ReqLanguage  ( T_ACI_CMD_SRC srcId)

{
  T_ACI_RETURN ret = AT_FAIL;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_ReqLanguage()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = SIM_ELP;
    simShrdPrm.atb[table_id].dataOff      = 0;
    /* length is variable */
    simShrdPrm.atb[table_id].dataLen      = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax       = ACI_LEN_LAN_FLD;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = CLANSimEfData;
    simShrdPrm.atb[table_id].rplyCB       = cmhSIM_RdCnfLangELP;


    simShrdPrm.aId = table_id;

    simEntStat.curCmd = AT_CMD_CLAN;
    simEntStat.entOwn = simShrdPrm.owner = srcId;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM in +CLAN");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}


/*
+-----------------------------------------------------------------------+
| PROJECT :                             MODULE  : SAT                   |
| STATE   : code                        ROUTINE : cmhSIM_ReqLanguagePrf |
+-----------------------------------------------------------------------+

  PURPOSE : This function starts reading of ELP field from SIM for SAT feature LS.
*/
GLOBAL BOOL cmhSIM_ReqLanguagePrf(void)

{
  BOOL         ret = FALSE;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_ReqLanguagePrf()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = SIM_ELP;
    simShrdPrm.atb[table_id].dataOff      = 0;
    // length is variable
    simShrdPrm.atb[table_id].dataLen      = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax       = ACI_LEN_LAN_FLD;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = CLANSimEfData;
    simShrdPrm.atb[table_id].rplyCB       = cmhSIM_RdCnfLangPrfELP;


    simShrdPrm.aId = table_id;

    
    if(psaSIM_AccessSIMData() < 0)
    {
      return ( ret );      
    }
    else
    {
      ret = TRUE;
    }
  }

  return ( ret );
}



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

  PURPOSE : get Supported Language from PCM and compare it
            with Language table.
*/
GLOBAL T_ACI_RETURN getSupLangFromPCM ( T_ACI_LAN_SUP *lanlst, SHORT *lastIdx)

{
  CHAR              *ef = EF_MSSUP_ID;
  pcm_FileInfo_Type fileInfo;
  EF_MSSUP          mssup;
  LONG              value;
  SHORT             i, idx=0;
  LONG              bitmask = 0x01;

  TRACE_FUNCTION ("getSupLangFromPCM()");

/*
 *-------------------------------------------------------------------
 *   read supported language from ME
 *-------------------------------------------------------------------
 */if (pcm_GetFileInfo ( (UBYTE*)ef, &fileInfo) NEQ PCM_OK)
   {
     TRACE_EVENT("Error getting datas from PCM");
     ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFail );
     return( AT_FAIL );
   }
   else
   {
     if ( pcm_ReadFile ( ( UBYTE* )ef,fileInfo.FileSize,
                         ( UBYTE*) &mssup,
                         &fileInfo.Version) EQ PCM_OK )
     {
       value =mssup.lng1;
       value |=mssup.lng2 <<8;
       value |=mssup.lng3 <<16;

       for(i=0;i<MAX_LAN;i++)
       {
         if (bitmask & value)
         {
           lanlst[idx].lng =i;
           idx++;
         }

         bitmask= bitmask<< 1;
       }

     }
     else
     {
       ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFail );
       return( AT_FAIL );
     }
   }

/*
 *-------------------------------------------------------------------
 * terminate list and set last index
 *-------------------------------------------------------------------
 */
  if( idx < MAX_LAN )
  {
    lanlst[idx].str = 0x0;
    lanlst[idx].lng = 0x0;

  }
  *lastIdx = idx;

/*
 *-------------------------------------------------------------------
 *   compare the code of supported language in PCM with
 *   Language table to get the char code
 *-------------------------------------------------------------------
 */
  for(i=0;i < *lastIdx;i++)
  {
    idx=0;
    while (lngs[idx].str NEQ NULL AND
           lngs[idx].lng NEQ lanlst[i].lng)
      idx++;

    if (lngs[idx].lng EQ lanlst[i].lng)
      lanlst[i].str=lngs[idx].str;
  }

  return( AT_CMPL );
}


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

  PURPOSE : check if the language to be read from the EF ELP
            is supported in PCM

            SupLng: is true if the language is supprted else False
*/

GLOBAL BOOL checkSuppLang     (T_ACI_LAN_SUP   *lanlst,
                               SHORT           lastIdx,
                               T_ACI_LAN_SUP   *clng)
{
  USHORT i;
  BOOL   SupLng=FALSE;

/*
 *-----------------------------------------------------------------
 *  check if the Language from EF ELP is supported in PCM
 *-----------------------------------------------------------------
 */
  for(i=0;i < lastIdx;i++)
  {
    if (!strcmp(lanlst[i].str,clng->str) )
    {
      clng->lng=lanlst[i].lng;
      SupLng= TRUE;
      break;
    }
  }

  return( SupLng );
}

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

  PURPOSE : check if the language to be read from the EF LP
            is supported in PCM

            SupLng: is true if the language is supprted else False
*/

GLOBAL BOOL checkSuppLangInLP(T_ACI_LAN_SUP *lanlst,SHORT lastIdx,
                              T_ACI_LAN_SUP *clng)
{
  USHORT i;
  BOOL   SupLng=FALSE;

/*
 *-----------------------------------------------------------------
 *  check if the Language from EF LP is supported in PCM
 *-----------------------------------------------------------------
 */
  for(i=0;i < lastIdx;i++)
  {
    if (lanlst[i].lng EQ clng->lng )
    {
      clng->str=lanlst[i].str;
      SupLng= TRUE;
      break;
    }
  }

  return( SupLng );
}

#if 0
/*
+------------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)             MODULE  : CMH_SIMS                |
| STATE   : code                       ROUTINE : cmhSIM_LanguageLP_Update|
+------------------------------------------------------------------------+

  PURPOSE :
*/
GLOBAL BOOL cmhSIM_LanguageLP_Update  ( int ref, T_SIM_FILE_UPDATE_IND *fu)
{
  T_ACI_CMD_SRC ownBuf;     /* buffers current owner */
  UBYTE i;
  BOOL found = FALSE;

  char *auptr="au";
  CHAR *ef = EF_CLNG_ID;
  pcm_FileInfo_Type fileInfo;
  EF_CLNG lng;


  TRACE_FUNCTION ("cmhSIM_LanguageLP_Update()");

  ownBuf     = simEntStat.entOwn;

  for (i = 0; i < (int)fu->val_nr; i++)
  {
    if (!found AND
        (fu->file_id[i] EQ SIM_LP))
    {
      found = TRUE;
    }
  }

  if (found)
  {
    /*
     *-------------------------------------------------------------------
     *   read supported language from ME
     *-------------------------------------------------------------------
     */
     if (pcm_GetFileInfo ( ( UBYTE* ) ef, &fileInfo) NEQ PCM_OK)
     {
       TRACE_EVENT("cmhSIM_LanguageLP_Update: error returned by pcm_GetFileInfo()" );
       return TRUE;
     }
     else
     {

       if ( pcm_ReadFile ( (UBYTE*)ef,
                           fileInfo.FileSize,
                           (UBYTE*) &lng,
                           &fileInfo.Version) EQ PCM_OK )
       {
       }
       else
       {
         TRACE_EVENT("cmhSIM_LanguageLP_Update: error returned by pcm_ReadFile()" );
         return TRUE;
       }
     }

    /*
     *-------------------------------------------------------------------
     *  Read EF LP from the sim if Automatic language is selected
     *-------------------------------------------------------------------
     */
    if (!strncmp((char*)&lng.data[0], auptr, 2))
    {
      cmhSIM_ReqLanguageLP(ownBuf);  /* reading files */
      simShrdPrm.fuRef = (UBYTE)ref;
      return FALSE;
    }
    else
    {
      return TRUE;
    }
  }
  else
  {
    return TRUE;  /* nothing to do */
  }
}
#endif

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

  PURPOSE : This function starts reading of ELP OR LP field from SIM.
*/
GLOBAL T_ACI_RETURN cmhSIM_ReqLanguageLP  ( T_ACI_CMD_SRC srcId )
{
  T_ACI_RETURN ret       = AT_FAIL;
  SHORT                  table_id;

  TRACE_FUNCTION ("cmhSIM_ReqLanguageLP()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = SIM_LP;
    simShrdPrm.atb[table_id].dataOff      = 0;
    /* length is variable */
    simShrdPrm.atb[table_id].dataLen      = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax       = ACI_MAX_LAN_LP_NTRY;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = CLANSimEfDataLP;
    simShrdPrm.atb[table_id].rplyCB       = cmhSIM_RdCnfLangLP;


    simShrdPrm.aId = table_id;

    simEntStat.curCmd = AT_CMD_CLAN;
    simEntStat.entOwn = simShrdPrm.owner = srcId;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR psaSIM in +CLAN");
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
    }
    else
    {
      ret = AT_EXCT;
    }
  }

  return ( ret );
}


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

  PURPOSE : This function starts reading of LP field from SIM for SAT
  fetaure LS.
*/
GLOBAL BOOL cmhSIM_ReqLanguagePrfLP  (void)
{
  BOOL     ret  = FALSE;
  SHORT        table_id;

  TRACE_FUNCTION ("cmhSIM_ReqLanguagePrfLP()");

/*
 *-----------------------------------------------------------------
 * request table id for SIM SAP access
 *-----------------------------------------------------------------
 */
  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].accType      = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld   = SIM_LP;
    simShrdPrm.atb[table_id].dataOff      = 0;
    // length is variable
    simShrdPrm.atb[table_id].dataLen      = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax       = ACI_MAX_LAN_LP_NTRY;
    simShrdPrm.atb[table_id].ntryUsdFlg   = TRUE;
    simShrdPrm.atb[table_id].exchData     = CLANSimEfDataLP;
    simShrdPrm.atb[table_id].rplyCB       = cmhSIM_RdCnfLangPrfLP;

    simShrdPrm.aId = table_id;

       
    if(psaSIM_AccessSIMData() < 0)
    {
      return ( ret );      
    }
    else
    {
      ret = TRUE;
    }
  }

  return ( ret );
}


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

  PURPOSE : This function is used to request the SIM Administrative
            Data (EF_AD).

*/
GLOBAL BOOL cmhSIM_AD_Update (int ref, T_SIM_FILE_UPDATE_IND *fu)
{
  BOOL found = FALSE;
  UBYTE i;
  TRACE_FUNCTION ("cmhSIM_AD_Update()");

  for (i = 0; i < (int)fu->val_nr; i++)
  {
    if (!found AND (fu->file_id[i] EQ SIM_AD))
    {
      found = TRUE;
    }
  }
  if (found)
  {
    cmhSIM_Read_AD();
    simShrdPrm.fuRef = (UBYTE)ref;
    return FALSE; /* reading files */
   }
  else
  {
    return TRUE;  /* nothing to do */
  }
}


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

  PURPOSE : This function is used to request the SIM Administrative
            Data (EF_AD).

*/
GLOBAL T_ACI_RETURN cmhSIM_Read_AD()
{
  SHORT table_id;

  TRACE_FUNCTION ("cmhSIM_Read_AD()");

  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
    simShrdPrm.atb[table_id].accType    = ACT_RD_DAT;
    simShrdPrm.atb[table_id].reqDataFld = SIM_AD;
    simShrdPrm.atb[table_id].dataOff    = 0;
    simShrdPrm.atb[table_id].dataLen    = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].recMax     = 0;
    simShrdPrm.atb[table_id].exchData   = NULL;
    simShrdPrm.atb[table_id].rplyCB     = cmhSIM_Read_AD_cb;

    simShrdPrm.aId = table_id;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR");
      return ( AT_FAIL );
    }

    return ( AT_CMPL );
  }
  return ( AT_FAIL );
}

/*
+-------------------------------------------------------------------+
| PROJECT :                  MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_EvalMNCLength         |
+-------------------------------------------------------------------+

  PURPOSE : This function evaluates the MNC length by extracting MNC 
            from IMSI and comparing it with the MNC in operListFixed.
*/
GLOBAL  UBYTE cmhSIM_EvalMNCLength(void)
{
  UBYTE digit;        /* holds 4bit digit */
  USHORT i;           /* holds counter */
  SHORT sim_mcc;      /* holds mcc from operListFixed */
  SHORT sim_mnc;      /* holds mnc from operListFixed */
  SHORT mcc;          /* holds mcc extracted from IMSI */
  SHORT mnc;          /* holds mnc extracted from IMSI */

  mcc = mnc = 0;      /* Initialize mcc, mnc */
  
  for (i = 0; i < SIZE_MCC + SIZE_MNC; i++)   /* Extract MCC and MNC. */
  {
    digit = (i & 1) ?
      (simShrdPrm.imsi.field[(i + 1)/2] & 0x0f) :
      (simShrdPrm.imsi.field[(i + 1)/2] & 0xf0) >> 4;
    if (i < SIZE_MCC)
       mcc = (mcc << 4) | digit;
    else
       mnc = (mnc << 4) | digit;
  }
  
  for( i = 0; operListFixed[i].mcc NEQ -1 AND operListFixed[i].mnc NEQ -1; i++ ) /* Evaluate mnc length */
  {
    sim_mcc = operListFixed[i].mcc;
    sim_mnc = operListFixed[i].mnc;

    if ( sim_mcc EQ mcc )
    {
      if ( (sim_mnc & 0xff0) EQ (mnc & 0xff0) )
      {
        if ( (sim_mnc & 0x0f) EQ 0x0f )
        {
          return 2;
        }
        else 
        {
          return 3;
        }
      }
    }
  }
  return NOT_PRESENT_8BIT;
}

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

  PURPOSE :   Call back for SIM read (EF_AD).

*/
void cmhSIM_Read_AD_cb(SHORT table_id)
{
#ifdef SIM_PERS
T_SIMLOCK_STATUS sl_status;
 #endif


  TRACE_FUNCTION ("cmhSIM_Read_AD_cb()");

  if ( simShrdPrm.atb[table_id].reqDataFld EQ SIM_AD )
  {
    if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
    {
      /* 
       * byte 2 and byte 3 of EF AD have only a meaning 
       * if the bit1 of byte 1 is set 
       */
      if (simShrdPrm.atb[table_id].exchData[0] & 0x01)
      {
        if (simShrdPrm.atb[table_id].exchData[2] & 0x01)
        {
          /* ci enabled on SIM */
          simShrdPrm.ciSIMEnabled = TRUE;
        }
        else
        {
          /* ci disabled on SIM, don't show indications */
          simShrdPrm.ciSIMEnabled = FALSE;
        }
      }
      /* byte 4 is optional */
      if (simShrdPrm.atb[table_id].dataLen >= 4)
      {
        switch (simShrdPrm.atb[table_id].exchData[3] & 0x0F)
        {
          case 2:  simShrdPrm.mnc_len = 2; break;
          case 3:  simShrdPrm.mnc_len = 3; break;
          default: simShrdPrm.mnc_len =NOT_PRESENT_8BIT;
        }
      }
      else
      {
        simShrdPrm.mnc_len = NOT_PRESENT_8BIT;
      }
      if (simShrdPrm.mnc_len NEQ 3)        /* Update MNC length */
      {
        simShrdPrm.mnc_len = cmhSIM_EvalMNCLength();
      }

    }
#ifdef SIM_TOOLKIT
    if (simShrdPrm.fuRef >= 0)
    {
      psaSAT_FUConfirm (simShrdPrm.fuRef,
                        (USHORT)((simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)?
                        SIM_FU_SUCCESS: SIM_FU_ERROR));
    }
#endif
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
if(last_sim_mmi_insert_ind NEQ NULL)
{
 #ifdef SIM_PERS
   aci_slock_sim_config.sim_read_ad_first_byte = simShrdPrm.atb[table_id].exchData[0] ; 
   aci_slock_sim_init(last_sim_mmi_insert_ind);
  /* To set the global variable config data */
   aci_slock_set_CFG();
  
   if(cfg_data EQ NULL)
   {
     AciSLockShrd.blocked = TRUE;
     cmhSIM_SIMInserted();
     PFREE (last_sim_mmi_insert_ind); /* 11_Apr_05 */
     last_sim_mmi_insert_ind= NULL;
     return;     
   }
   aci_slock_init();
   sl_status = SIMLOCK_ENABLED;
   AciSLockShrd.pb_load = FALSE; 
   AciSLockShrd.check_lock = SIMLOCK_CHECK_PERS;
   sl_status = aci_slock_checkpersonalisation(SIMLOCK_NETWORK);

   #else
    /*
      * Start to build phonebook
      */
      pb_reset();

#ifdef TI_PS_FFS_PHB
      pb_inserted_sim (MAX_SRV_TBL,
                       last_sim_mmi_insert_ind->sim_serv,
                       &last_sim_mmi_insert_ind->imsi_field,
                       last_sim_mmi_insert_ind->func,
                       last_sim_mmi_insert_ind->phase);
#else
      pb_build_req(last_sim_mmi_insert_ind);
#endif

     /* Request the Customer Service Profile  from the SIM (EF_CPHS_CSP) */
      cmhSIM_Get_CSP();

      #ifdef SIM_TOOLKIT
      cmhSMS_ReadCbDtaDwnl (last_sim_mmi_insert_ind);
      #endif

      #ifdef FF_MMI_RIV
       rAT_PlusCFUNP (last_sim_mmi_insert_ind);
      #endif /* FF_MMI_RIV */
      PFREE (last_sim_mmi_insert_ind); /* 11_Apr_05 */
      last_sim_mmi_insert_ind= NULL;
    
      cmhSIM_SIMInserted();
    #endif  
}
  
}

/*
+--------------------------------------------------------------------+
| PROJECT : EONS        MODULE  : CMH_SIMF                           |
| STATE   : code        ROUTINE : cmhSIM_OpUpdate                    |
+--------------------------------------------------------------------+

  PURPOSE : This function will be used to process the update of EFopl and EFpnn.
         
*/
GLOBAL BOOL cmhSIM_OpUpdate (int ref, T_SIM_FILE_UPDATE_IND *fu)
{
  UBYTE i;
  BOOL  ps_is_not_reading_files_1 = FALSE, 
        ps_is_not_reading_files_2 = FALSE;
  
  TRACE_FUNCTION ("cmhSIM_OpUpdate()");

  for (i = 0; i < (int)fu->val_nr; i++)
  {
    switch(fu->file_id[i])
    {
      case SIM_OPL:
        TRACE_EVENT("EF_OPL has been updated ");
        ps_is_not_reading_files_1 = cmhSIM_UpdateOperatorName(SIM_OPL);
        /*lint -fallthrough */

      case SIM_PNN:
        if(fu->file_id[i] NEQ SIM_OPL)
        {
          TRACE_EVENT("EF_PNN has been updated ");
        }
        ps_is_not_reading_files_2 = !cmhMM_OpUpdateName();
        cmhMM_Registered();
        simShrdPrm.fuRef = (UBYTE)ref;
        if(ps_is_not_reading_files_1 OR
           ps_is_not_reading_files_2)
          return(TRUE);
        
        return(FALSE); /* reading files ? */

      default:
        break;
    }
  }
  return(TRUE);  /* nothing to do */
}


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_OpReadOplRcd          |
+-------------------------------------------------------------------+

  PURPOSE : Sends a SIM read request
*/

GLOBAL BOOL cmhSIM_OpReadOplRcd(UBYTE rcd)
{
  SHORT table_id;

  TRACE_FUNCTION ("cmhSIM_OpReadOplRcd()");

  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
    simShrdPrm.atb[table_id].accType    = ACT_RD_REC;
    simShrdPrm.atb[table_id].reqDataFld = SIM_OPL;
    simShrdPrm.atb[table_id].dataOff    = 0;
    simShrdPrm.atb[table_id].recNr      = rcd;
    simShrdPrm.atb[table_id].recMax     = 0;
    simShrdPrm.atb[table_id].exchData   = NULL;
    simShrdPrm.atb[table_id].dataLen    = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].rplyCB     = cmhSIM_OpReadOplRcdCb;

    simShrdPrm.aId = table_id;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR");
      return FALSE;
    }
    
    return TRUE;
  }
  return TRUE;
}


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_OpReadPnnRcd          |
+-------------------------------------------------------------------+

  PURPOSE : Sends a SIM read request
*/
GLOBAL BOOL cmhSIM_OpReadPnnRcd(UBYTE rcd)
{
  SHORT table_id;

  TRACE_FUNCTION ("cmhSIM_OpReadPnnRcd()");

  table_id = psaSIM_atbNewEntry();

  if(table_id NEQ NO_ENTRY)
  {
    simShrdPrm.atb[table_id].ntryUsdFlg = TRUE;
    simShrdPrm.atb[table_id].accType    = ACT_RD_REC;
    simShrdPrm.atb[table_id].reqDataFld = SIM_PNN;
    simShrdPrm.atb[table_id].dataOff    = 0;
    simShrdPrm.atb[table_id].recNr      = rcd;
    simShrdPrm.atb[table_id].recMax     = 0;
    simShrdPrm.atb[table_id].exchData   = NULL;
    simShrdPrm.atb[table_id].dataLen    = NOT_PRESENT_8BIT;
    simShrdPrm.atb[table_id].rplyCB     = cmhSIM_OpReadPnnRcdCb;

    simShrdPrm.aId = table_id;

    if(psaSIM_AccessSIMData() < 0)
    {
      TRACE_EVENT("FATAL ERROR");
      return FALSE;
    }
    
    return TRUE;
  }
  return TRUE;
}


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_BuildOPLList          |
+-------------------------------------------------------------------+

  PURPOSE : 
*/
LOCAL void cmhSIM_BuildOPLList(SHORT table_id)
{
  UBYTE *data = simShrdPrm.atb[table_id].exchData;
  T_opl *opl_entry = &simShrdPrm.opl_list.opl_rcd[simShrdPrm.opl_list.num_rcd];

  /* Test if record is valid */
/*  opl_entry->plmn.v_plmn = (data[0] EQ 0xFF) ? INVLD_PLMN : VLD_PLMN; */

  /* Copy MCC and MNC from SIM data to OPL list */
  memcpy (opl_entry->plmn, data, UBYTES_PER_PLMN);

  /* Extract LAC from SIM data and copy to OPL list*/
  opl_entry->lac1        = data[3] << 8 | data[4];
  opl_entry->lac2        = data[5] << 8 | data[6];

  /* Extract PNN record number from SIM data and copy to OPL list*/
  opl_entry->pnn_rec_num = data[7];
}


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_OpReadOplRcdCb        |
+-------------------------------------------------------------------+

  PURPOSE : Call back for SIM retrieval of EF_OPL.
*/
GLOBAL void cmhSIM_OpReadOplRcdCb(SHORT table_id)
{
  TRACE_FUNCTION("cmhSIM_OpReadOplRcdCb");

  /* Decode and copy OPL record data to OPL list*/
 /*------------------------------------------*/
  if(simShrdPrm.atb[table_id].dataLen AND simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)
  {
    cmhSIM_BuildOPLList(table_id);

    simShrdPrm.opl_list.opl_status = TRUE;
    /*
    if ((memcmp (simShrdPrm.opl_list.opl_rcd[simShrdPrm.opl_list.num_rcd].plmn, 
                PLMNselEmpty,
                UBYTES_PER_PLMN) NEQ 0))
    {
      cmhSIM_OpReadPnnRcd(simShrdPrm.opl_list.opl_rcd[simShrdPrm.opl_list.num_rcd].pnn_rec_num);
    }
    */
  }
  else
  {
    TRACE_EVENT("Empty OPL record");
  }

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;

  
 /* If not last EF_OPL reoord retrieve next record*/
 /*------------------------------------------*/
  simShrdPrm.atb[table_id].recNr++;
  simShrdPrm.opl_list.num_rcd++;

  if(simShrdPrm.opl_list.num_rcd > OPL_MAX_RECORDS)
  {
    TRACE_EVENT("Max OPL records reached");
  }
  else if(simShrdPrm.atb[table_id].recNr <= simShrdPrm.atb[table_id].recMax )
  {
    TRACE_EVENT_P1("Read next OPL record: %d",simShrdPrm.atb[table_id].recNr);
    cmhSIM_OpReadOplRcd(simShrdPrm.atb[table_id].recNr);
    return;
  }
  
  TRACE_EVENT("Retrieval of OPL records finished");
  /* continue with next one */
  cmhSIM_StartOperatorName();
}



/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_BuildPnnList          |
+-------------------------------------------------------------------+

  PURPOSE : decodes EF_PNN record read from SIM
*/
LOCAL void cmhSIM_BuildPnnList(SHORT table_id)
{
  UBYTE *data = simShrdPrm.atb[table_id].exchData;
  T_pnn *pnn_entry = &simShrdPrm.pnn_list.pnn_rcd[simShrdPrm.pnn_list.num_rcd];

  if (*data++ EQ PNN_LONG_NAME_IEI)
  {
    pnn_entry->v_plmn = TRUE;

    pnn_entry->long_len = (*data++)-1;  /* adjust dcs */
    pnn_entry->long_ext_dcs = *data++;
    memcpy(pnn_entry->long_name,
           data,
           MINIMUM(pnn_entry->long_len, sizeof(pnn_entry->long_name)));
    data += pnn_entry->long_len;
  
     /*----- IEI PNN short name ------*/
    if (*data++ EQ PNN_SHORT_NAME_IEI)
    {
      pnn_entry->shrt_len = (*data++)-1; /* adjust dcs */
      pnn_entry->shrt_ext_dcs = *data++;
      memcpy(pnn_entry->shrt_name,
             data, 
             MINIMUM(pnn_entry->shrt_len, sizeof(pnn_entry->shrt_name)));
    } 
    else
    {
      pnn_entry->shrt_len = 0;
    }
  }
  else
  {
    /* marc record as unused */
    pnn_entry->v_plmn = FALSE;
    pnn_entry->long_len = pnn_entry->shrt_len = 0;
  }

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


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_OpReadPnnRcdCb        |
+-------------------------------------------------------------------+

  PURPOSE : Call back for SIM retrieval of EF_PNN.
*/
GLOBAL void cmhSIM_OpReadPnnRcdCb(SHORT table_id)
{

  TRACE_FUNCTION("cmhSIM_OpReadPnnRcdCb");

  /* Decode and copy PNN record data to PNN list*/
 /*------------------------------------------*/
  if(simShrdPrm.atb[table_id].dataLen AND simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
  {
    cmhSIM_BuildPnnList(table_id);
    simShrdPrm.pnn_list.pnn_status = TRUE;
  }
  else
  {
    TRACE_EVENT("Empty PNN record");
  }

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;

  
 /* If not last EF_PNN reoord retrieve next record*/
 /*------------------------------------------*/
  simShrdPrm.atb[table_id].recNr++;
  simShrdPrm.pnn_list.num_rcd++;

  if(simShrdPrm.pnn_list.num_rcd > PNN_MAX_RECORDS)
  {
    TRACE_EVENT("Max OPL records reached");
  }
  else if(simShrdPrm.atb[table_id].recNr <= simShrdPrm.atb[table_id].recMax )
  {
    TRACE_EVENT_P1("Read next PNN record: %d",simShrdPrm.atb[table_id].recNr);
    cmhSIM_OpReadPnnRcd(simShrdPrm.atb[table_id].recNr);
    return;
  }

  TRACE_EVENT("Retrieval of PNN records finished");

  /* continue with next one */
  cmhSIM_StartOperatorName();
}


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_StartOperatorName     |
+-------------------------------------------------------------------+

  PURPOSE : Start retireval of EF_OPL from SIM
*/
GLOBAL BOOL cmhSIM_StartOperatorName()
{
  TRACE_FUNCTION ("cmhSIM_StartOperatorName()");

  /* If EF_PNN and/or EF_OPL are allocated then start retrieval of from EF_OPL */
  if (simShrdPrm.opl_list.num_rcd EQ 0 AND psaSIM_ChkSIMSrvSup(SRV_PNN) AND psaSIM_ChkSIMSrvSup(SRV_OPL))
  {
    TRACE_EVENT (" start reading SIM_OPL");
    return(!cmhSIM_OpReadOplRcd(1));
  }

  if (simShrdPrm.pnn_list.num_rcd EQ 0 AND psaSIM_ChkSIMSrvSup(SRV_PNN))
  {
    TRACE_EVENT (" start reading SIM_PNN");
    return(!cmhSIM_OpReadPnnRcd(1));
  }

  TRACE_EVENT (" reading finished!");

  if(psaSIM_ChkSIMSrvSup(SRV_PNN))
  {
    if (simShrdPrm.pnn_list.pnn_status EQ TRUE)
    {
      percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_Ready);
    }
    else if (psaSIM_ChkSIMSrvSup(SRV_OPL) AND simShrdPrm.opl_list.opl_status EQ TRUE)
    {
      percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_Ready);
    }
    else
    {
      percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_NotReady);
    }
  }
  else
  {
    percentCSTAT_indication(STATE_MSG_EONS, ENTITY_STATUS_NotReady);
  }


  
  if (mmShrdPrm.regStat EQ RS_FULL_SRV)
  {
    cmhMM_Registered();
  }

  return(TRUE);
}


/*
+-------------------------------------------------------------------+
| PROJECT : EONS             MODULE  : CMH_SIMF                     |
| STATE   : code             ROUTINE : cmhSIM_UpdateOperatorName    |
+-------------------------------------------------------------------+

  PURPOSE : Start File Update of EF_OPL from SIM
*/
GLOBAL BOOL cmhSIM_UpdateOperatorName(USHORT reqDataFld)
{
  int i;
  TRACE_FUNCTION ("cmhSIM_UpdateOperatorName()");

  if (reqDataFld EQ SIM_OPL OR reqDataFld EQ NOT_PRESENT_16BIT)
  {
    simShrdPrm.opl_list.num_rcd = 0;
    for (i=0; i<OPL_MAX_RECORDS; i++)
    {
      memcpy (simShrdPrm.opl_list.opl_rcd[i].plmn, 
              PLMNselEmpty,
              UBYTES_PER_PLMN);
    }
  }

  if (reqDataFld EQ SIM_PNN OR reqDataFld EQ NOT_PRESENT_16BIT)
  {
    simShrdPrm.pnn_list.num_rcd = 0;
    for (i=0; i<PNN_MAX_RECORDS; i++)
    {
      simShrdPrm.pnn_list.pnn_rcd[i].v_plmn=FALSE;
    }
  }

  return (!cmhSIM_StartOperatorName());
}


GLOBAL T_opl_field* cmhSIM_GetOPL()
{
  return &simShrdPrm.opl_list;
}

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

  PURPOSE : This function returns the current PLMN mode bit value

*/
GLOBAL UBYTE cmhSIM_isplmnmodebit_set()
{
  return simShrdPrm.PLMN_Mode_Bit;
}
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : CMH_SIMF             |
| STATE   : code                      ROUTINE : cmhSIM_ONS_Update    |
+--------------------------------------------------------------------+

  PURPOSE : This function is used to Read the CPHS ONS file EF_ONS.

*/

GLOBAL BOOL cmhSIM_ONS_Update (int ref, T_SIM_FILE_UPDATE_IND *fu)
{
  BOOL found = FALSE;
  UBYTE i;
  TRACE_FUNCTION ("cmhSIM_ONS_Update()");

  for (i = 0; i < (int)fu->val_nr; i++)
  {
    if (fu->file_id[i] EQ SIM_CPHS_ONSTR)
    {
      found = TRUE;
      break;
    }
  }
  if (found)
  {
    cmhMM_ONSReadName();
    simShrdPrm.fuRef = (UBYTE)ref;
    return FALSE; /* reading files */
  }
  else
  {
    return TRUE;  /* nothing to do */
  }
}

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

  PURPOSE : This function is used to request the SIM CPHS file

*/
GLOBAL void cmhSIM_Get_CSP()
{
  
  TRACE_FUNCTION ("cmhSIM_Get_CSP()");

  cmhSIM_ReadTranspEF( CMD_SRC_NONE,
                       AT_CMD_NONE,
                       SIM_CPHS_CINF,
                       0,
                       ACI_CPHS_INFO_SIZE,
                       NULL,
                       cmhSIM_Get_CSP_cb );

}


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

  PURPOSE :   Call back for SIM read for CPHS.

*/
void cmhSIM_Get_CSP_cb(SHORT table_id)
{
  
  TRACE_FUNCTION ("cmhSIM_Get_CSP_cb()");

  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;

  /* Step #1: Reading of CPHS Info */
  if (simShrdPrm.atb[table_id].errCode NEQ SIM_NO_ERROR OR
      simShrdPrm.atb[table_id].exchData EQ NULL         OR
      simShrdPrm.atb[table_id].dataLen < ACI_CPHS_INFO_SIZE )
  {
    ;  /* CPHS info not supported or invalid */
  }
  else if ((simShrdPrm.atb[table_id].exchData[1] & 0x03) EQ ALLOCATED_AND_ACTIVATED)
  {
    /* continue with reading of CSP file */
    cmhSIM_Read_CSP();
    return;
  }

}

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

  PURPOSE : This function is used to request the SIM Customer Service Profile (EF_CPHS_CSP).

*/
GLOBAL BOOL cmhSIM_CSP_Update (int ref, T_SIM_FILE_UPDATE_IND *fu)
{
  BOOL found = FALSE;
  UBYTE i;
  TRACE_FUNCTION ("cmhSIM_CSP_Update()");

  for (i = 0; i < (int)fu->val_nr; i++)
  {
    if (!found AND (fu->file_id[i] EQ SIM_CPHS_CSP))
    {
      found = TRUE;
    }
  }
  if (found)
  {
    cmhSIM_Read_CSP();
    simShrdPrm.fuRef = (UBYTE)ref;
    return FALSE; /* reading files */
  }
  else
  {
    return TRUE;  /* nothing to do */
  }
}

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

  PURPOSE : This function is used to request the SIM Customer Service Profile
            (EF_CSP).

*/
GLOBAL void cmhSIM_Read_CSP()
{
  
  TRACE_FUNCTION ("cmhSIM_Read_CSP()");

  cmhSIM_ReadTranspEF( CMD_SRC_NONE,
                       AT_CMD_NONE,
                       SIM_CPHS_CSP,
                       0,
                       0,
                       NULL,
                       cmhSIM_Read_CSP_cb );

}


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

  PURPOSE :   Call back for SIM read (EF_CSP).

*/
void cmhSIM_Read_CSP_cb(SHORT table_id)
{
  
  TRACE_FUNCTION ("cmhSIM_Read_CSP_cb()");

  if ( simShrdPrm.atb[table_id].reqDataFld EQ SIM_CPHS_CSP )
  {
    if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
    {
      if(simShrdPrm.atb[table_id].dataLen >= ACI_CPHS_CSP_SIZE)
      {
        USHORT idx;
        for(idx=0; idx < simShrdPrm.atb[table_id].dataLen; idx = idx+2)
        {
         if(simShrdPrm.atb[table_id].exchData[idx] EQ VAS_SERVICE_GROUP_CODE)
         {
           if(simShrdPrm.atb[table_id].exchData[idx+1] & PLMN_MODE_BIT_ON)
           {
             simShrdPrm.PLMN_Mode_Bit = CPHS_CSP_PLMN_MODE_BIT_ON;
           }
           else
           {
             simShrdPrm.PLMN_Mode_Bit = CPHS_CSP_PLMN_MODE_BIT_OFF;
           }
           break;
         }
        }
      }
    }
    
#ifdef SIM_TOOLKIT
    if (simShrdPrm.fuRef >= 0)
    {
      psaSAT_FUConfirm (simShrdPrm.fuRef,
                        (USHORT)((simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR)?
                        SIM_FU_SUCCESS: SIM_FU_ERROR));
    }
#endif
  }
  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
}


#ifdef SIM_PERS_OTA

/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_Register_Read_DCK
+------------------------------------------------------------------------------
|  Description : This function is used to request the SIM De-personalization Control Keys
|            (EF_DCK)
|  Parameters  : ref      - Reference for file update
|                       *fu     - Pointer to T_SIM_FILE_UPDATE_IND
|                
|  Return      : TRUE if no files left to read, 
|                    FALSE if some files are there to read
|
+------------------------------------------------------------------------------
*/

GLOBAL BOOL cmhSIM_Register_Read_DCK (int ref, T_SIM_FILE_UPDATE_IND *fu)
{
  BOOL found = FALSE;
  UBYTE i;

  TRACE_FUNCTION ("cmhSIM_Register_Read_DCK()");

  for (i = 0; i < (int)fu->val_nr AND (fu->file_id[i] NEQ SIM_DCK); i++)
  {
  }

  if (i NEQ (int)fu->val_nr )
  {
  
   if (psaSIM_ChkSIMSrvSup(SRV_DePersCK))
  {
    TRACE_FUNCTION("SRV_DePersCK supported.");
    cmhSIM_ReadTranspEF( CMD_SRC_NONE,
             AT_CMD_NONE,
             SIM_DCK,
             0,
             16,
             NULL,
             cmhSIM_Read_DCK_cb );
  }
  
    simShrdPrm.fuRef = (UBYTE)ref;
    return FALSE; /* reading files */
  }
  else
  {
    return TRUE;  /* nothing to do */
  }
}




/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_Read_DCK_cb
+------------------------------------------------------------------------------
|  Description : Call back for SIM read (EF_DCK).
|  Parameters  : SHORT table_id
|                
|  Return      : void
|
+------------------------------------------------------------------------------
*/
void cmhSIM_Read_DCK_cb(SHORT table_id)
{
  TRACE_FUNCTION ("cmhSIM_Read_DCK_cb()");

  if ( simShrdPrm.atb[table_id].reqDataFld EQ SIM_DCK )
  {
    if ( simShrdPrm.atb[table_id].errCode EQ SIM_NO_ERROR )
    {
      aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[0], 8, (char *) nw_ctrl_key);
      aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[4], 8, (char *) nw_subset_ctrl_key);
      aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[8], 8, (char *) sp_ctrl_key);
      aci_slock_psaSIM_decodeIMSI_without_parity (&simShrdPrm.atb[table_id].exchData[12], 8, (char *) corp_ctrl_key);

      aci_slock_unlock(SIMLOCK_NETWORK, (char *) nw_ctrl_key);
  aci_slock_unlock(SIMLOCK_NETWORK_SUBSET, (char *) nw_subset_ctrl_key);
  aci_slock_unlock(SIMLOCK_SERVICE_PROVIDER, (char *) sp_ctrl_key);
  aci_slock_unlock(SIMLOCK_CORPORATE, (char *) corp_ctrl_key);
      cmhSIM_WriteDefaultValue_DCK();
    }
  }
}


/*
+------------------------------------------------------------------------------
|  Function    : cmhSIM_WriteDefaultValue_DCK
+------------------------------------------------------------------------------
|  Description : This function is used to write back the SIM De-personalization Control Keys
|            (EF_DCK) read during init after depersonalizing the ME
|
|  Parameters  : none
|                
|  Return      : void
|
+------------------------------------------------------------------------------
*/
GLOBAL void cmhSIM_WriteDefaultValue_DCK()
{
  UBYTE all_keys[MAX_DCK_LEN];

  TRACE_FUNCTION ("cmhSIM_WriteDefaultValue_DCK()");
  memset(all_keys,NOT_PRESENT_8BIT,MAX_DCK_LEN);
  cmhSIM_WriteTranspEF( CMD_SRC_NONE,
             AT_CMD_NONE,
        SIM_DCK,
        0,
        MAX_DCK_LEN,
        all_keys  ,             
        NULL );
}


#endif //SIM_PERS_OTA
/*==== EOF ========================================================*/