FreeCalypso > hg > fc-magnetite
view src/aci2/aci/aci_slock.c @ 362:4c3d05866531
FCHG: beginning of the new version
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 Dec 2017 07:06:06 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | 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