diff g23m/condat/ms/src/aci/aci_slock.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m/condat/ms/src/aci/aci_slock.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,2892 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  
+|  Modul   :  J:\g23m-aci\aci\aci_slock.c
++----------------------------------------------------------------------------- 
+|  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 :  
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifdef SIM_PERS
+#include "aci_all.h"
+
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+
+#ifdef FAX_AND_DATA
+#include "aci_fd.h"
+#endif /* FAX_AND_DATA */
+
+#include "aci.h"
+#include "psa.h"
+#include "psa_sim.h"
+#include "psa_sms.h"
+#include "psa_mmi.h"
+#include "cmh.h"
+#include "dti_conn_mng.h"
+#include "cmh_sim.h"
+#include "phb.h"
+#include "aoc.h"
+
+#include "psa_sim.h"            /* simShrdPrm */ 
+
+#include "aci_ext_pers.h"       /* we are using personalisation extensions */
+#include "aci_slock.h"          /* in order to asure interfaces */
+
+/* Remember actual stati of already checked locks */
+GLOBAL T_ACI_SLOCK_SHARED AciSLockShrd;
+
+GLOBAL UBYTE sim_code_present_in_me; /* used by personalisation */
+GLOBAL T_ACI_SIM_CONFIG aci_slock_sim_config;     /* SIM configuration, initialised by a T_SIM_MMI_INSERT_IND */
+
+#include "general.h"  // inluded for UINT8 compilation error in sec_drv.h
+#include "sec_drv.h" 
+
+GLOBAL T_SEC_DRV_CONFIGURATION *cfg_data ;
+
+EXTERN T_SEC_DRV_CATEGORY *personalisation_nw;
+
+EXTERN T_SEC_DRV_CATEGORY *personalisation_ns;
+
+EXTERN T_SEC_DRV_CATEGORY *personalisation_sp;
+
+EXTERN T_SEC_DRV_CATEGORY *personalisation_cp;
+
+EXTERN T_SEC_DRV_CATEGORY *personalisation_sim;
+
+EXTERN T_SEC_DRV_CATEGORY *personalisation_first_sim;
+EXTERN void  psaSAT_FUConfirm       ( int, USHORT );
+const UBYTE mnc_mcc[6] = "00101"; // 04-08-2005
+
+LOCAL UBYTE aci_slock_sim_service_table [10];     /* SIM service table        */
+
+EXTERN T_SIM_MMI_INSERT_IND *last_sim_mmi_insert_ind;
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_init
++------------------------------------------------------------------------------
+|  Description : Initialising of this module. Has to be called first and *once only* before 
+|                     calling any other method.
+|
+|  Parameters  : None
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+
+void aci_slock_init ( void )
+{
+
+  TRACE_FUNCTION("aci_slock_init()");
+
+  /* Initialise the ACI Personalisation extension */
+  aci_ext_personalisation_init();
+  AciSLockShrd.blocked = FALSE;
+
+}
+
+
+
+
+/*
+  Temporary Unlocks the lock of the given type after verifying the given password.
+  The ACI extension for password verifying (see 2.3.9.1) will be used to
+  determine if the given password is correct or not.
+  On a successful unlock the actual status of the lock will be returned.
+  If an error occurred SIMLOCK_FAIL will be returned.
+  (Uses the ACI extension "personalisation data access".)
+  */
+T_SIMLOCK_STATUS aci_slock_authenticate ( T_SIMLOCK_TYPE type, char *passwd )
+{
+  T_SIMLOCK_STATUS result;
+
+  TRACE_FUNCTION("aci_slock_authenticate()");
+  result = aci_ext_personalisation_verify_password(type, passwd);
+  
+  if ( (result EQ SIMLOCK_DISABLED) AND (AciSLockShrd.blocked)) /* If lock is checked as blocked at the moment uncheck it! */
+  {
+    AciSLockShrd.blocked = !(AciSLockShrd.current_lock EQ type);
+  }
+
+  return result;
+}
+
+
+/*
+ ACI method for retrieving the status of a single personalisation type. This method calls extension 
+ methods which in turn calls Security Drv. API and retrn the status of a personalisation category.
+ The personalisation status is stored in MEPD which is directly accessed by Security Drv. 
+ Added on 11/03/2005
+*/
+T_SIMLOCK_STATUS aci_personalisation_get_status ( T_SIMLOCK_TYPE personalisation_type )
+{
+  TRACE_FUNCTION("aci_personalisation_get_status ()");
+  return aci_ext_personalisation_get_status(personalisation_type);
+}
+//#endif
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_unlock
++------------------------------------------------------------------------------
+|  Description : Unlocks the lock of the given type after verifying the given password.
+|  The ACI extension for password verifying (see 2.3.9.1) will be used to
+|  determine if the given password is correct or not.
+|  On a successful unlock the actual status of the lock will be returned.
+|  If an error occurred SIMLOCK_FAIL will be returned.
+|  (Uses the ACI extension "personalisation data access".)
+|
+|  Parameters  : type       - Category Lock type
+|         passwd   - lock Password
+|
+|  Return      : SIMLOCK_FAIL = -1,
+|         SIMLOCK_DISABLED,      No SIM lock check has to be done  
+|       SIMLOCK_PERM_DISABLED,
+|       SIMLOCK_ENABLED,       A SIM lock check has to be executed
+|       SIMLOCK_BLOCKED,       The SIM is blocked, i.e. because of a (or to many) wrong PIN(s) 
+|        SIMLOCK_LOCKED         The ME is locked because of wrong SIM 
+|
++------------------------------------------------------------------------------
+*/
+ 
+T_SIMLOCK_STATUS aci_slock_unlock ( T_SIMLOCK_TYPE type, char *passwd )
+{
+  T_SIMLOCK_STATUS result;
+
+  TRACE_FUNCTION("aci_slock_unlock()");
+   aci_slock_set_CFG();
+    if(cfg_data EQ NULL)
+   {
+      return SIMLOCK_FAIL;  
+    }
+
+  result = aci_ext_personalisation_set_status(type, SIMLOCK_DISABLED, passwd);
+  
+  if ( (result EQ SIMLOCK_DISABLED) AND (AciSLockShrd.blocked)) /* If lock is checked as blocked at the moment uncheck it! */
+  {
+    AciSLockShrd.blocked = !(AciSLockShrd.current_lock EQ type);
+  }
+  MFREE(cfg_data);
+  
+  return result;
+
+  
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_lock
++------------------------------------------------------------------------------
+|  Description :   Locks the lock of the given type.  On a successful lock the actual
+|  status of the lock will be returned. If an error occurred SIMLOCK_FAIL
+|  will be returned. This method will use the ACI extension for password
+|  verifying (see 2.3.9.1) to determine if the given password is correct
+|  or not. (Uses the ACI extension "personalisation data access".)
+|
+|  Parameters  : type       - Category Lock type
+|         passwd   - lock Password
+|
+|  Return      : SIMLOCK_FAIL = -1,
+|         SIMLOCK_DISABLED,      No SIM lock check has to be done  
+|       SIMLOCK_PERM_DISABLED,
+|       SIMLOCK_ENABLED,       A SIM lock check has to be executed
+|       SIMLOCK_BLOCKED,       The SIM is blocked, i.e. because of a (or to many) wrong PIN(s) 
+|        SIMLOCK_LOCKED         The ME is locked because of wrong SIM 
+|
++------------------------------------------------------------------------------
+*/
+T_SIMLOCK_STATUS aci_slock_lock ( T_SIMLOCK_TYPE type, char *passwd )
+{
+
+  T_SIMLOCK_STATUS result;
+  T_SEC_DRV_RETURN ret;
+  UBYTE imsi_sim[MAX_IMSI_LEN+1];
+  int numUserCodeIdx;
+  BOOL lock = TRUE;
+  TRACE_FUNCTION("aci_slock_lock()");
+ 
+  if(aci_slock_sim_config.sim_type EQ SIM_NORMAL)
+  {
+     aci_slock_set_CFG();
+    if(cfg_data EQ NULL)
+   {
+      return SIMLOCK_FAIL;  
+    }
+    aci_ext_personalisation_init();
+    result = aci_ext_personalisation_get_status( type );
+
+     if(result EQ SIMLOCK_DISABLED)
+    {  
+        if(cfg_data->AddNewIMSI & ( 0x0001 << type) )   /* 1-Apr-05 Bitmap check */
+        {
+          sim_code_present_in_me = FALSE;
+          psaSIM_decodeIMSI(simShrdPrm.imsi.field, simShrdPrm.imsi.c_field, (char *)imsi_sim);
+          switch(type)
+          {
+            case SIMLOCK_NETWORK: aci_slock_check_NWlock(imsi_sim, 1);break;
+            case SIMLOCK_NETWORK_SUBSET: aci_slock_check_NSlock(imsi_sim, 1);break;
+            case SIMLOCK_SIM: aci_slock_check_SMlock(imsi_sim, 1); break;
+            /*Added cases for SP & CP below: 2nd April - 2005*/
+            case SIMLOCK_SERVICE_PROVIDER:
+                          if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1) )
+                           {
+                             if(aci_slock_sim_config.sim_read_gid1 EQ FALSE)
+                             {
+                               aci_slock_sim_read_sim(SIM_GID1, NOT_PRESENT_8BIT, MAX_GID);
+                               aci_ext_personalisation_free();
+                               MFREE(cfg_data);
+                               return SIMLOCK_WAIT;
+                             }
+                          }
+                         else 
+                          {
+                             aci_ext_personalisation_free();
+                             MFREE(cfg_data);
+                             return SIMLOCK_FAIL;
+                          }
+                         aci_slock_check_SPlock(imsi_sim,1);break;
+            case SIMLOCK_CORPORATE: 
+                         if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+                         {
+                            if(aci_slock_sim_config.sim_read_gid1 EQ FALSE)
+            	                {
+                                aci_slock_sim_read_sim(SIM_GID1, NOT_PRESENT_8BIT, MAX_GID);
+                                aci_ext_personalisation_free();
+                                MFREE(cfg_data);
+                                return SIMLOCK_WAIT; 
+            	                }
+                         }
+                        else 
+                         {
+                           aci_ext_personalisation_free();
+                           MFREE(cfg_data);               
+                           return SIMLOCK_FAIL;
+                         }
+						
+                         if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+                         {
+                           if(aci_slock_sim_config.sim_read_gid2 EQ FALSE)
+            	               {
+                              aci_slock_sim_read_sim(SIM_GID2, NOT_PRESENT_8BIT, MAX_GID);
+                              aci_ext_personalisation_free();
+                              MFREE(cfg_data);
+                              return SIMLOCK_WAIT; 
+            	               }
+                        }
+                       else 
+                        {
+                         aci_ext_personalisation_free();
+                         MFREE(cfg_data);
+                         return SIMLOCK_FAIL;
+                        }
+                        aci_slock_check_CPlock(imsi_sim, 1);break;              
+            default:TRACE_ERROR ("illegal type aci_slock_lock ()");
+                 return;
+          }  
+          if (sim_code_present_in_me EQ FALSE)         
+          {  
+            /* changes for ETSI behavior  date : 01-Apr-05*/
+            if (cfg_data->Flags & SEC_DRV_HDR_FLAG_ETSI_Flag)
+            {
+              ret = SEC_DRV_RET_Ok ; 
+            }
+            else 
+            {
+              ret = sec_cmp_KEY(type,passwd,0);
+            }
+            if(ret EQ SEC_DRV_RET_Ok)
+            {  
+              aci_ext_add_code(type);
+            }
+            else
+            {
+              aci_ext_personalisation_free();
+              MFREE(cfg_data);
+              return SIMLOCK_FAIL;
+            }
+          }
+         else if(sim_code_present_in_me EQ CHECK_FAIL)
+          {
+              aci_ext_personalisation_free();
+              MFREE(cfg_data);
+              return SIMLOCK_FAIL;
+           }
+        }   
+
+      /*
+       * If there are no operator-defined codes or user-defined codes in the MEPD at all, do not lock the category
+       */
+       switch(type)
+       {
+         case SIMLOCK_NETWORK : 
+           numUserCodeIdx =  OPCODE_LEN_INDEX + ((UBYTE *)personalisation_nw->pBody)[OPCODE_LEN_INDEX] + 1;
+           if( (((UBYTE *) personalisation_nw->pBody)[OPCODE_LEN_INDEX] EQ 0) AND 
+           (((UBYTE *) personalisation_nw->pBody)[numUserCodeIdx] EQ 0) )
+           {
+             /*Do not lock the category*/
+             lock = FALSE;
+            }
+         break;
+        
+         case SIMLOCK_NETWORK_SUBSET : 
+           numUserCodeIdx =  OPCODE_LEN_INDEX + ((UBYTE *)personalisation_ns->pBody)[OPCODE_LEN_INDEX] + 1;
+           if( ( ((UBYTE *)personalisation_ns->pBody)[OPCODE_LEN_INDEX] EQ 0) AND 
+           ( ((UBYTE *)personalisation_ns->pBody)[numUserCodeIdx] EQ 0) )
+           {
+             /*Do not lock the category*/
+             lock = FALSE;
+           }
+         break;
+        
+         case SIMLOCK_SIM : 
+           numUserCodeIdx =  OPCODE_LEN_INDEX +((UBYTE *) personalisation_sim->pBody)[OPCODE_LEN_INDEX] + 1;
+           if( (((UBYTE *) personalisation_sim->pBody)[OPCODE_LEN_INDEX] EQ 0) AND 
+           (((UBYTE *) personalisation_sim->pBody)[numUserCodeIdx] EQ 0) )
+           {
+             /*Do not lock the category*/
+             lock = FALSE;
+            }
+         break;
+         
+         case SIMLOCK_SERVICE_PROVIDER: 
+           numUserCodeIdx =  OPCODE_LEN_INDEX + ((UBYTE *)personalisation_sp->pBody)[OPCODE_LEN_INDEX] + 1;
+           if( ( ((UBYTE *)personalisation_sp->pBody)[OPCODE_LEN_INDEX] EQ 0) AND 
+           (((UBYTE *) personalisation_sp->pBody)[numUserCodeIdx] EQ 0) )
+           {
+             /*Do not lock the category*/
+             lock = FALSE;
+           }
+         break;
+        
+         case SIMLOCK_CORPORATE: 
+           numUserCodeIdx =  OPCODE_LEN_INDEX + ((UBYTE *)personalisation_cp->pBody)[OPCODE_LEN_INDEX] + 1;
+           if( ( ((UBYTE *)personalisation_cp->pBody)[OPCODE_LEN_INDEX] EQ 0) AND 
+           ( ((UBYTE *)personalisation_cp->pBody)[numUserCodeIdx] EQ 0) )
+           {
+             /*Do not lock the category*/
+             lock = FALSE;
+           }        
+         break;
+       }
+       
+       if(lock EQ TRUE)
+       {
+         result = aci_ext_personalisation_set_status(type, SIMLOCK_ENABLED, passwd);
+       }
+
+  aci_ext_personalisation_free();
+       MFREE(cfg_data);
+       return result;
+    }
+    else 
+    {
+      aci_ext_personalisation_free();
+      MFREE(cfg_data);
+      return SIMLOCK_FAIL;
+    }
+  }
+  else 
+    return SIMLOCK_FAIL;
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_reset_fc
++------------------------------------------------------------------------------
+|  Description : This function is used to reset the Failure Counter
+|
+|  Parameters  : char* fcKey - Failure Reset Key
+|
+|  Return      :   OPER_FAIL 
+|           OPER_SUCCESS  
+|
++------------------------------------------------------------------------------
+*/
+
+T_OPER_RET_STATUS aci_slock_reset_fc ( char *fcKey )
+{  
+  TRACE_FUNCTION("aci_slock_reset_fc ()");
+  return aci_ext_slock_reset_fc(fcKey);
+}
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_sup_info
++------------------------------------------------------------------------------
+|  Description : This function is used to get the supplementary information like FCMAX,   
+|      FCATTEMPTSLEFT,  FCRESETFAILMAX, FCRESETFAILATTEMPTSLEFT,
+|        FCRESETSUCCESSMAX, FCRESETSUCCESSATTEMPTSLEFT, TIMERFLAG,
+|      ETSIFLAG,  AIRTELINDFLAG
+|
+|  Parameters  : sup_info - Pointer to T_SUP_INFO
+|
+|  Return      :   OPER_FAIL 
+|           OPER_SUCCESS  
+|
++------------------------------------------------------------------------------
+*/
+T_OPER_RET_STATUS aci_slock_sup_info(T_SUP_INFO *sup_info)
+{  
+  TRACE_FUNCTION("aci_slock_sup_info()");
+  return aci_ext_slock_sup_info (sup_info);
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_change_password
++------------------------------------------------------------------------------
+|  Description : This function is used to change the password of a category
+|
+|  Parameters  :     type - Category lock type
+|             passwd - Old  Control key
+|        new_passwd - New  Control key
+|
+|  Return      :  SIMLOCK_FAIL = -1,
+|         SIMLOCK_DISABLED,      No SIM lock check has to be done  
+|       SIMLOCK_PERM_DISABLED,
+|       SIMLOCK_ENABLED,       A SIM lock check has to be executed
+|       SIMLOCK_BLOCKED,       The SIM is blocked, i.e. because of a (or to many) wrong PIN(s) 
+|        SIMLOCK_LOCKED         The ME is locked because of wrong SIM 
+|
++------------------------------------------------------------------------------
+*/
+
+T_SIMLOCK_STATUS aci_slock_change_password ( T_SIMLOCK_TYPE type, char *passwd, char *new_passwd )
+{
+  TRACE_FUNCTION("aci_slock_change_password()");
+  return aci_ext_personalisation_change_password(type, passwd, new_passwd);
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_psaSIM_decodeIMSI
++------------------------------------------------------------------------------
+|  Description : convert imsi (packed bcd to ASCIIZ; ->11.11)
+|
+|  Parameters  :   imsi_field            - IMSI in BCD
+|                    imsi_c_field         - 
+|                    imsi_asciiz           - ASCII IMSI
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void aci_slock_psaSIM_decodeIMSI (UBYTE* imsi_field,    
+                    UBYTE  imsi_c_field,  CHAR* imsi_asciiz)
+{
+
+  UBYTE imsi_len;
+  UBYTE i;
+  UBYTE digit;
+
+
+ /*
+      
+        | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+      
+    +---+---+---+---+---+---+---+---+
+     imsi_c_field  = |         Length indicator      |     
+     imsi_field[0] = | IMSI digit 1  | p | 0 | 0 | 1 |
+     imsi_field[1] = | IMSI digit 3  | IMSI digit 2  |
+
+     imsi_c_field = length indicator:
+          
+     The length indicator refers to the number of significant bytes, not including this length byte, 
+     required for the IMSI.
+     p = parity
+         0: Even number of IMSI digits
+         1: Odd number of IMSI digits
+
+     If the number of IMSI digits is even then bits 5 to 8 of the last octet shall be filled with an end mark coded as 1111b
+   */
+
+  /*
+   *
+ Check length
+   */
+  if ((imsi_c_field EQ 0) OR (imsi_c_field > (MAX_IMSI-1)))  /* maybe 0xFF on some testcards */
+  {
+    TRACE_EVENT_P1("[WRN] imsi_c_field = %d is not valid", imsi_c_field);
+
+    imsi_asciiz[0] = '\0';    /* return empty string in case of error */
+
+    return;
+  }
+
+  /*
+   * calculate number of digits
+   */
+  imsi_len = (imsi_c_field)*2-1;   /* -1 goes off for parity nibble */
+
+
+  /*
+   * if even number of digits then last upper nibble is an end mark '1111'
+   */
+  if ((imsi_field[0] & 0x08) EQ 0)
+  {
+    imsi_len--;
+  }
+
+ 
+
+  if ((imsi_field[0] & 0x08) EQ 0)
+  {
+    imsi_len--;
+  }
+
+  /*
+   * extract all digits
+   */
+  for (i=0; i<imsi_len; i++)
+  {
+    if ((i & 1) EQ 0)
+    {
+      /* process IMSI digit 1,3,5,... at i=0,2,4,...*/
+      digit = (imsi_field[(i+1)/2] & 0xf0) >> 4;   /* +1 is to skip parity nibble */
+    }
+    else
+    {
+      /* process IMSI digit 2,4,6,... at i=1,3,5,...*/
+      digit = (imsi_field[(i+1)/2] & 0x0f); 
+    }
+
+    if (digit > 9)  
+    {
+      imsi_asciiz[i] = 'F';    
+      //  return;
+    }
+    else
+    {
+      imsi_asciiz[i] = '0' + digit;
+    }
+   
+  }
+  imsi_asciiz[i] = '\0';
+  return;
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_psaSIM_decodeIMSI_without_parity
++------------------------------------------------------------------------------
+|  Description : convert imsi (packed bcd to ASCIIZ; ->11.11)
+|
+|  Parameters  :   imsi_field            - IMSI in BCD
+|                    imsi_c_field         - 
+|                    imsi_asciiz           - ASCII IMSI
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+
+GLOBAL void aci_slock_psaSIM_decodeIMSI_without_parity(UBYTE* imsi_field, 
+                               UBYTE  imsi_c_field, 
+                               CHAR* imsi_asciiz)
+{
+
+  UBYTE imsi_len;
+  UBYTE i;
+  UBYTE digit;
+ 
+  //TRACE_FUNCTION ("aci_slock_sim_decodeIMSI()");
+
+  /*
+                     | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+                     +---+---+---+---+---+---+---+---+
+     imsi_c_field  = |         Length indicator      |
+     imsi_field[0] = | IMSI digit 1  | p | 0 | 0 | 1 |
+     imsi_field[1] = | IMSI digit 3  | IMSI digit 2  |
+                    
+
+     imsi_c_field = length indicator:
+                    The length indicator refers to the number of significant bytes,
+                    not including this length byte, required for the IMSI.
+     p = parity
+         0: Even number of IMSI digits
+         1: Odd number of IMSI digits
+
+     If the number of IMSI digits is even then bits 5 to 8 of the last octet
+     shall be filled with an end mark coded as 1111b
+   */
+
+  /*
+   * Check length
+   */
+  if ((imsi_c_field EQ 0) OR (imsi_c_field > (MAX_IMSI-1)))  /* maybe 0xFF on some testcards */
+  {
+    TRACE_EVENT_P1("[WRN] imsi_c_field = %d is not valid", imsi_c_field);
+    imsi_asciiz[0] = '\0';    /* return empty string in case of error */
+    return;
+  }
+
+  /*
+   * calculate number of digits
+   */
+  imsi_len = (imsi_c_field)*2;   
+
+  
+
+  /*
+   * extract all digits
+   */
+  for (i=0; i<imsi_len; i++)
+  {
+    if ((i & 1) EQ 0)
+    {
+      /* process IMSI digit 1,3,5,... at i=0,2,4,...*/
+       digit = (imsi_field[i/2] & 0x0f); 
+      
+    }
+    else
+    {
+      /* process IMSI digit 2,4,6,... at i=1,3,5,...*/
+     digit = (imsi_field[i/2] & 0xf0) >> 4;   /* +1 is to skip parity nibble */
+    }
+
+    if (digit > 9)  
+    {
+     
+      imsi_asciiz[i] = 'F';    
+    //  return;
+    }
+    else
+    {
+      imsi_asciiz[i] = '0' + digit;
+    }
+
+   
+  }
+  imsi_asciiz[i] = '\0';
+  return;
+
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_check_NWlock
++------------------------------------------------------------------------------
+|  Description : Check IMSI against network personalisation 
+|
+|  Parameters  :   imsi_sim            - IMSI
+|                    personalisation   - 0-add the lock data
+|                    1-verify the existing lock data  
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+
+void aci_slock_check_NWlock( UBYTE* imsi_sim, UBYTE  personalisation  )
+{
+
+  UBYTE max_num_user_codes;
+  UBYTE num_op_codes;
+  UBYTE curr_user_code_index;
+  UBYTE num_user_codes;
+  UBYTE opcode_len;
+  UBYTE code_type;
+
+  UBYTE i;
+  UINT16 index =0;
+  UBYTE me_nw_code_bcd[NW_CODE_LEN];
+  UBYTE me_nw_code_first_bcd[NW_CODE_LEN];
+  UBYTE me_nw_code_last_bcd[NW_CODE_LEN];
+  UBYTE imsi_me[MAX_IMSI_LEN+1];
+  UBYTE imsi_sim_temp[MAX_IMSI_LEN+1];
+
+  int   me_nw_code_first, me_nw_code_last, sim_nw_code;
+
+  TRACE_FUNCTION("aci_slock_check_NWlock()");
+
+  /*
+  personalisation_nw->pBody[0] -----maximum number of user codes 
+  personalisation_nw->pBody[1] -----num of operator codes 
+  personalisation_nw->pBody[2] -----Operator Code-group length (To be set during configuration)
+where length =  total number of bytes occupied by operator codes
+
+
+Code type = 0x0a ( Type identifier for normal code)  
+Normal code (Including parity nibble)  -- 4 bytes
+
+Code type = 0x0b (Type identifier for range)
+Start value (Including parity nibble) ---- 4 byte
+End value (Including parity nibble) -----4 byte 
+
+Code type = 0x0c (Type identifier for regular expression)   
+Regular Expression  -------------6 byte
+
+
+Number of User Codes  --- 1 byte
+Current user code index  --- 1 byte
+User code1  ------------4 byte
+
+  */
+//TRACE_FUNCTION_P1("personalisation = %d",personalisation);
+  if((personalisation_nw NEQ NULL) AND ((UBYTE *)personalisation_nw->pBody NEQ NULL))
+  {
+    max_num_user_codes = ((UBYTE *)personalisation_nw->pBody)[index];
+    index += MAX_NUM_USERCODE_SIZE;
+
+    num_op_codes = ((UBYTE *)personalisation_nw->pBody)[index];
+    index += NUM_OPCODE_SIZE;
+
+    opcode_len = ((UBYTE *)personalisation_nw->pBody)[index];
+    index +=OPCODE_LEN_SIZE;
+
+    if(!personalisation)
+    {
+      AciSLockShrd.blocked = TRUE;
+    }
+    else 
+    {
+      sim_code_present_in_me = FALSE; 
+    }
+  /*
+   * check operator defined code-groups
+   */
+    for(i=0; i< num_op_codes; i++)
+    {
+      code_type =((UBYTE *) personalisation_nw->pBody)[index];
+      index +=CODE_TYPE_SIZE;
+
+      switch(code_type)
+      {
+        case NORMAL_CODE :
+          memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_nw->pBody)[index]),NW_CODE_LEN);
+          index +=NW_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me);
+          
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              return; /* IMSI is matching a personalisation, so break! */
+            }
+          }
+          else 
+          {
+            sim_code_present_in_me =memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+            if(sim_code_present_in_me EQ TRUE)
+              return;
+          }
+          
+         break;
+    
+         case INTERVAL_TYPE1 :
+           memcpy(me_nw_code_first_bcd,&(((UBYTE *)personalisation_nw->pBody)[index]),NW_CODE_LEN);
+           index +=NW_CODE_LEN;
+           memcpy(me_nw_code_last_bcd,&(((UBYTE *)personalisation_nw->pBody)[index]),NW_CODE_LEN);
+           index +=NW_CODE_LEN;
+          
+           aci_slock_psaSIM_decodeIMSI(me_nw_code_first_bcd, NW_CODE_LEN, (char *)imsi_me);
+           imsi_me[simShrdPrm.mnc_len+3] = '\0';  //to remove trailing F (if any) from imsi_me string
+           me_nw_code_first = atoi((const char *)imsi_me);
+           aci_slock_psaSIM_decodeIMSI(me_nw_code_last_bcd, NW_CODE_LEN, (char *)imsi_me); 
+           imsi_me[simShrdPrm.mnc_len+3] = '\0';
+           me_nw_code_last = atoi((const char *)imsi_me);
+
+           memcpy(imsi_sim_temp,imsi_sim,simShrdPrm.mnc_len+3);
+           imsi_sim_temp[simShrdPrm.mnc_len+3] = '\0'; 
+           sim_nw_code = atoi((const char *)imsi_sim_temp);
+
+           if(!personalisation)
+           {
+             if((sim_nw_code >= me_nw_code_first ) AND (sim_nw_code <= me_nw_code_last))
+             {
+               AciSLockShrd.blocked = FALSE;
+               return ;
+             }
+             else 
+               AciSLockShrd.blocked = TRUE;  
+           }
+           else 
+           {
+              if((sim_nw_code >= me_nw_code_first ) AND (sim_nw_code <= me_nw_code_last))
+             {
+               sim_code_present_in_me  = TRUE; 
+               return;
+             }
+           }
+         break;
+          
+         case REGULAR_EXP :
+         break;
+    
+         default :
+         break;
+      }
+    }
+
+    num_user_codes = ((UBYTE *)personalisation_nw->pBody)[index];
+    index +=NUM_USER_CODE_SIZE;
+
+    curr_user_code_index = ((UBYTE *)personalisation_nw->pBody)[index];
+    index +=CURR_USER_CODE_INDEX_SIZE;
+
+  /*
+   * check user defined code-groups
+   */
+    for(i=0; i< num_user_codes; i++)
+    {
+      memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_nw->pBody)[index]),NW_CODE_LEN);
+      index +=NW_CODE_LEN;
+      aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me);
+  
+      if(!personalisation)
+      {
+        AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+        if (AciSLockShrd.blocked EQ FALSE)
+          return; /* IMSI is matching a personalisation, so break! */
+      }
+      else 
+      {
+        sim_code_present_in_me =memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+        if(sim_code_present_in_me EQ TRUE)
+          return;
+      }
+    }
+  }
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_check_NSlock
++------------------------------------------------------------------------------
+|  Description : Check IMSI against network subset personalisation 
+|
+|  Parameters  :   imsi_sim            - IMSI
+|                    personalisation   - 0-add the lock data
+|                    1-verify the existing lock data  
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_check_NSlock( UBYTE* imsi_sim, UBYTE  personalisation  )
+{
+  UBYTE max_num_user_codes;
+  UBYTE num_op_codes;
+  UBYTE curr_user_code_index;
+  UBYTE num_user_codes;
+  UBYTE opcode_len;
+  UBYTE code_type;
+  
+  
+  UINT16 index =0;
+  UBYTE me_nw_code_bcd[NW_CODE_LEN];
+  UBYTE me_ns_code_bcd[NS_CODE_LEN];
+  UBYTE me_nw_ns_code_bcd[NW_NS_CODE_LEN];
+  UBYTE me_nw_ns_ns_code_bcd[NW_NS_NS_CODE_LEN];
+  UBYTE me_nw_code[MAX_IMSI_LEN+1];
+  UBYTE me_ns_code[2 +1];
+  UBYTE imsi_me[MAX_IMSI_LEN+1];
+  UBYTE me_nw_ns_ns_code_str[6+2+2+1];
+  UBYTE imsi_sim_temp[MAX_IMSI_LEN+1];
+  UBYTE imsi_sim_8or9th_digit_str[1+1] ;
+  UBYTE imsi_sim_ns_code_str[2+1] ;
+  UBYTE no_of_digit_8th_value; 
+  UBYTE digit_8th_value; 
+  UBYTE no_of_normal_8th_digit_ns_code; 
+  UBYTE no_of_interval_8th_digit_ns_code; 
+  
+  
+  int   me_ns_code_first,    
+  me_ns_code_last,
+  sim_ns_code,
+  sim_8or9th_digit_code,
+  i,j,k;
+  
+  TRACE_FUNCTION("aci_slock_check_NSlock()");
+
+/*
+  personalisation_ns->pBody[0] -----maximum number of user codes 
+  personalisation_ns->pBody[1] -----num of operator codes 
+  personalisation_ns->pBody[2] -----Operator Code-group length (To be set during configuration)
+where length =  total number of bytes occupied by operator codes
+
+
+Code type = 0x0a ( Type identifier for normal code)  
+Normal code (Including parity nibble)  -- 5 bytes  (Nw code + NS code)
+
+Code type = 0x0b (Type identifier for range)
+Network code --------- 4 byte 
+Start value of NS code ---- 1 byte
+End value of NS code -----1 byte 
+
+Code type = 0x0c (Type identifier for regular expression)   
+Regular expression including Network + NS Code -------------8 byte
+
+Code type = 0x0d
+(8thdigit normal code/range)
+Network code (Including parity nibble) ------ 4 byte
+No. of  8th digit values for which normal codes and/or intervals are to be stored   ---- 1 byte
+8th digit value  -- 1 byte
+No. of normal codes to be associated with the digit (n1)  ---- 1 byte
+No. of intervals to be associated with the digit (n2)  ----- 1 byte
+Normal code 1   --- 1 byte 
+            |
+            |
+            |
+Normal code n1 ---- 1 byte 
+
+Start value of interval 1  ---- 1 byte 
+End value of interval 1   ---- 1 byte 
+            |
+            |
+            |
+ Start value of interval n2  ------ 1 byte 
+  End value of interval n2  ------- 1 byte 
+
+  Number of User Codes   ------- 1 byt e
+  Current user code index 
+(for FIFO based addition/deletion of user codes)
+(should be set to 0xff if no user codes are present)  ---- 1 byte 
+
+User code1             ---------- 5 byte 
+User code 2      ---------- 5 byte 
+         | 
+         |
+ User code n (n = Max number of user codes for NS)  -- 5 byte
+
+
+  */
+      
+  if(!personalisation)
+  {
+    AciSLockShrd.blocked = TRUE;
+  }
+  else 
+  {
+    sim_code_present_in_me = FALSE; 
+  }
+  if((personalisation_ns NEQ NULL) AND ((UBYTE *)personalisation_ns->pBody NEQ NULL))
+  {
+    max_num_user_codes = ((UBYTE *)personalisation_ns->pBody)[index];
+    index += MAX_NUM_USERCODE_SIZE;
+    
+    num_op_codes =((UBYTE *) personalisation_ns->pBody)[index];
+    index += NUM_OPCODE_SIZE;
+    
+    opcode_len = ((UBYTE *)personalisation_ns->pBody)[index];
+    index +=OPCODE_LEN_SIZE;
+
+    /*
+     * check operator defined code-groups
+     */
+    for(i=0; i< num_op_codes; i++)
+    {
+      code_type = ((UBYTE *)personalisation_ns->pBody)[index];
+      index +=CODE_TYPE_SIZE;
+      switch(code_type)
+      {
+        case NORMAL_CODE :
+          memcpy(me_nw_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NW_NS_CODE_LEN);
+          index +=NW_NS_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_ns_code_bcd, NW_NS_CODE_LEN, (char *)imsi_me);
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/+2/* NS length */) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              return; /* IMSI is matching a personalisation, so break! */
+            }
+          }
+          else
+          {
+            sim_code_present_in_me =memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/+2/* NS length */) EQ 0; 
+            if(sim_code_present_in_me EQ TRUE)
+              return;
+          }
+        break;
+      
+        case INTERVAL_TYPE1 :
+          memcpy(me_nw_ns_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NW_NS_NS_CODE_LEN);
+          index +=NW_NS_NS_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_ns_ns_code_bcd, NW_NS_NS_CODE_LEN, (char *)me_nw_ns_ns_code_str);
+          memcpy(me_nw_code,me_nw_ns_ns_code_str,simShrdPrm.mnc_len+3);
+
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,me_nw_code,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              memcpy(me_ns_code,me_nw_ns_ns_code_str+7/*skip the 'F'*/,2);
+              me_ns_code[2] = '\0';
+              me_ns_code_first = atoi((const char *)me_ns_code);
+     
+              memcpy(me_ns_code,me_nw_ns_ns_code_str+7+2/*skip the 'F'*/,2);
+              me_ns_code[2] = '\0';
+              me_ns_code_last = atoi((const char *)me_ns_code);
+     
+              memcpy(imsi_sim_temp,imsi_sim+simShrdPrm.mnc_len+3,2);
+              imsi_sim_temp[2] = '\0';
+              sim_ns_code = atoi((const char *)imsi_sim_temp);
+              if((sim_ns_code >= me_ns_code_first ) AND (sim_ns_code <= me_ns_code_last))
+              {
+                AciSLockShrd.blocked = FALSE;
+                return ;
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;  
+            }
+          }
+          else 
+          {
+             sim_code_present_in_me= memcmp(imsi_sim,me_nw_code,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+             if(sim_code_present_in_me EQ TRUE)
+             {
+               sim_code_present_in_me = FALSE;
+               memcpy(me_ns_code,me_nw_ns_ns_code_str+7/*skip the 'F'*/,2);
+               me_ns_code[2] = '\0';
+               me_ns_code_first = atoi((const char *)me_ns_code);
+     
+               memcpy(me_ns_code,me_nw_ns_ns_code_str+7+2/*skip the 'F'*/,2);
+               me_ns_code[2] = '\0';
+               me_ns_code_last = atoi((const char *)me_ns_code);
+     
+               memcpy(imsi_sim_temp,imsi_sim+simShrdPrm.mnc_len+3,2);
+               imsi_sim_temp[2] = '\0';
+               sim_ns_code = atoi((const char *)imsi_sim_temp);
+               if((sim_ns_code >= me_ns_code_first ) AND (sim_ns_code <= me_ns_code_last))
+               {
+                 sim_code_present_in_me =TRUE;
+                 return;
+               }
+             }
+          }
+           
+        break;
+      
+        case INTERVAL_TYPE2 :
+          TRACE_FUNCTION("INTERVAL_TYPE2");
+          memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NW_CODE_LEN);
+          index +=NW_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)me_nw_code); 
+          no_of_digit_8th_value = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+          index += 1; 
+
+     if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,me_nw_code,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {  
+              AciSLockShrd.blocked = TRUE;
+              
+              imsi_sim_8or9th_digit_str[0] = imsi_sim[simShrdPrm.mnc_len+3+2] ;
+              imsi_sim_8or9th_digit_str[1]  ='\0';
+              sim_8or9th_digit_code = atoi((const char *)imsi_sim_8or9th_digit_str);
+
+    for(j=0; j <no_of_digit_8th_value; j++ )
+              {
+                digit_8th_value = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+                index += 1;
+                no_of_normal_8th_digit_ns_code  = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+                index += 1;
+                no_of_interval_8th_digit_ns_code  = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+                index += 1;
+                if(sim_8or9th_digit_code EQ digit_8th_value)
+                {
+                  for(k =0; k < no_of_normal_8th_digit_ns_code; k++)
+                  {
+                    memcpy(me_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NS_CODE_LEN);
+                    index += NS_CODE_LEN; 
+                    aci_slock_psaSIM_decodeIMSI_without_parity(me_ns_code_bcd, NS_CODE_LEN, (char *)me_ns_code); 
+                    AciSLockShrd.blocked = memcmp(imsi_sim+simShrdPrm.mnc_len+3,me_ns_code,2) NEQ 0; 
+                    if(AciSLockShrd.blocked EQ FALSE)
+                      return ;
+                  }
+                  if(AciSLockShrd.blocked EQ TRUE)
+                  {
+                    for(k =0; k < no_of_interval_8th_digit_ns_code; k++)
+                    {
+                      memcpy(me_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NS_CODE_LEN);
+                      index += NS_CODE_LEN; 
+                      aci_slock_psaSIM_decodeIMSI_without_parity(me_ns_code_bcd, NS_CODE_LEN, (char *)me_ns_code); 
+                      me_ns_code[2] = '\0';
+                      me_ns_code_first =  atoi((const char *)me_ns_code);
+                      
+                      memcpy(me_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NS_CODE_LEN);
+                      index += NS_CODE_LEN; 
+                      aci_slock_psaSIM_decodeIMSI_without_parity(me_ns_code_bcd, NS_CODE_LEN, (char *)me_ns_code); 
+                      me_ns_code[2] = '\0';
+                      me_ns_code_last =  atoi((const char *)me_ns_code);
+                      
+                      memcpy(imsi_sim_ns_code_str,&imsi_sim[simShrdPrm.mnc_len+3],2);
+                      imsi_sim_ns_code_str[2] = '\0';
+                      sim_ns_code = atoi((const char *)imsi_sim_ns_code_str);
+                    
+                      if((sim_ns_code >= me_ns_code_first) AND (sim_ns_code <= me_ns_code_last) )
+                      {
+                        AciSLockShrd.blocked = FALSE;
+                        return ;
+                      }
+                      else 
+                        AciSLockShrd.blocked = TRUE;
+                    }
+                  }
+                }
+                else 
+                  index += (NS_CODE_LEN*no_of_normal_8th_digit_ns_code +2*NS_CODE_LEN*no_of_interval_8th_digit_ns_code ) ;
+              }
+            }
+          }
+          else 
+          {
+             sim_code_present_in_me = memcmp(imsi_sim,me_nw_code,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+             if (sim_code_present_in_me EQ TRUE)
+             {  
+               sim_code_present_in_me = FALSE;
+               imsi_sim_8or9th_digit_str[0] = imsi_sim[simShrdPrm.mnc_len+3+2] ;
+               imsi_sim_8or9th_digit_str[1]  ='\0';
+               sim_8or9th_digit_code = atoi((const char *)imsi_sim_8or9th_digit_str);
+               
+               for(j=0; j <no_of_digit_8th_value; j++ )
+               {
+                 digit_8th_value = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+                 index += 1;
+                 no_of_normal_8th_digit_ns_code  = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+                 index += 1;
+                 no_of_interval_8th_digit_ns_code  = ((UBYTE *)personalisation_ns->pBody)[index] ; 
+                 index += 1;
+                      
+                 if(sim_8or9th_digit_code EQ digit_8th_value)
+                 {
+                   for(k =0; k < no_of_normal_8th_digit_ns_code; k++)
+                   {
+                     memcpy(me_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NS_CODE_LEN);
+                     index += NS_CODE_LEN; 
+                     aci_slock_psaSIM_decodeIMSI_without_parity(me_ns_code_bcd, NS_CODE_LEN, (char *)me_ns_code); 
+                     sim_code_present_in_me = memcmp(imsi_sim+simShrdPrm.mnc_len+3,me_ns_code,2) EQ 0; 
+                     if(sim_code_present_in_me EQ TRUE)
+                       return ;
+                   }
+                   if(sim_code_present_in_me EQ FALSE)
+                   {
+                     for(k =0; k < no_of_interval_8th_digit_ns_code; k++)
+                     {
+                       memcpy(me_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NS_CODE_LEN);
+                       index += NS_CODE_LEN; 
+                       aci_slock_psaSIM_decodeIMSI_without_parity(me_ns_code_bcd, NS_CODE_LEN, (char *)me_ns_code); 
+                       me_ns_code[2] = '\0';
+                       me_ns_code_first =  atoi((const char *)me_ns_code);
+     
+                       memcpy(me_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NS_CODE_LEN);
+                       index += NS_CODE_LEN; 
+                       aci_slock_psaSIM_decodeIMSI_without_parity(me_ns_code_bcd, NS_CODE_LEN, (char *)me_ns_code); 
+                       me_ns_code[2] = '\0';
+                       me_ns_code_last =  atoi((const char *)me_ns_code);
+                       
+                       memcpy(imsi_sim_ns_code_str,&imsi_sim[simShrdPrm.mnc_len+3],2);
+                       imsi_sim_ns_code_str[2] = '\0';
+                       sim_ns_code = atoi((const char *)imsi_sim_ns_code_str);
+     
+                       if((sim_ns_code >= me_ns_code_first) AND (sim_ns_code <= me_ns_code_last) )
+                       {
+                         sim_code_present_in_me = TRUE;
+                         return ;
+                       }
+                       else 
+                         sim_code_present_in_me = FALSE;
+                     }
+                   }
+                 }
+                 else 
+                   index += (NS_CODE_LEN*no_of_normal_8th_digit_ns_code +2*NS_CODE_LEN*no_of_interval_8th_digit_ns_code ) ;
+               }
+             }
+          }
+        break;
+      
+        case REGULAR_EXP :
+        break;
+
+   default :
+        break;
+      }
+    }
+
+    num_user_codes = ((UBYTE *)personalisation_ns->pBody)[index];
+    index +=NUM_USER_CODE_SIZE;
+     
+    curr_user_code_index = ((UBYTE *)personalisation_ns->pBody)[index];
+    index +=CURR_USER_CODE_INDEX_SIZE;
+
+     /*
+     * check user defined code-groups
+     */
+    for(i=0; i< num_user_codes; i++)
+    {
+      memcpy(me_nw_ns_code_bcd,&(((UBYTE *)personalisation_ns->pBody)[index]),NW_NS_CODE_LEN);
+      index +=NW_NS_CODE_LEN;
+      aci_slock_psaSIM_decodeIMSI(me_nw_ns_code_bcd, NW_NS_CODE_LEN, (char *)imsi_me); 
+      if(!personalisation)
+      {
+        AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/+2/* NS length */) NEQ 0; // F is not expected here 
+        if (AciSLockShrd.blocked EQ FALSE)
+        {
+          return; /* IMSI is matching a personalisation, so break! */
+         }
+      }
+      else 
+      {
+        sim_code_present_in_me= memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/+2/* NS length */) EQ 0; // F is not expected here 
+        if(sim_code_present_in_me EQ TRUE)
+        {
+          return;
+        }
+      }
+    }
+  }
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_check_SPlock
++------------------------------------------------------------------------------
+|  Description : Check IMSI against service provider personalisation
+|
+|  Parameters  :   imsi_sim            - IMSI
+|                    personalisation   - 0-add the lock data
+|                    1-verify the existing lock data  
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_check_SPlock( UBYTE* imsi_sim, UBYTE  personalisation )
+{
+  UBYTE max_num_user_codes;
+  UBYTE num_op_codes;
+  UBYTE curr_user_code_index;
+  UBYTE num_user_codes;
+  UBYTE opcode_len;
+  UBYTE code_type;
+  
+  UINT16 index =0;
+  UBYTE me_nw_code_bcd[NW_CODE_LEN];
+  UBYTE imsi_me[MAX_IMSI_LEN+1];
+  UBYTE me_gid1_str[GID1_LEN+1];
+  UBYTE sim_gid1_str[GID1_LEN+1];
+  
+  int   me_gid1_first,
+  me_gid1_last,
+  sim_gid1,
+  i;
+
+  TRACE_FUNCTION("aci_slock_check_SPlock()");
+
+   if((aci_slock_sim_config.sim_gidl1[0] EQ NOT_PRESENT_8BIT) OR (aci_slock_sim_config.gid1_len NEQ cfg_data->GID1_Len))
+   {
+   
+    TRACE_FUNCTION_P1("aci_slock_sim_config.sim_gidl1[0] %d", aci_slock_sim_config.sim_gidl1[0]);
+   if(!personalisation)
+    {
+      AciSLockShrd.blocked = TRUE;
+    }
+   else 
+   {
+      sim_code_present_in_me = CHECK_FAIL; 
+   }
+    return; 
+  }
+  else
+   {
+
+  
+  /*
+  personalisation_sp->pBody[0] -----maximum number of user codes 
+  personalisation_sp->pBody[1] -----num of operator codes 
+  personalisation_sp->pBody[2] -----Operator Code-group length (To be set during configuration)
+where length =  total number of bytes occupied by operator codes
+
+
+Code type = 0x0a ( Type identifier for normal code)  
+Normal code (Including parity nibble)  -- 8 bytes  (Network code + GID1 value)
+
+Code type = 0x0b (Type identifier for range)
+Network code --------- 4 byte 
+Start GID1 ---- -------4 byte
+End GID1 -------------4 byte 
+
+Code type = 0x0c (Type identifier for regular expression)   
+Regular Expression (including NW code and GID1 value)  --- 10 byte
+
+  Number of User Codes   ------- 1 byt e
+  Current user code index 
+(for FIFO based addition/deletion of user codes)
+(should be set to 0xff if no user codes are present)  ---- 1 byte 
+
+User code1             ---------- 8 byte 
+User code 2      ---------- 8 byte 
+         | 
+         |
+ User code n (n = Max number of user codes for NS)  -- 8 byte
+
+
+  */
+  if(!personalisation)
+  {
+    AciSLockShrd.blocked = TRUE;
+  }
+  else 
+  {
+    sim_code_present_in_me = FALSE; 
+  }
+  if((personalisation_sp NEQ NULL) AND ((UBYTE *)personalisation_sp->pBody NEQ NULL))
+  {
+    max_num_user_codes = ((UBYTE *)personalisation_sp->pBody)[index];
+    index += MAX_NUM_USERCODE_SIZE;
+     
+    num_op_codes = ((UBYTE *)personalisation_sp->pBody)[index];
+    index += NUM_OPCODE_SIZE;
+     
+    opcode_len = ((UBYTE *)personalisation_sp->pBody)[index];
+    index +=OPCODE_LEN_SIZE;
+     
+    /*
+    * check operator defined code-groups
+    */
+    for(i=0; i< num_op_codes; i++)
+    {
+      code_type = ((UBYTE *)personalisation_sp->pBody)[index];
+      index +=CODE_TYPE_SIZE;
+      switch(code_type)
+      {
+        case NORMAL_CODE :
+          memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_sp->pBody)[index]),NW_CODE_LEN);
+          index +=NW_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me); 
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len/*GID1_LEN*/) NEQ 0; 
+                if (AciSLockShrd.blocked EQ FALSE)
+                {
+                  return;
+                }
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;
+            }
+          }
+          else
+          {
+            sim_code_present_in_me= memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+            if(sim_code_present_in_me EQ TRUE)
+            {
+              sim_code_present_in_me = FALSE;
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                sim_code_present_in_me = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) EQ 0; 
+                if (sim_code_present_in_me EQ TRUE)
+                {
+                return;
+                }
+              }              
+            }
+          }
+        break;
+                  
+        case INTERVAL_TYPE1 :
+          memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_sp->pBody)[index]),NW_CODE_LEN);
+          index +=NW_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me); 
+          
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                me_gid1_str[GID1_LEN] ='\0';
+                me_gid1_first = atoi((const char *)me_gid1_str);
+            
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                me_gid1_str[GID1_LEN] ='\0';
+                me_gid1_last = atoi((const char *)me_gid1_str);
+                memcpy(sim_gid1_str,aci_slock_sim_config.sim_gidl1,GID1_LEN);
+                sim_gid1_str[GID1_LEN] = '\0';
+                sim_gid1 = atoi((const char *)sim_gid1_str);
+
+      if((sim_gid1 >= me_gid1_first) AND (sim_gid1 <= me_gid1_last))
+                {
+                  AciSLockShrd.blocked = FALSE;
+                  return ;
+                }
+                else 
+                  AciSLockShrd.blocked = TRUE;  
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;  
+            }
+          }
+          else 
+          {
+            sim_code_present_in_me= memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0;
+            if (sim_code_present_in_me EQ TRUE)
+            {
+              sim_code_present_in_me = FALSE;
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                me_gid1_str[GID1_LEN] ='\0';
+                me_gid1_first = atoi((const char *)me_gid1_str);
+            
+            
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                me_gid1_str[GID1_LEN] ='\0';
+                me_gid1_last = atoi((const char *)me_gid1_str);
+                memcpy(sim_gid1_str,aci_slock_sim_config.sim_gidl1,GID1_LEN);
+                sim_gid1_str[GID1_LEN] = '\0';
+                sim_gid1 = atoi((const char *)sim_gid1_str);
+
+                if((sim_gid1 >= me_gid1_first) AND (sim_gid1 <= me_gid1_last))
+                {
+                  sim_code_present_in_me = TRUE;
+                  return ;
+                }
+              }
+            }
+          }
+        break;
+                  
+        case REGULAR_EXP :
+        break;
+        default :
+        break;
+      }
+    }
+
+    num_user_codes = ((UBYTE *)personalisation_sp->pBody)[index];
+    index +=NUM_USER_CODE_SIZE;
+    
+    curr_user_code_index =((UBYTE *) personalisation_sp->pBody)[index];
+    index +=CURR_USER_CODE_INDEX_SIZE;
+     
+     
+    /*
+    * check user defined code-groups
+    */
+    for(i=0; i< num_user_codes; i++)
+    {
+      memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_sp->pBody)[index]),NW_CODE_LEN);
+      index +=NW_CODE_LEN;
+      aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me); 
+      if(!personalisation)
+      {
+        AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+        if (AciSLockShrd.blocked EQ FALSE)
+        {
+          if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+          {
+            memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+            index +=GID1_LEN;
+            AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              return;
+            }
+          }
+          else 
+            AciSLockShrd.blocked = TRUE;
+        }
+      }
+      else 
+      {
+        sim_code_present_in_me = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+        if (sim_code_present_in_me EQ TRUE)
+        {
+          sim_code_present_in_me = FALSE;
+          if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+          {
+            memcpy(me_gid1_str,&(((UBYTE *)personalisation_sp->pBody)[index]),GID1_LEN);
+            index +=GID1_LEN;
+            sim_code_present_in_me= memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) EQ 0; 
+            if (sim_code_present_in_me EQ TRUE)
+            {
+              return;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_check_CPlock
++------------------------------------------------------------------------------
+|  Description : Check IMSI against service corporate personalisation
+|
+|  Parameters  :   imsi_sim            - IMSI
+|                    personalisation   - 0-add the lock data
+|                    1-verify the existing lock data  
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_check_CPlock( UBYTE* imsi_sim, UBYTE  personalisation)
+{
+  UBYTE max_num_user_codes;
+  UBYTE num_op_codes;
+  UBYTE curr_user_code_index;
+  UBYTE num_user_codes;
+  UBYTE opcode_len;
+  
+  UBYTE code_type;
+  
+  UINT16 index =0;
+  UBYTE me_nw_code_bcd[NW_CODE_LEN];
+  UBYTE imsi_me[MAX_IMSI_LEN+1];
+  UBYTE me_gid1_str[GID1_LEN+1];
+  UBYTE me_gid2_str[GID2_LEN+1];
+  UBYTE sim_gid2_str[GID2_LEN+1];
+  
+  int   me_gid2_first,
+  me_gid2_last,
+  sim_gid2,
+  i;
+
+  TRACE_FUNCTION("aci_slock_check_CPlock()");
+
+
+  
+  if((aci_slock_sim_config.sim_gidl1[0] EQ NOT_PRESENT_8BIT) OR (aci_slock_sim_config.sim_gidl2[0] EQ NOT_PRESENT_8BIT)
+       OR (aci_slock_sim_config.gid1_len NEQ cfg_data->GID1_Len) OR (aci_slock_sim_config.gid2_len NEQ cfg_data->GID2_Len))
+   {
+     if(!personalisation)
+      {
+        AciSLockShrd.blocked = TRUE;
+      }
+     else 
+     {
+       sim_code_present_in_me = CHECK_FAIL; 
+     }
+     return; 
+   }
+  else
+   {
+
+
+    /*
+  personalisation_cp->pBody[0] -----maximum number of user codes 
+  personalisation_cp->pBody[1] -----num of operator codes 
+  personalisation_cp->pBody[2] -----Operator Code-group length (To be set during configuration)
+where length =  total number of bytes occupied by operator codes
+
+
+Code type = 0x0a ( Type identifier for normal code)  
+Normal code (Including parity nibble)  -- 12 bytes  (Network code + GID1 value + GID2 value)
+
+Code type = 0x0b (Type identifier for range)
+Network code --------- 4 byte 
+GID1 value------------4 byte
+Start GID1 ---- -------4 byte
+End GID1 -------------4 byte 
+
+Code type = 0x0c (Type identifier for regular expression)   
+Regular Expression (including NW code, GID1 value and GID2 value)  --- 14 byte
+
+  Number of User Codes   ------- 1 byt e
+  Current user code index 
+(for FIFO based addition/deletion of user codes)
+(should be set to 0xff if no user codes are present)  ---- 1 byte 
+
+User code1             ---------- 12 byte 
+User code 2      ---------- 12 byte 
+         | 
+         |
+ User code n (n = Max number of user codes for NS)  -- 12 byte
+
+
+  */
+  if(!personalisation)
+  {
+    AciSLockShrd.blocked = TRUE;
+  }
+  else 
+  {
+    sim_code_present_in_me = FALSE; 
+  }
+  if((personalisation_cp NEQ NULL) AND ((UBYTE *)personalisation_cp->pBody NEQ NULL))
+  {
+    max_num_user_codes = ((UBYTE *)personalisation_cp->pBody)[index];
+    index += MAX_NUM_USERCODE_SIZE;
+     
+    num_op_codes = ((UBYTE *)personalisation_cp->pBody)[index];
+    index += NUM_OPCODE_SIZE;
+
+    opcode_len = ((UBYTE *)personalisation_cp->pBody)[index];
+    index +=OPCODE_LEN_SIZE;
+    /*
+    * check operator defined code-groups
+    */
+    for(i=0; i< num_op_codes; i++)
+    {
+      code_type = ((UBYTE *)personalisation_cp->pBody)[index];
+      index +=CODE_TYPE_SIZE;
+      switch(code_type)
+      {
+        case NORMAL_CODE :
+          memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_cp->pBody)[index]),NW_CODE_LEN);
+          index +=NW_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me); 
+
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) NEQ 0; 
+                if (AciSLockShrd.blocked EQ FALSE)
+                {
+                  if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+                  {
+                    memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                    index +=GID2_LEN;
+                    AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl2,me_gid2_str,cfg_data->GID2_Len) NEQ 0; 
+                    if (AciSLockShrd.blocked EQ FALSE)
+                    {
+                      return;
+                    }
+                  }
+                  else 
+                    AciSLockShrd.blocked = TRUE;
+                }
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;
+            }
+          }
+          else 
+          {
+            sim_code_present_in_me = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+            if(sim_code_present_in_me EQ TRUE)
+            {
+              sim_code_present_in_me = FALSE;
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                sim_code_present_in_me = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) EQ 0; 
+                if (sim_code_present_in_me EQ TRUE)
+                {
+                  sim_code_present_in_me = FALSE;
+                  if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+                  {
+                    memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                    index +=GID2_LEN;
+                    sim_code_present_in_me = memcmp(aci_slock_sim_config.sim_gidl2,me_gid2_str,cfg_data->GID2_Len) EQ 0; 
+                    if (sim_code_present_in_me EQ TRUE)
+                    {
+                      return;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        break;
+    
+        case INTERVAL_TYPE1 :
+          memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_cp->pBody)[index]),NW_CODE_LEN);
+          index +=NW_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me);
+
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+      
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) NEQ 0; 
+                  
+                if (AciSLockShrd.blocked EQ FALSE)
+                {
+                  if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+                  {
+                    memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                    index +=GID2_LEN;
+                    me_gid2_str[GID2_LEN] ='\0';
+                    me_gid2_first = atoi((const char *)me_gid2_str);
+      
+                    memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                    index +=GID2_LEN;
+                    me_gid2_str[GID2_LEN] ='\0';
+                    me_gid2_last = atoi((const char *)me_gid2_str);
+                    
+                    memcpy(sim_gid2_str,aci_slock_sim_config.sim_gidl2,GID1_LEN);
+                    sim_gid2_str[GID2_LEN] = '\0';
+                    sim_gid2 = atoi((const char *)sim_gid2_str);
+                    if((sim_gid2 >= me_gid2_first) AND (sim_gid2 <= me_gid2_last))
+                    {
+                      AciSLockShrd.blocked = FALSE;
+                      return ;
+                    }
+                    else 
+                      AciSLockShrd.blocked = TRUE;  
+                  }
+                  else 
+                    AciSLockShrd.blocked = TRUE;  
+                }
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;
+            }
+          }
+          else 
+          {
+            sim_code_present_in_me = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+            if (sim_code_present_in_me EQ TRUE)
+            {
+              sim_code_present_in_me = FALSE;
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+              {
+                memcpy(me_gid1_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID1_LEN);
+                index +=GID1_LEN;
+                sim_code_present_in_me= memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) EQ 0; 
+                if (sim_code_present_in_me EQ TRUE)
+                {
+                  sim_code_present_in_me = FALSE;
+                  if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+                  {
+                    memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                    index +=GID2_LEN;
+                    me_gid2_str[GID2_LEN] ='\0';
+                    me_gid2_first = atoi((const char *)me_gid2_str);
+      
+                    memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                    index +=GID2_LEN;
+                    me_gid2_str[GID2_LEN] ='\0';
+                    me_gid2_last = atoi((const char *)me_gid2_str);
+                    
+                    memcpy(sim_gid2_str,aci_slock_sim_config.sim_gidl2,GID1_LEN);
+                    sim_gid2_str[GID2_LEN] = '\0';
+                    sim_gid2 = atoi((const char *)sim_gid2_str);
+                    if((sim_gid2 >= me_gid2_first) AND (sim_gid2 <= me_gid2_last))
+                    {
+                      sim_code_present_in_me = TRUE;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        break;
+
+   case REGULAR_EXP :
+        break;
+
+   default :
+        break;
+      }
+    }
+
+    num_user_codes = ((UBYTE *)personalisation_cp->pBody)[index];
+    index +=NUM_USER_CODE_SIZE;
+
+    curr_user_code_index =((UBYTE *) personalisation_cp->pBody)[index];
+    index +=CURR_USER_CODE_INDEX_SIZE;
+
+
+    /*
+     * check user defined code-groups
+     */
+    for(i=0; i< num_user_codes; i++)
+    {
+      memcpy(me_nw_code_bcd,&(((UBYTE *)personalisation_cp->pBody)[index]),NW_CODE_LEN);
+      index +=NW_CODE_LEN;
+      aci_slock_psaSIM_decodeIMSI(me_nw_code_bcd, NW_CODE_LEN, (char *)imsi_me); 
+      if(!personalisation)
+      {
+        AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) NEQ 0; 
+        if (AciSLockShrd.blocked EQ FALSE)
+        {
+          if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+          {
+            memcpy(me_gid1_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID1_LEN);
+            index +=GID1_LEN;
+            AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+              {
+                memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                index +=GID2_LEN;
+                AciSLockShrd.blocked = memcmp(aci_slock_sim_config.sim_gidl2,me_gid2_str,cfg_data->GID2_Len) NEQ 0; 
+                if (AciSLockShrd.blocked EQ FALSE)
+                {
+                  return;
+                }
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;
+            }
+          }
+          else 
+            AciSLockShrd.blocked = TRUE;
+        }
+      }
+      else 
+      {
+        sim_code_present_in_me= memcmp(imsi_sim,imsi_me,simShrdPrm.mnc_len+3/*MCC length*/) EQ 0; 
+        if ( sim_code_present_in_me EQ TRUE)
+        {
+          sim_code_present_in_me = FALSE;
+          if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+          {
+            memcpy(me_gid1_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID1_LEN);
+            index +=GID1_LEN;
+            sim_code_present_in_me = memcmp(aci_slock_sim_config.sim_gidl1,me_gid1_str,cfg_data->GID1_Len) EQ 0; 
+            if (sim_code_present_in_me EQ TRUE)
+            {
+              sim_code_present_in_me = FALSE;
+              if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+              {
+                memcpy(me_gid2_str,&(((UBYTE *)personalisation_cp->pBody)[index]),GID2_LEN);
+                index +=GID2_LEN;
+                sim_code_present_in_me = memcmp(aci_slock_sim_config.sim_gidl2,me_gid2_str,cfg_data->GID2_Len) EQ 0; 
+                if (sim_code_present_in_me EQ TRUE)
+                {
+                  return;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+ }
+ 
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_check_SMlock
++------------------------------------------------------------------------------
+|  Description :   Check IMSI against SIM personalisation
+|
+|  Parameters  :   imsi_sim            - IMSI
+|                    personalisation   - 0-add the lock data
+|                    1-verify the existing lock data  
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+ void aci_slock_check_SMlock( UBYTE* imsi_sim, UBYTE  personalisation)
+{
+  UBYTE max_num_user_codes;
+  UBYTE num_op_codes;
+  UBYTE curr_user_code_index;
+  UBYTE num_user_codes;
+  UBYTE opcode_len;
+  
+  UBYTE code_type;
+  
+  UBYTE i;
+  UINT16 index =0;
+  UBYTE me_nw_ns_msin_code_bcd[NW_NS_MSIN_CODE_LEN];
+  UBYTE me_nw_ns_msin_msin_code_bcd[NW_NS_MSIN_MSIN_CODE_LEN];
+  
+  UBYTE me_nw_ns_code_str[6+2+1];
+  UBYTE me_msin_code_str[8+1];
+  UBYTE me_nw_ns_msin_msin_code_str[6+2+8+8+1];
+  
+  UBYTE imsi_me[MAX_IMSI_LEN+1];
+  UBYTE imsi_sim_temp[MAX_IMSI_LEN+1];
+  
+  int   me_msin_code_first,
+  me_msin_code_last,
+            sim_msin_code;
+
+  TRACE_FUNCTION("aci_slock_check_SMlock()");
+
+/*
+  personalisation_sim->pBody[0] -----maximum number of user codes 
+  personalisation_sim->pBody[1] -----num of operator codes 
+  personalisation_sim->pBody[2] -----Operator Code-group length (To be set during configuration)
+where length =  total number of bytes occupied by operator codes
+
+
+Code type = 0x0a ( Type identifier for normal code)  
+Normal code (Including parity nibble)  -- 8 bytes  (Network code + NS code + MSIN)
+
+Code type = 0x0b (Type identifier for range)
+Network code + NS code  --------- 5 byte 
+Start MSIN ---- -------4 byte
+End MSIN -------------4 byte 
+
+Code type = 0x0c (Type identifier for regular expression)   
+Regular Expression (including NW code NS code and MSIN)  --- 15 byte
+
+  Number of User Codes   ------- 1 byt e
+  Current user code index 
+(for FIFO based addition/deletion of user codes)
+(should be set to 0xff if no user codes are present)  ---- 1 byte 
+
+User code1             ---------- 8 byte 
+User code 2      ---------- 8 byte 
+         | 
+         |
+ User code n (n = Max number of user codes for NS)  -- 8 byte
+
+
+  */
+         
+  if(!personalisation)
+  {
+    AciSLockShrd.blocked = TRUE;
+  }
+  else 
+  {
+    sim_code_present_in_me = FALSE; 
+  }
+  if((personalisation_sim NEQ NULL) AND ((UBYTE *)personalisation_sim->pBody NEQ NULL))
+  {
+    max_num_user_codes =((UBYTE *) personalisation_sim->pBody)[index];
+    index += MAX_NUM_USERCODE_SIZE;
+    
+    num_op_codes =((UBYTE *) personalisation_sim->pBody)[index];
+    index += NUM_OPCODE_SIZE;
+    
+    opcode_len =((UBYTE *) personalisation_sim->pBody)[index];
+    index +=OPCODE_LEN_SIZE;
+  
+    /*
+    * check operator defined code-groups
+    */
+    for(i=0; i< num_op_codes; i++)
+    {
+      code_type = ((UBYTE *)personalisation_sim->pBody)[index];
+      index +=CODE_TYPE_SIZE;
+      
+      switch(code_type)
+      {
+        case NORMAL_CODE :
+          memcpy(me_nw_ns_msin_code_bcd,&(((UBYTE *)personalisation_sim->pBody)[index]),NW_NS_MSIN_CODE_LEN);
+          index +=NW_NS_MSIN_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_ns_msin_code_bcd, NW_NS_MSIN_CODE_LEN, (char *)imsi_me);
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,MAX_IMSI_LEN) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              return; /* IMSI is matching a personalisation, so break! */
+            }
+          }
+          else 
+          {
+            sim_code_present_in_me= memcmp(imsi_sim,imsi_me,MAX_IMSI_LEN) EQ 0; 
+            if (sim_code_present_in_me EQ TRUE)
+            {
+              return; /* IMSI is matching a personalisation, so break! */
+            }
+          }
+        break;
+                
+        case INTERVAL_TYPE1 :
+          memcpy(me_nw_ns_msin_msin_code_bcd,&(((UBYTE *)personalisation_sim->pBody)[index]),NW_NS_MSIN_MSIN_CODE_LEN);
+          index +=NW_NS_MSIN_MSIN_CODE_LEN;
+          aci_slock_psaSIM_decodeIMSI(me_nw_ns_msin_msin_code_bcd, NW_NS_MSIN_MSIN_CODE_LEN, (char *)me_nw_ns_msin_msin_code_str); 
+          memcpy(me_nw_ns_code_str,me_nw_ns_msin_msin_code_str,simShrdPrm.mnc_len+3+2);
+          if(!personalisation)
+          {
+            AciSLockShrd.blocked = memcmp(imsi_sim,me_nw_ns_code_str,simShrdPrm.mnc_len+3/*MCC length*/+2 /* Ns code length*/) NEQ 0; 
+            if (AciSLockShrd.blocked EQ FALSE)
+            {
+              memcpy(me_msin_code_str,me_nw_ns_msin_msin_code_str+9/*skip the 'F'*/,(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/);
+              me_msin_code_str[(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/] = '\0';
+              me_msin_code_first = atoi((const char *)me_msin_code_str);
+  
+              memcpy(me_msin_code_str,me_nw_ns_msin_msin_code_str+9+8/*skip the 'F'*/,(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/);
+              me_msin_code_str[(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/] = '\0';
+              me_msin_code_last = atoi((const char *)me_msin_code_str);
+  
+              memcpy(imsi_sim_temp,imsi_sim+simShrdPrm.mnc_len+3+2,(MAX_IMSI_LEN - cfg_data->MNC_Len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/);
+              imsi_sim_temp[(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/] = '\0';
+              sim_msin_code = atoi((const char *)imsi_sim_temp);
+              if((sim_msin_code >= me_msin_code_first ) AND (sim_msin_code <= me_msin_code_last))
+              {
+                AciSLockShrd.blocked = FALSE;
+                return ;
+              }
+              else 
+                AciSLockShrd.blocked = TRUE;  
+            }
+          }
+          else 
+          {
+            sim_code_present_in_me= memcmp(imsi_sim,me_nw_ns_code_str,simShrdPrm.mnc_len+3/*MCC length*/+2 /* Ns code length*/) EQ 0; 
+            if (sim_code_present_in_me EQ  TRUE)
+            {
+              sim_code_present_in_me =  FALSE;
+                    
+              memcpy(me_msin_code_str,me_nw_ns_msin_msin_code_str+9/*skip the 'F'*/,(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/);
+              me_msin_code_str[(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/] = '\0';
+              me_msin_code_first = atoi((const char *)me_msin_code_str);
+  
+              memcpy(me_msin_code_str,me_nw_ns_msin_msin_code_str+9+8/*skip the 'F'*/,(MAX_IMSI_LEN -simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/);
+              me_msin_code_str[(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/] = '\0';
+              me_msin_code_last = atoi((const char *)me_msin_code_str);
+  
+              memcpy(imsi_sim_temp,imsi_sim+simShrdPrm.mnc_len+3+2,(MAX_IMSI_LEN - cfg_data->MNC_Len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/);
+              imsi_sim_temp[(MAX_IMSI_LEN - simShrdPrm.mnc_len+3/*MCC length*/+2/* Ns length*/)/* MSIN length*/] = '\0';
+              sim_msin_code = atoi((const char *)imsi_sim_temp);
+              if((sim_msin_code >= me_msin_code_first ) AND (sim_msin_code <= me_msin_code_last))
+              {
+                sim_code_present_in_me =  TRUE;
+                return ;
+              }
+            }
+          }
+        break;    
+                
+        case REGULAR_EXP :
+        break;
+        default :
+        break;
+      }
+    }
+
+    num_user_codes = ((UBYTE *)personalisation_sim->pBody)[index];
+    index +=NUM_USER_CODE_SIZE;
+
+    curr_user_code_index =((UBYTE *) personalisation_sim->pBody)[index];
+    index +=CURR_USER_CODE_INDEX_SIZE;
+
+    /*
+     * check user defined code-groups
+     */
+    for(i=0; i< num_user_codes; i++)
+    {
+      memcpy(me_nw_ns_msin_code_bcd,&(((UBYTE *)personalisation_sim->pBody)[index]),NW_NS_MSIN_CODE_LEN);
+      index +=NW_NS_MSIN_CODE_LEN;
+      aci_slock_psaSIM_decodeIMSI(me_nw_ns_msin_code_bcd, NW_NS_MSIN_CODE_LEN, (char *)imsi_me);
+      if(!personalisation)
+      {
+        AciSLockShrd.blocked = memcmp(imsi_sim,imsi_me,MAX_IMSI_LEN) NEQ 0; 
+        if (AciSLockShrd.blocked EQ FALSE)
+         return; /* IMSI is matching a personalisation, so break! */
+      }
+      else 
+      {
+        sim_code_present_in_me =  memcmp(imsi_sim,imsi_me,MAX_IMSI_LEN) EQ 0; 
+        if (sim_code_present_in_me EQ TRUE)
+         return; /* IMSI is matching a personalisation, so break! */
+      }
+    }
+  }
+}
+
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_checkpersonalisation
++------------------------------------------------------------------------------
+|  Description :   Checks for all kinds of personalisation locks (except sp & cp : Apr 03,2005). 
+|        The given IMSI will be checked against the internal personalisation data. 
+|        Returns SIMLOCK_BLOCKED, if one lock was not matching the given IMSI.
+|
+|  Parameters  :   None  
+|
+|  Return      : SIMLOCK_FAIL = -1,
+|         SIMLOCK_DISABLED,      No SIM lock check has to be done  
+|       SIMLOCK_PERM_DISABLED,
+|       SIMLOCK_ENABLED,       A SIM lock check has to be executed
+|       SIMLOCK_BLOCKED,       The SIM is blocked, i.e. because of a (or to many) wrong PIN(s) 
+|        SIMLOCK_LOCKED         The ME is locked because of wrong SIM 
+|
++------------------------------------------------------------------------------
+*/
+T_SIMLOCK_STATUS aci_slock_checkpersonalisation(T_SIMLOCK_TYPE   current_lock)
+{
+  T_SIMLOCK_TYPE type;
+
+  UBYTE imsi_sim[MAX_IMSI_LEN+1];
+  T_SIMLOCK_TYPE check_type;
+  T_SIMLOCK_STATUS sl_status;
+  T_AUTOLOCK_STATUS al_status;
+
+  TRACE_FUNCTION("aci_slock_checkpersonalisation()");
+     
+   psaSIM_decodeIMSI(simShrdPrm.imsi.field, simShrdPrm.imsi.c_field, (char *)imsi_sim); 
+  
+   /*
+  *  Test SIM
+  */
+    if(memcmp(imsi_sim,mnc_mcc,5) EQ 0)
+    {
+      aci_slock_set_simtype(SIM_TEST);
+       switch(cfg_data->TestCPHS)
+         {
+           case ALWAYS_ACCEPTED :
+                  TRACE_FUNCTION("TEST SIM: always accepted");
+                  return( aci_slock_check_done(SIMLOCK_ENABLED));
+             break;
+           case ALWAYS_REJECTED :  
+                  TRACE_FUNCTION("TEST SIM: always rejected");
+           break;
+         }
+    }
+  /*   
+  *  type approval
+  */
+    else if(aci_slock_sim_config.sim_read_ad_first_byte & 0x80)
+    {
+       TRACE_FUNCTION("sim type: Classic Test SIM (Type Approval SIM)");
+       aci_slock_set_simtype(SIM_TYPEAPPROVAL);
+     switch(cfg_data->TypeAprovalSIM)
+       {
+          case ALWAYS_ACCEPTED :
+          TRACE_FUNCTION("type approval: always accepted");
+          return( aci_slock_check_done(SIMLOCK_ENABLED));
+          break;
+        
+          case ALWAYS_REJECTED :  
+           TRACE_FUNCTION("type approval: always rejected");
+            for (type=SIMLOCK_NETWORK; type<=SIMLOCK_SIM; type++)
+            {
+              if(AciSLockShrd.status[type] EQ SIMLOCK_ENABLED)
+              {
+                sl_status = SIMLOCK_BLOCKED;
+                AciSLockShrd.blocked = TRUE;
+                break;
+               }
+            }
+           if(AciSLockShrd.blocked NEQ TRUE)
+           {  
+             sl_status = SIMLOCK_ENABLED ;
+           }
+          return(aci_slock_check_done(sl_status));
+        break;
+      
+         case UNTIL_NORMAL_SIM :
+         if(AciSLockShrd.status[SIMLOCK_FIRST_SIM] EQ SIMLOCK_ENABLED) /*11_Apr_05*/
+          {
+            AciSLockShrd.blocked = TRUE;
+            return(aci_slock_check_done(SIMLOCK_BLOCKED));
+          }
+         break;
+       }
+     }
+     /*
+       *Normal SIM 
+       */
+     else 
+     {
+       TRACE_FUNCTION("sim type: NORMAL SIM");
+        aci_slock_set_simtype(SIM_NORMAL );
+   
+     }
+
+if((cfg_data->FC_Current < cfg_data->FC_Max) OR (cfg_data->FC_Max EQ FC_MAX_INFINITE))
+ {
+       
+  if((aci_slock_sim_config.sim_type EQ SIM_NORMAL) AND (personalisation_first_sim NEQ NULL)
+       AND (AciSLockShrd.status[SIMLOCK_FIRST_SIM] EQ SIMLOCK_DISABLED) ) 
+  {
+           TRACE_FUNCTION("personalisation_first_sim NEQ NULL");
+           al_status =  aci_ext_auto_personalise(current_lock);
+           switch(al_status)
+           {
+            case AUTOLOCK_CMPL :
+                   return(aci_slock_check_done(SIMLOCK_ENABLED));
+            case AUTOLOCK_EXCT:
+                    return SIMLOCK_WAIT;  /* wait for gid1 andgid2 read cnf*/
+		case AUTOLOCK_FAIL:
+            default : 
+                    AciSLockShrd.blocked = TRUE;
+                   return (aci_slock_check_done(SIMLOCK_BLOCKED)); 
+            }
+            
+   }
+  else
+  {
+  
+  for (type=current_lock; type<=SIMLOCK_SIM; type++)
+  {
+    AciSLockShrd.current_lock=type;
+
+    if (AciSLockShrd.status[type] EQ SIMLOCK_ENABLED) /* initialised in aci_slock_init */
+    {
+      switch (type)
+      {
+        case SIMLOCK_NETWORK:          aci_slock_check_NWlock(imsi_sim, 0); break;
+        case SIMLOCK_NETWORK_SUBSET:   aci_slock_check_NSlock(imsi_sim, 0); break;
+        case SIMLOCK_SERVICE_PROVIDER:
+           if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1) )
+           {
+             if(aci_slock_sim_config.sim_read_gid1 EQ FALSE)
+             {
+               aci_slock_sim_read_sim(SIM_GID1, NOT_PRESENT_8BIT, MAX_GID);
+               return SIMLOCK_WAIT;
+             }
+           }
+          else 
+           {
+             AciSLockShrd.blocked = TRUE; 
+             return (aci_slock_check_done(SIMLOCK_BLOCKED));
+           }
+  
+            aci_slock_check_SPlock(imsi_sim, 0); 
+	      break;
+        case SIMLOCK_CORPORATE:      
+           if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
+           {
+            if(aci_slock_sim_config.sim_read_gid1 EQ FALSE)
+            	{
+               aci_slock_sim_read_sim(SIM_GID1, NOT_PRESENT_8BIT, MAX_GID);
+               return SIMLOCK_WAIT; 
+            	}
+            }
+           else 
+           {
+              AciSLockShrd.blocked = TRUE; 
+             return (aci_slock_check_done(SIMLOCK_BLOCKED));
+           }
+           if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
+           {
+            if(aci_slock_sim_config.sim_read_gid2 EQ FALSE)
+            	{
+                aci_slock_sim_read_sim(SIM_GID2, NOT_PRESENT_8BIT, MAX_GID);
+                return SIMLOCK_WAIT; 
+            	}
+           }
+           else 
+           {
+             AciSLockShrd.blocked = TRUE; 
+             return (aci_slock_check_done(SIMLOCK_BLOCKED));
+            }
+            aci_slock_check_CPlock(imsi_sim, 0); 
+	      break;
+		  
+        case SIMLOCK_SIM:              aci_slock_check_SMlock(imsi_sim, 0); break;  
+        default:                       return (aci_slock_check_done(SIMLOCK_FAIL)); /* won't happen */
+      }
+    }
+
+    if (AciSLockShrd.blocked)       /* if one lock isn't matching, don't try the others */
+      return (aci_slock_check_done(SIMLOCK_BLOCKED));
+  }
+ 
+return (aci_slock_check_done(SIMLOCK_ENABLED));
+  
+ }
+}
+else 
+{
+  AciSLockShrd.blocked = TRUE;
+  return (aci_slock_check_done(SIMLOCK_BLOCKED));
+}
+}
+
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_sim_init
++------------------------------------------------------------------------------
+|  Description :   Install information found in the primitive into configuration buffers
+|
+|  Parameters  :   sim_mmi_insert_ind- pointer to  T_SIM_MMI_INSERT_IND
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_sim_init ( T_SIM_MMI_INSERT_IND *sim_mmi_insert_ind )
+{
+  TRACE_FUNCTION("aci_slock_sim_init()");
+  
+  aci_slock_sim_config.oper_mode = sim_mmi_insert_ind->func;
+  memcpy(aci_slock_sim_service_table,sim_mmi_insert_ind->sim_serv,sizeof(aci_slock_sim_service_table));
+  
+  aci_slock_sim_config.phase = sim_mmi_insert_ind->phase;
+  aci_slock_sim_config.access_acm = sim_mmi_insert_ind->access_acm;
+  aci_slock_sim_config.access_acmmax = sim_mmi_insert_ind->access_acmmax;
+  aci_slock_sim_config.access_puct = sim_mmi_insert_ind->access_puct;
+  aci_slock_reset();
+
+}
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_sim_gid1_cnf
++------------------------------------------------------------------------------
+|  Description :   read SIM group identifier 1 from SIM card
+|  Parameters  :   error- error code
+|        data - gid1 data
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_sim_gid1_cnf(USHORT error, UBYTE *data)
+{
+  T_SIMLOCK_STATUS sl_status;
+  T_ACI_CME_ERR err_code;   /* code holding the correct error code for SIM LOCK */
+
+ TRACE_FUNCTION("aci_slock_sim_gid1_cnf()");
+  if (error EQ SIM_NO_ERROR)
+  {
+     aci_slock_sim_config.sim_read_gid1= TRUE;  //this flag will be used to check whether gid's were read
+    memcpy(aci_slock_sim_config.sim_gidl1, data, MAX_GID);
+    if(simEntStat.curCmd NEQ AT_CMD_NONE)
+    {
+      if(AciSLockShrd.check_lock EQ SIMLOCK_CHECK_LOCK)
+      	{
+      	  sl_status = aci_slock_lock(AciSLockShrd.lock_type, AciSLockShrd.lock_passwd);
+        aci_slock_check_done(sl_status);
+      	}
+	else if((AciSLockShrd.check_lock EQ SIMLOCK_CHECK_PERS) OR (AciSLockShrd.check_lock EQ SIMLOCK_CHECK_RESET_FC))
+      {
+              
+        /* check for SP and corporate personalisation. This is the first case, we can do this, as we have the gid1/gid2 file here */
+          sl_status= aci_slock_checkpersonalisation(AciSLockShrd.current_lock);
+	}
+       
+   }
+  }
+}
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_sim_gid2_cnf
++------------------------------------------------------------------------------
+|  Description :   read SIM group identifier 2 from SIM card
+|  Parameters  :   error- error code
+|        data - gid2 data
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_sim_gid2_cnf(USHORT error, UBYTE *data)
+{
+  T_SIMLOCK_STATUS sl_status;
+  T_ACI_CME_ERR err_code;   /* code holding the correct error code for SIM LOCK */
+
+  TRACE_FUNCTION("aci_slock_sim_gid2_cnf()");
+
+  if (error EQ SIM_NO_ERROR)
+  {
+    aci_slock_sim_config.sim_read_gid2= TRUE;  //this flag will be used to check whether gid's were read
+    memcpy(aci_slock_sim_config.sim_gidl2, data, MAX_GID);
+    if(simEntStat.curCmd NEQ AT_CMD_NONE)
+    {
+     if(AciSLockShrd.check_lock EQ SIMLOCK_CHECK_LOCK)
+      	{
+      	  sl_status = aci_slock_lock(AciSLockShrd.lock_type, AciSLockShrd.lock_passwd);
+        aci_slock_check_done(sl_status);
+      	}
+	else if((AciSLockShrd.check_lock EQ SIMLOCK_CHECK_PERS) OR (AciSLockShrd.check_lock EQ SIMLOCK_CHECK_RESET_FC))
+      {
+              
+        /* check for SP and corporate personalisation. This is the first case, we can do this, as we have the gid1/gid2 file here */
+          sl_status= aci_slock_checkpersonalisation(AciSLockShrd.current_lock);
+	}
+        
+    }
+ }
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_sim_read_sim_cb
++------------------------------------------------------------------------------
+|  Description :   Call back for SIM read.
+|  Parameters  :   table_id- 
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_sim_read_sim_cb(SHORT table_id)
+{
+
+  T_SIMLOCK_STATUS sl_status;
+  T_ACI_CME_ERR err_code;   /* code holding the correct error code for SIM LOCK */
+
+  TRACE_FUNCTION ("aci_slock_sim_read_sim_cb()");
+
+  simShrdPrm.atb[table_id].ntryUsdFlg = FALSE;
+
+  switch (simShrdPrm.atb[table_id].reqDataFld)
+  {
+    case SIM_GID1:
+      aci_slock_sim_config.gid1_len = simShrdPrm.atb[table_id].dataLen; 
+      aci_slock_sim_gid1_cnf(simShrdPrm.atb[table_id].errCode, simShrdPrm.atb[table_id].exchData); 
+      break;
+      
+    case SIM_GID2:
+      aci_slock_sim_config.gid2_len= simShrdPrm.atb[table_id].dataLen; 
+      aci_slock_sim_gid2_cnf(simShrdPrm.atb[table_id].errCode, simShrdPrm.atb[table_id].exchData); 
+      break;
+    default:
+      break;
+  }
+
+ }
+  
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_sim_read_sim
++------------------------------------------------------------------------------
+|  Description :    Request to read SIM card.
+|  Parameters  :   data_id    - data field identifier
+|        len      - actual length of data
+|        max_length  - max length of data
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_sim_read_sim(USHORT data_id, UBYTE len, UBYTE max_length)
+{
+  SHORT table_id;
+
+  TRACE_FUNCTION ("aci_slock_sim_read_sim()");
+  
+  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 = data_id;
+    simShrdPrm.atb[table_id].dataOff    = 0;
+    simShrdPrm.atb[table_id].dataLen    = len;
+    simShrdPrm.atb[table_id].recMax     = max_length;
+    simShrdPrm.atb[table_id].exchData   = NULL;
+    simShrdPrm.atb[table_id].rplyCB     = aci_slock_sim_read_sim_cb;
+
+    simShrdPrm.aId = table_id;
+  if(psaSIM_AccessSIMData() < 0)
+  {
+    TRACE_FUNCTION("abc FATAL ERROR");
+  }
+ }
+}
+
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_set_simtype
++------------------------------------------------------------------------------
+|  Description :    Setting the sim_type value (Normal, Test SIM, Type Approval SIM
+|  Parameters  :   sim_type    -   SIM_NORMAL =0,
+|                   SIM_TYPEAPPROVAL,
+|                   SIM_TEST
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_set_simtype(T_SIM_TYPE sim_type )
+{
+    aci_slock_sim_config.sim_type = sim_type; 
+}
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_slock_set_CFG
++------------------------------------------------------------------------------
+|  Description :    To set global variable for configuration data ( part1 of Security Driver)
+|  Parameters  :   none
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_slock_set_CFG(void)
+{
+  T_SEC_DRV_RETURN status ;
+  TRACE_FUNCTION("aci_slock_set_CFG()");  
+  status = sec_get_CFG(&cfg_data);
+  if(status NEQ SEC_DRV_RET_Ok)
+    cfg_data = NULL; 
+}
+
+
+
+
+
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_set_cme_error
++------------------------------------------------------------------------------
+|  Description :   Set the cme error using ACI_ERR_DESC
+|  Parameters  :   slocktype - lock type
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_set_cme_error(T_SIMLOCK_TYPE slocktype)
+{
+  switch (slocktype) 
+  {
+    case SIMLOCK_NETWORK:          
+      if(cfg_data->FC_Current  < cfg_data->FC_Max)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NetworkPersPinReq ); 
+      }
+      else 
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme,  CME_ERR_NetworkPersPukReq); 
+      }
+      break;
+    
+    case SIMLOCK_NETWORK_SUBSET:   
+      if(cfg_data->FC_Current  < cfg_data->FC_Max)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NetworkSubsetPersPinReq ); 
+      }
+      else 
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme,  CME_ERR_NetworkSubsetPersPukReq); 
+      }
+      break;
+
+    case SIMLOCK_SERVICE_PROVIDER: 
+      if(cfg_data->FC_Current  < cfg_data->FC_Max)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_ProviderPersPinReq ); 
+      }
+      else 
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme,  CME_ERR_ProviderPersPukReq); 
+      }
+      break;
+    
+    case SIMLOCK_CORPORATE:        
+      if(cfg_data->FC_Current  < cfg_data->FC_Max)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_CorporatePersPinReq ); 
+      }
+      else 
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme,  CME_ERR_CorporatePersPukReq); 
+      }
+      break;
+    
+    case SIMLOCK_SIM:              
+      if(cfg_data->FC_Current  < cfg_data->FC_Max)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_PhSimPinReq ); 
+      }
+      else 
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme,  CME_ERR_PhoneFail); 
+      }
+      break;
+     
+    default:                       
+    {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_WrongPasswd );            
+      break;
+    }
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+|  Function    : aci_set_cme_error_code
++------------------------------------------------------------------------------
+|  Description :   Set the cme error code 
+|  Parameters  :   err_code - cme error code
+|
+|  Return      : void
+|
++------------------------------------------------------------------------------
+*/
+void aci_set_cme_error_code(T_SIMLOCK_TYPE current_lock ,T_ACI_CME_ERR *err_code)
+{
+/* @GBR: Alternativly CME_ERR_SimWrong might be returned, but this way is telling the MMI mor specific, what went wrong. */
+  switch (current_lock)
+  {
+    case SIMLOCK_NETWORK:
+      if(cfg_data->FC_Current  < cfg_data->FC_Max)
+        *err_code = CME_ERR_NetworkPersPinReq ;
+      else
+        *err_code = CME_ERR_NetworkPersPukReq;
+      break;
+     
+     case SIMLOCK_NETWORK_SUBSET:
+     
+       if(cfg_data->FC_Current  < cfg_data->FC_Max)
+         *err_code = CME_ERR_NetworkSubsetPersPinReq ;
+       else
+         *err_code = CME_ERR_NetworkSubsetPersPukReq;
+     
+     break;
+
+     case SIMLOCK_SERVICE_PROVIDER:
+     
+       if(cfg_data->FC_Current  < cfg_data->FC_Max)
+         *err_code = CME_ERR_ProviderPersPinReq;
+       else
+         *err_code =  CME_ERR_ProviderPersPukReq;
+     
+     break;
+     
+     case SIMLOCK_CORPORATE:
+     
+       if(cfg_data->FC_Current  < cfg_data->FC_Max)
+         *err_code =  CME_ERR_CorporatePersPinReq ;
+       else
+         *err_code = CME_ERR_CorporatePersPukReq;
+     
+     break;
+     
+     case SIMLOCK_SIM:
+     
+       if(cfg_data->FC_Current  < cfg_data->FC_Max)
+         *err_code =  CME_ERR_PhSimPinReq;
+       else
+         *err_code = CME_ERR_PhoneFail;  /* for SIMLOCK_SIM there is no PUK available. Instead the phone is blocked and can only be                           unblocked by the manufacturer as an anti-theft protection. (See manual of several competitor phones ...) */
+     
+     break;
+     
+     case SIMLOCK_FIRST_SIM:
+     
+       if(cfg_data->FC_Current  < cfg_data->FC_Max)
+         *err_code = CME_ERR_PhFSimPinReq ;
+       else
+         *err_code = CME_ERR_PhFSimPukReq;
+     
+     break;
+     
+     default:
+       *err_code = CME_ERR_Unknown;
+     break;
+  }
+
+}
+
+
+void aci_slock_reset()
+{
+   aci_slock_sim_config.sim_gidl1[0] = NOT_PRESENT_8BIT;
+   aci_slock_sim_config.sim_gidl2[0] = NOT_PRESENT_8BIT;
+   aci_slock_sim_config.sim_read_gid1= FALSE; 
+   aci_slock_sim_config.sim_read_gid2= FALSE;
+ }
+
+
+T_SIMLOCK_STATUS aci_slock_check_done(T_SIMLOCK_STATUS sl_status)
+{
+
+UBYTE cmdBuf;   
+T_ACI_CME_ERR err_code = CME_ERR_NotPresent; /* code holding the correct error code calculated */
+
+TRACE_FUNCTION_P1 ("aci_slock_check_done() %d",simEntStat.curCmd );
+  switch( simEntStat.curCmd )
+  {
+    case( AT_CMD_CFUN ):
+    case( AT_CMD_CPIN ):
+    case( AT_CMD_PVRF ):
+    case(AT_CMD_NRG) : 
+    case( AT_CMD_SIMRST):
+    case( AT_CMD_NONE ):
+    case (AT_CMD_CIMI):
+    case( KSD_CMD_UBLK):
+      /*
+       * Start to build phonebook
+       */
+       AciSLockShrd.pb_load = TRUE;
+       pb_reset();
+
+#ifdef TI_PS_FFS_PHB
+      if(last_sim_mmi_insert_ind NEQ NULL)
+      {
+        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
+      if(last_sim_mmi_insert_ind NEQ NULL)
+      {
+        pb_build_req(last_sim_mmi_insert_ind);
+      }
+#endif
+
+       /* Request the Customer Service Profile  from the SIM (EF_CPHS_CSP) */
+       cmhSIM_Get_CSP();
+       if(last_sim_mmi_insert_ind  NEQ NULL)
+        {
+           #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();
+      aci_ext_personalisation_free();
+      MFREE(cfg_data);
+      break;
+	  
+    case (AT_CMD_CLCK):
+
+	if(AciSLockShrd.check_lock  EQ SIMLOCK_CHECK_RESET_FC)
+	{
+	    cmdBuf = simEntStat.curCmd;
+          simEntStat.curCmd = AT_CMD_NONE;
+	    if((sl_status EQ SIMLOCK_ENABLED) AND (AciSLockShrd.pb_load EQ FALSE))
+          {
+               /*
+             * Start to build phonebook
+             */
+             AciSLockShrd.pb_load = TRUE;
+             pb_reset();
+
+#ifdef TI_PS_FFS_PHB
+        if(last_sim_mmi_insert_ind NEQ NULL)
+        {
+          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
+        if(last_sim_mmi_insert_ind NEQ NULL)
+        {
+          pb_build_req(last_sim_mmi_insert_ind);
+        }
+#endif
+
+            /* Request the Customer Service Profile  from the SIM (EF_CPHS_CSP) */
+             cmhSIM_Get_CSP();
+
+           if(last_sim_mmi_insert_ind NEQ NULL)
+            {
+             #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;  
+            }
+            R_AT( RAT_OK, simEntStat.entOwn ) ( cmdBuf );
+           cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, -1, -1 );
+         }
+          if ( AciSLockShrd.blocked)
+          {
+            /* @GBR: Alternativly CME_ERR_SimWrong might be returned, but this way is telling the MMI mor specific, what went wrong. */
+             aci_set_cme_error_code(AciSLockShrd.current_lock,&err_code);
+             R_AT( RAT_CME, simEntStat.entOwn )
+             ( cmdBuf, err_code );
+             cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf, -1, -1, err_code );
+          }
+         aci_ext_personalisation_free();
+         MFREE(cfg_data);
+	}
+	
+	else if(AciSLockShrd.check_lock  EQ SIMLOCK_CHECK_LOCK)
+	{
+     
+       switch(sl_status)
+       {
+        case SIMLOCK_ENABLED :
+                cmdBuf = simEntStat.curCmd;
+                simEntStat.curCmd = AT_CMD_NONE;
+                R_AT( RAT_OK, simEntStat.entOwn ) ( cmdBuf );
+                cmh_logRslt ( simEntStat.entOwn, RAT_OK, cmdBuf, -1, -1, -1 );
+                break; 
+       case SIMLOCK_WAIT : 
+                break; 
+       case SIMLOCK_FAIL :
+	   	    cmdBuf = simEntStat.curCmd;
+                 simEntStat.curCmd = AT_CMD_NONE;
+                 err_code =CME_ERR_WrongPasswd;
+                 R_AT( RAT_CME, simEntStat.entOwn )
+                 ( cmdBuf, err_code );
+                 cmh_logRslt ( simEntStat.entOwn, RAT_CME, cmdBuf, -1, -1, err_code );
+                break;
+       }
+     }
+     break; 
+          
+  }
+ return sl_status;
+}
+
+#endif