diff src/aci2/aci/cmh_simf.c @ 3:93999a60b835

src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 26 Sep 2016 00:29:36 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aci2/aci/cmh_simf.c	Mon Sep 26 00:29:36 2016 +0000
@@ -0,0 +1,2871 @@
+/*  
++-----------------------------------------------------------------------------
+|  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 ========================================================*/
+