FreeCalypso > hg > fc-magnetite
view src/g23m-gsm/sim/sim_fkt.c @ 639:026c98f757a6
tpudrv12.h & targets/gtm900.h: our current support is for MGC2GSMT version only
As it turns out, there exist two different Huawei-made hw platforms both
bearing the marketing name GTM900-B: one is MG01GSMT, the other is MGC2GSMT.
The two are NOT fw-compatible: aside from flash chip differences which
should be handled by autodetection, the two hw platforms are already known
to have different RFFEs with different control signals, and there may be
other differences not yet known. Our current gtm900 build target is for
MGC2GSMT only; we do not yet have a specimen of MG01GSMT on hand, hence
no support for that version will be possible until and unless someone
provides one.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 30 Jan 2020 18:19:01 +0000 |
parents | 27a4235405c6 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-F&D (8411) | Modul : SIM_FKT +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This modul defines the wrapping functions for the | SIM application. +----------------------------------------------------------------------------- */ #ifndef SIM_FKT_C #define SIM_FKT_C #define ENTITY_SIM /*==== INCLUDES ===================================================*/ #include <string.h> #include "typedefs.h" #include "pconst.cdg" #include "message.h" #include "ccdapi.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "cnf_sim.h" #include "mon_sim.h" #include "prim.h" #include "pei.h" #include "tok.h" #include "sim.h" #include "sim_em.h" /*==== EXPORT =====================================================*/ #ifdef _SIMULATION_ LOCAL USHORT first_time_into_fkt_select = TRUE; LOCAL USHORT file_id; #endif GLOBAL USHORT stk_l_cmd = 0; /*==== PRIVAT =====================================================*/ /*==== VARIABLES ==================================================*/ /*==== FUNCTIONS ===================================================*/ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_check_pin_count | +--------------------------------------------------------------------+ PURPOSE : PIN/PUK count is checked for secret code initialisation. count is set to zero, if not initialised, otherwise the initialisation flag (most significant bit) is reset. */ GLOBAL UBYTE FKT_check_pin_count (UBYTE count) { if ((count & 0x80) EQ 0) return 0; return count & 0x0F; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_convert_error | +--------------------------------------------------------------------+ PURPOSE : Converts sw1 and sw2 to an unique error code for the SIM application. */ /* * PIN/PUK is wrong, remaining attempts */ const static USHORT sim_inv_chv_A [6] = { /* last requested PIN no error code */ /* none */ SIM_CAUSE_OTHER_ERROR, /* PIN 1 */ SIM_CAUSE_PIN1_EXPECT, /* PIN 2 */ SIM_CAUSE_PIN2_EXPECT, /* PUK 1 */ SIM_CAUSE_PUK1_EXPECT, /* PUK 2 */ SIM_CAUSE_PUK2_EXPECT, /* NEVER */ SIM_CAUSE_ACCESS_PROHIBIT }; /* * PIN/PUK is wrong, no remaining attempts */ const static USHORT sim_inv_chv_B [6] = { /* last requested PIN no error code */ /* none */ SIM_CAUSE_OTHER_ERROR, /* PIN 1 */ SIM_CAUSE_PIN1_BLOCKED, /* PIN 2 */ SIM_CAUSE_PIN2_BLOCKED, /* PUK 1 */ SIM_CAUSE_PUK1_BLOCKED, /* PUK 2 */ SIM_CAUSE_PUK2_BLOCKED, /* NEVER */ SIM_CAUSE_OTHER_ERROR }; GLOBAL USHORT FKT_convert_error (USHORT sw1sw2, USHORT size) { TRACE_FUNCTION ("FKT_convert_error()"); sim_data.sw1 = (UBYTE)(sw1sw2 >> 8); sim_data.sw2 = (UBYTE)sw1sw2; TRACE_EVENT_P2 ("SW1=%02X SW2=%02X", sim_data.sw1, sim_data.sw2); switch (sim_data.sw1) { case 0x00: /* * SIM driver error */ if (SIM_IS_FLAG_CLEARED(SIM_INSERT)) { return SIM_CAUSE_CARD_REMOVED; } if (sim_data.sw2 EQ 14) { SIM_SET_FLAG(DRV_FAILED_RETRY); return SIM_CAUSE_DRV_TEMPFAIL; } return CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, SIM_ORIGINATING_ENTITY, sim_data.sw2); #if defined SIM_TOOLKIT case 0x9E: /* * use SW2 as length indicator for * the following get response */ if (sim_data.sim_phase >= 3) /* Phase 2+ or higher */ { if (sim_data.stk_profile[0] & SAT_TP1_9E_XX) { sim_data.sim_data_len = (sim_data.sw2 EQ 0)? 0x100: (USHORT)sim_data.sw2; return SIM_CAUSE_DNL_ERROR; } else return SIM_CAUSE_SAT_BUSY; } else return SIM_CAUSE_OTHER_ERROR; case 0x93: if (sim_data.sim_phase >= 3) /* Phase 2+ or higher */ { return SIM_CAUSE_SAT_BUSY; } else return SIM_CAUSE_OTHER_ERROR; case 0x91: if (sim_data.sim_phase >= 3) /* Phase 2+ or higher */ { sim_data.proactive_sim_data_len = (sim_data.sw2 EQ 0)? 0x100: (SHORT)sim_data.sw2; return SIM_NO_ERROR; } else return SIM_CAUSE_OTHER_ERROR; #endif case 0x92: if (sim_data.sw2 > 0xF) { #ifdef REL99 if (sim_data.sw2 EQ SW2_MEMORY_PROBLEM) { return SIM_CAUSE_MEM_PROBLEM; } #endif /* end of ifdef REL99 */ return SIM_CAUSE_OTHER_ERROR; } /* no break (otherwise the command was successful) */ case 0x90: if( (size >= 0) AND (size <= 0x100) ) { sim_data.sim_data_len = size; TRACE_EVENT_P1 ("sim_data.sim_data_len updated size =%X ", size); } return SIM_NO_ERROR; case 0x9F: /* * use SW2 as length indicator for * the following get response */ sim_data.sim_data_len = (sim_data.sw2 EQ 0)? 0x100: (USHORT)sim_data.sw2; return SIM_NO_ERROR; case 0x94: switch (sim_data.sw2) { case 0: return SIM_CAUSE_NO_SELECT; case 2: return SIM_CAUSE_ADDR_WRONG; case 4: return SIM_CAUSE_UNKN_FILE_ID; case 8: return SIM_CAUSE_CMD_INCONSIST; default: break; } break; case 0x98: TRACE_EVENT_P1 ("LRP = %d", (int)sim_data.last_requested_pin_no); switch (sim_data.sw2) { case 2: return SIM_CAUSE_CHV_NOTSET; case 8: return SIM_CAUSE_CHV_VALIDATED; case 0x10: return SIM_CAUSE_EF_INVALID; /* contradiction cases */ case 4: return sim_inv_chv_A [sim_data.last_requested_pin_no]; case 0x40: return sim_inv_chv_B [sim_data.last_requested_pin_no]; case 0x50: return SIM_CAUSE_MAX_INCREASE; default: break; } break; } return SIM_CAUSE_OTHER_ERROR; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_ChangeCHV | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_ChangeCHV. */ GLOBAL USHORT FKT_ChangeCHV (UBYTE * old_pin, UBYTE * new_pin, UBYTE pin_id) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_ChangeCHV()"); sw1sw2 = SIM_ChangeCHV ((UBYTE *)response, (UBYTE *)old_pin, (UBYTE *)new_pin, (UBYTE)pin_id, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_DisableCHV | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_DisableCHV. */ GLOBAL USHORT FKT_DisableCHV (UBYTE * pin) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_DisableCHV()"); sw1sw2 = SIM_DisableCHV ((UBYTE *)response, (UBYTE *)pin, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_EnableCHV | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_EnableCHV. */ GLOBAL USHORT FKT_EnableCHV (UBYTE * pin) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_EnableCHV()"); sw1sw2 = SIM_EnableCHV ((UBYTE *)response, (UBYTE *)pin, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_GetResponse | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_GetResponse. */ GLOBAL USHORT FKT_GetResponse (UBYTE * data, USHORT len) { USHORT size = 0; USHORT sw1sw2; TRACE_FUNCTION ("FKT_GetResponse()"); sw1sw2 = SIM_GetResponse ((UBYTE *)data, len, &size); return FKT_convert_error (sw1sw2, len); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_Increase | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Increase. */ GLOBAL USHORT FKT_Increase (UBYTE * data) { USHORT sw1sw2; USHORT size = 0; UBYTE response[4]; TRACE_FUNCTION ("FKT_Increase()"); sw1sw2 = SIM_Increase ((UBYTE *)response, (UBYTE *)data, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_Invalidate | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Invalidate. */ GLOBAL USHORT FKT_Invalidate (void) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_Invalidate()"); sw1sw2 = SIM_Invalidate ((UBYTE *)response, &size); if (sw1sw2 EQ 0x9810) /* already invalidated */ return SIM_NO_ERROR; return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_ReadBinary | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_ReadBinary. */ GLOBAL USHORT FKT_ReadBinary (UBYTE * data, USHORT offset, USHORT length) { USHORT sw1sw2; USHORT size = 0; TRACE_FUNCTION ("FKT_ReadBinary()"); sw1sw2= SIM_ReadBinary ((UBYTE *)data, offset, length, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_ReadRecord | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_ReadRecord. */ GLOBAL USHORT FKT_ReadRecord (UBYTE * data, UBYTE mode, USHORT record, USHORT length) { USHORT sw1sw2; USHORT size = 0; #if !defined NTRACE char buf[48]; sprintf (buf, "FKT_ReadRecord(): Nr. %hu", record); TRACE_FUNCTION (buf); #endif sw1sw2 = SIM_ReadRecord ((UBYTE *)data, (UBYTE)mode, (UBYTE)record, length, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_Rehabilitate | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Rehabilitate. */ GLOBAL USHORT FKT_Rehabilitate (void) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_Rehabilitate()"); sw1sw2 = SIM_Rehabilitate ((UBYTE *)response, &size); if (sw1sw2 EQ 0x9810) /* already rehabilitated */ return SIM_NO_ERROR; return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_Status | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Status. */ GLOBAL USHORT FKT_Status (UBYTE * pin_cnt, UBYTE * pin2_cnt, UBYTE * puk_cnt, UBYTE * puk2_cnt) { USHORT size = 0; USHORT sw1sw2; USHORT cause; USHORT fileid; union { T_DIR_STATUS status; UBYTE response [40]; } dir; TRACE_FUNCTION ("FKT_Status()"); memset (dir.response, 0, sizeof(dir.response)); sw1sw2 = SIM_Status_Extended (dir.response, sim_data.dir_status_len, &size); cause = FKT_convert_error (sw1sw2, size); *pin_cnt = 0; *puk_cnt = 0; *pin2_cnt = 0; *puk2_cnt = 0; if (cause EQ SIM_NO_ERROR) { /* * Check file id on active call: if different from last directory * indicate failure during SIM Presence Detection (27.20). * A selection of a non-existent DF (possible with SIM_ACCESS_REQ) * leads to the loss of the current DF: this confuses the SIM * Presence Detection, therefore the validity of the actual DF * stored in 'sim_data.act_directory' must be considered. */ fileid = (dir.status.fileid[0] << 8) | dir.status.fileid[1]; if (SIM_IS_FLAG_SET (CALL_ACTIVE) AND /* call active */ sim_data.act_directory NEQ NOT_PRESENT_16BIT /* actual DF known? */ AND fileid NEQ sim_data.act_directory) /* compare DF */ return SIM_CAUSE_CARD_REMOVED; else { if (SIM_TI_DRV_X_BYTES > 0) /* discard SW1, SW2 from response! */ memset (&dir.response[sim_data.dir_status_len], 0, SIM_TI_DRV_X_BYTES); /* * Directory status is available */ *pin_cnt = FKT_check_pin_count (dir.status.pinstatus); *puk_cnt = FKT_check_pin_count (dir.status.unbstatus); *pin2_cnt = FKT_check_pin_count (dir.status.pin2status); *puk2_cnt = FKT_check_pin_count (dir.status.unb2status); } } return cause; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_RunGSMAlgo | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_RunGSMAlgo. */ GLOBAL USHORT FKT_RunGSMAlgo (UBYTE * rand, UBYTE * data, USHORT len) { UBYTE response[4]; USHORT sw1sw2; USHORT error; USHORT size = 0; TRACE_FUNCTION ("FKT_RunGSMAlgo()"); sw1sw2 = SIM_RunGSMAlgo ((UBYTE *)response, (UBYTE *)rand, &size); error = FKT_convert_error (sw1sw2, size); if (error EQ SIM_NO_ERROR) error = FKT_GetResponse (data, len); return error; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_Select | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Select. */ LOCAL USHORT fkt_select_one (USHORT id, UBYTE * data, USHORT len) { USHORT size = 0; USHORT sw1sw2; USHORT error; UBYTE response[4]; sw1sw2 = SIM_Select (id, (UBYTE *)response, &size); error = FKT_convert_error (sw1sw2, size); if (error EQ SIM_NO_ERROR) { if( (data NEQ NULL ) AND (len NEQ 0 ) #ifdef _SIMULATION_ AND (id EQ file_id) #endif ) { #ifdef _SIMULATION_ len = (sim_data.sim_data_len < len)? sim_data.sim_data_len: len; first_time_into_fkt_select = TRUE; #endif error = FKT_GetResponse (data, sim_data.sim_data_len); } } return error; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : sim_select_df | +--------------------------------------------------------------------+ PURPOSE : Function to select the directory given the path. */ LOCAL USHORT sim_select_df(U16 dir_level,UBYTE *data,USHORT len) { USHORT result = SIM_NO_ERROR; result = fkt_select_one (dir_level, data, len); if (result NEQ SIM_NO_ERROR) { sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; } else { sim_data.act_directory = dir_level; } return result; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_Select | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Select. */ GLOBAL USHORT FKT_Select (USHORT id, BOOL path_info_present, T_path_info * path_info_ptr, UBYTE * data, USHORT len) { USHORT result; USHORT directory = (SIM_IS_FLAG_SET (GSM_DATAFIELD))? SIM_DF_GSM: SIM_DF_1800; /* default parent directory */ #if !defined NTRACE char buf[32]; sprintf (buf, "FKT_Select(): id = %04X", id); TRACE_FUNCTION (buf); #endif #ifdef _SIMULATION_ if( (first_time_into_fkt_select EQ TRUE ) AND (data NEQ NULL) AND (len NEQ 0) ) file_id = id; #endif switch (id & 0xFF00) /* selecting DF deselects EF */ { case 0x3F00: case 0x7F00: case 0x5F00: sim_data.act_field = NOT_PRESENT_16BIT; break; } if( path_info_present NEQ FALSE ) { if((sim_data.act_directory & 0xFF00) NEQ 0x5F00 AND sim_data.act_directory NEQ NOT_PRESENT_16BIT) { /* Currently selected df is MF or a first level directory */ if(sim_data.act_directory NEQ path_info_ptr->df_level1) { result = sim_select_df(path_info_ptr->df_level1,data,len); if(result NEQ SIM_NO_ERROR) return result; } } /* Currently selected df is a second level directory */ else { result = sim_select_df(SIM_MF,data,len); if(result NEQ SIM_NO_ERROR) return result; result = sim_select_df(path_info_ptr->df_level1,data,len); if(result NEQ SIM_NO_ERROR) return result; } if(path_info_ptr->v_df_level2) { result = sim_select_df(path_info_ptr->df_level2,data,len); if(result NEQ SIM_NO_ERROR) return result; } result = fkt_select_one (id, data, len); if (result NEQ SIM_NO_ERROR) { sim_data.act_field = NOT_PRESENT_16BIT; } else { sim_data.act_field = id; } return result; } else { switch (id) { case SIM_MF: result = fkt_select_one (SIM_MF, data, len); if (result NEQ SIM_NO_ERROR) sim_data.act_directory = NOT_PRESENT_16BIT; else { sim_data.dir_status_len = sim_data.sim_data_len; sim_data.act_directory = id; } return result; default: /* All the standard defined EFs would be handled before coming to this * point. Complete path information should be given for non-standard 2nd level EFs * and they also would be handled before coming to this point. * This statement will be hit for non-standard files * without path information. Hence returning error */ return SIM_CAUSE_UNKN_FILE_ID; break; /* any other elementary file */ /* continue here in case of any first level directory */ case SIM_DF_GSM: case SIM_DF_1800: case SIM_DF_TELECOM: case SIM_DF_VI: case SIM_DF_ORANGE: if (sim_data.act_directory EQ id) return SIM_NO_ERROR; /* already selected */ else { /* If current directory has not been selected or it is a 2nd level and under another 1st level DF */ if (((sim_data.act_directory & 0xFF00) EQ 0x5F00 AND ! SIM_IS_DF_LEVEL2_UNDER_DF_LEVEL1(sim_data.act_directory,id)) OR sim_data.act_directory EQ NOT_PRESENT_16BIT) { /* MF has to be selected first */ result = sim_select_df(SIM_MF,data,len); if(result NEQ SIM_NO_ERROR) return result; } result = fkt_select_one (id, data, len); if (result NEQ SIM_NO_ERROR) { sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; } else { sim_data.dir_status_len = sim_data.sim_data_len; sim_data.act_directory = id; } return result; } case SIM_DF_GRAPHICS: directory = SIM_DF_TELECOM; /* parent directory */ /* no break */ /*lint -fallthrough*/ case SIM_DF_SOLSA: case SIM_DF_MEXE: if (sim_data.act_directory EQ id) return SIM_NO_ERROR; /* already selected */ if (sim_data.act_directory NEQ directory) { /* not the parent directory */ /* If current directory is MF or first level OR if the 2nd level directory is under another 1st level df, select the parent directory */ if((sim_data.act_directory & 0xFF00) NEQ 0x5F00 || (!SIM_IS_DF_LEVEL2_UNDER_DF_LEVEL1(sim_data.act_directory,directory)) ) { result = FKT_Select (directory, FALSE, NULL, data, len); if (result NEQ SIM_NO_ERROR) { sim_data.act_directory = NOT_PRESENT_16BIT; return result; } } } result = fkt_select_one (id, data, len); if (result NEQ SIM_NO_ERROR) { sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; } else { sim_data.dir_status_len = sim_data.sim_data_len; sim_data.act_directory = id; } return result; case SIM_ICCID: case SIM_ELP: /* * Access to Root Directory */ directory = SIM_MF; break; case SIM_ADN: case SIM_FDN: case SIM_SMS: case SIM_CCP: case SIM_MSISDN: case SIM_SMSP: case SIM_SMSS: case SIM_LND: case SIM_SMSR: case SIM_SDN: case SIM_EXT1: case SIM_EXT2: case SIM_EXT3: case SIM_BDN: case SIM_EXT4: /* VO temp PATCH: Needed for reading CPHS info num from old SIMs */ case SIM_CPHS_INFN2: /* VO temp PATCH end */ /* * Access to Telecom Directory */ directory = SIM_DF_TELECOM; break; case SIM_LP: case SIM_IMSI: case SIM_KC: case SIM_PLMNSEL: case SIM_HPLMN: case SIM_ACMMAX: case SIM_SST: case SIM_ACM: case SIM_GID1: case SIM_GID2: case SIM_PUCT: case SIM_CBMI: case SIM_SPN: case SIM_CBMID: case SIM_BCCH: case SIM_ACC: case SIM_FPLMN: case SIM_LOCI: case SIM_AD: case SIM_PHASE: case SIM_VGCS: case SIM_VGCSS: case SIM_VBS: case SIM_VBSS: case SIM_EMLPP: case SIM_AAEM: case SIM_ECC: case SIM_CBMIR: case SIM_DCK: case SIM_CNL: case SIM_NIA: case SIM_KCGPRS: case SIM_LOCGPRS: case SIM_SUME: case SIM_CPHS_VMW: case SIM_CPHS_SST: case SIM_CPHS_CFF: case SIM_CPHS_ONSTR: case SIM_CPHS_CSP: case SIM_CPHS_CINF: case SIM_CPHS_MBXN: case SIM_CPHS_ONSHF: case SIM_CPHS_INFN: #ifdef REL99 case SIM_UCPS_ACTEC: case SIM_OCPS_ACTEC: case SIM_HPLMN_ACT: case SIM_CPBCCH: case SIM_INV_SCAN: case SIM_RPLMN_ACT: #endif /* REL99 */ case SIM_PNN: case SIM_OPL: /* * Access to GSM */ directory = (SIM_IS_FLAG_SET (GSM_DATAFIELD))? SIM_DF_GSM: SIM_DF_1800; break; #ifndef REL99 case SIM_VI_HZ_PARAM: case SIM_VI_HZ_CACHE_1: case SIM_VI_HZ_CACHE_2: case SIM_VI_HZ_CACHE_3: case SIM_VI_HZ_CACHE_4: directory = SIM_DF_VI; break; #endif /* ifndef REL99 */ case SIM_MEXE_ST: case SIM_ORPK: case SIM_ARPK: case SIM_TPRPK: /* * Access to MExE Directory */ directory = SIM_DF_MEXE; break; case SIM_IMG: /* * Access to Icon Directory */ directory = SIM_DF_GRAPHICS; break; case SIM_ORANGE_DYN2_FLAG: case SIM_ORANGE_CSP2: case SIM_ORANGE_ACM2: case SIM_ORANGE_DYN_FLAGS: /* * Access to Orange Directory */ directory = SIM_DF_ORANGE; break; case SIM_SAI: case SIM_SLL: /* * Access to SoLSA Directory */ directory = SIM_DF_SOLSA; break; } } if (sim_data.act_directory NEQ directory) { /* * select directory */ #ifdef _SIMULATION_ if( (data NEQ NULL) AND (len NEQ 0) ) first_time_into_fkt_select = FALSE; #endif result = FKT_Select (directory, FALSE, NULL, data, len); if (result NEQ SIM_NO_ERROR) /* directory selection fails */ { sim_data.act_directory = NOT_PRESENT_16BIT; sim_data.act_field = NOT_PRESENT_16BIT; return result; } } if (sim_data.act_field NEQ id) { /* * secondly select elementary field */ result = fkt_select_one (id, data, len); if (result NEQ SIM_NO_ERROR) /* EF selection fails */ { sim_data.act_field = NOT_PRESENT_16BIT; #ifdef __INVALID /* more sophisticated SELECT error handling */ sw1 = (UBYTE)(SIM_Status_Extended ((UBYTE *)response, 6, &size) >> 8); if (sw1 NEQ 0x90 AND sw1 NEQ 0x91) /* * SIM Status request failed */ sim_data.act_directory = NOT_PRESENT_16BIT; else if (((response[4] << 8) | response[5]) NEQ sim_data.act_directory) /* * SIM Presence Detection indicates invalid SIM */ sim_data.act_directory = NOT_PRESENT_16BIT; #endif } else { sim_data.act_directory = directory; sim_data.act_field = id; } return result; } else /* * field is already selected */ return SIM_NO_ERR_FILE_ALREADY_SELECTED; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_UnblockCHV | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_UnblockCHV. */ GLOBAL USHORT FKT_UnblockCHV (UBYTE * unblockCHV, UBYTE * new_CHV, UBYTE chvType) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_UnblockCHV()"); sw1sw2 = SIM_UnblockCHV ((UBYTE *)response, (UBYTE *)unblockCHV, (UBYTE *)new_CHV, (UBYTE)chvType, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_UpdateBinary | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_UpdateBinary. */ GLOBAL USHORT FKT_UpdateBinary (UBYTE * data, USHORT length, USHORT offset) { USHORT size = 0; USHORT sw1sw2; UBYTE response [4]; TRACE_FUNCTION ("FKT_UpdateBinary()"); sw1sw2 = SIM_UpdateBinary ((UBYTE *)response, (UBYTE *)data, offset, length, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_UpdateRecord | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_UpdateRecord. */ GLOBAL USHORT FKT_UpdateRecord (UBYTE * data, USHORT length, UBYTE mode, USHORT record) { USHORT size = 0; USHORT sw1sw2; UBYTE response [4]; #if !defined NTRACE char buf[48]; sprintf (buf, "FKT_UpdateRecord(): Nr. %hu", record); TRACE_FUNCTION (buf); #endif sw1sw2 = SIM_UpdateRecord ((UBYTE *)response, (UBYTE *)data, (UBYTE)mode, (UBYTE)record, length, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6302) MODULE : SIM_FKT | | STATE : code ROUTINE : FKT_VerifyCHV | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_VerifyCHV. */ GLOBAL USHORT FKT_VerifyCHV (UBYTE * pin, UBYTE pin_id) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_VerifyCHV()"); sw1sw2 = SIM_VerifyCHV ((UBYTE *)response, (UBYTE *)pin, (UBYTE)pin_id, &size); return FKT_convert_error (sw1sw2, size); } /* +********************************************************************+ | Moved from sim_stk.c - for CQ 34109 under feature flag SIM_TOOLKIT | +********************************************************************+ */ #ifdef SIM_TOOLKIT static const UBYTE timer_env[] = { STK_TIMER_EXPIRATION_TAG, STK_DEVICE_IDENTITY_LEN+STK_TIMER_ID_LEN+STK_TIMER_VALUE_LEN+6, STK_DEVICE_IDENTITY_TAG|STK_COMPREHENSION_REQUIRED, STK_DEVICE_IDENTITY_LEN, 0x82, 0x81, STK_TIMER_ID_TAG|STK_COMPREHENSION_REQUIRED, STK_TIMER_ID_LEN, 0, STK_TIMER_VALUE_TAG|STK_COMPREHENSION_REQUIRED, STK_TIMER_VALUE_LEN, 0, 0, 0 }; UBYTE pending_timers[9] = {0,0,0,0,0,0,0,0,0}; UBYTE next_pos_to_fill = 0; UBYTE next_pos_to_send = 0; /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : FKT_TerminalResponse | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_TerminalResponse */ GLOBAL USHORT FKT_TerminalResponse (UBYTE * data, USHORT length) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; UBYTE env[sizeof(timer_env)]; USHORT index; UBYTE dummy[4]; USHORT error; USHORT i; TRACE_FUNCTION ("FKT_TerminalResponse()"); sw1sw2 = SIM_TerminalResponse (response, data, length, &size); sim_data.term_resp_sent = TRUE; SIM_EM_TERMINAL_RESPONSE; /* * if SIM response is OK, try resending pending timer expiry envelopes (send updated envelopes) */ if( 0x9000 == sw1sw2 ) { for(i=0;i<8;i++) { if (next_pos_to_fill != next_pos_to_send) { /* * some timer expiry envelopes are pending */ index = pending_timers[next_pos_to_send]; memcpy (env, timer_env, sizeof(timer_env)); env[8] = (UBYTE)(index + 1); /* Timer number range is 1..8 */ env[11] = sim_data.timer[index].hour; env[12] = sim_data.timer[index].minute; env[13] = sim_data.timer[index].second; error = FKT_Envelope (dummy, env, sizeof(timer_env),0); if(8 == next_pos_to_send) { next_pos_to_send = 0; } else { next_pos_to_send++; } if (error NEQ SIM_NO_ERROR) { break; } } } } return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : FKT_Envelope | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Envelope */ GLOBAL USHORT FKT_Envelope (UBYTE * data_out, UBYTE * data_in, USHORT in_length, USHORT out_length) { USHORT size = 0; USHORT sw1sw2; USHORT error; TRACE_FUNCTION ("FKT_Envelope()"); sw1sw2 = SIM_Envelope (data_out, data_in, in_length, &size); SIM_EM_ENVELOPE; error = FKT_convert_error (sw1sw2, size); if(sw1sw2 EQ 0x9000) sim_data.sim_data_len = 0; if (error EQ SIM_NO_ERROR) { if (data_out AND out_length) { if (sim_data.sim_data_len > 0) { stk_l_cmd = sim_data.sim_data_len << 3; out_length = (USHORT) (stk_l_cmd >> 3); error = FKT_GetResponse (data_out, out_length); } } } return error; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : FKT_TerminalProfile | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_TerminalProfile */ GLOBAL USHORT FKT_TerminalProfile (UBYTE * data, USHORT length) { USHORT size = 0; USHORT sw1sw2; UBYTE response[4]; TRACE_FUNCTION ("FKT_TerminalProfile()"); sw1sw2 = SIM_TerminalProfile (response, data, length, &size); return FKT_convert_error (sw1sw2, size); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8419) MODULE : SIM_STK | | STATE : code ROUTINE : FKT_Fetch | +--------------------------------------------------------------------+ PURPOSE : Wrapping function for the SIM driver call SIM_Fetch */ GLOBAL USHORT FKT_Fetch (UBYTE * cmd, USHORT length) { USHORT size = 0; USHORT sw1sw2; TRACE_FUNCTION ("FKT_Fetch()"); sw1sw2 = SIM_Fetch (cmd, length, &size); return FKT_convert_error (sw1sw2, size); } #endif /* SIM_TOOLKIT */ #endif