FreeCalypso > hg > freecalypso-sw
diff gsm-fw/g23m-gsm/sim/sim_fkt.c @ 673:2f7df7a314f8
gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 28 Sep 2014 23:20:04 +0000 |
parents | |
children | ec171ca4afb4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/g23m-gsm/sim/sim_fkt.c Sun Sep 28 23:20:04 2014 +0000 @@ -0,0 +1,1363 @@ +/* ++----------------------------------------------------------------------------- +| 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