FreeCalypso > hg > fc-magnetite
diff src/aci2/aci/aci_slock.c @ 3:93999a60b835
src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 26 Sep 2016 00:29:36 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/aci2/aci/aci_slock.c Mon Sep 26 00:29:36 2016 +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