FreeCalypso > hg > fc-magnetite
diff src/g23m-gsm/sim/uicc_fkt.c @ 104:27a4235405c6
src/g23m-gsm: import from LoCosto source
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 04 Oct 2016 18:24:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gsm/sim/uicc_fkt.c Tue Oct 04 18:24:05 2016 +0000 @@ -0,0 +1,1556 @@ +/* ++----------------------------------------------------------------------------- +| 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" +#include "8010_136_SIMDRV_SAP_inline.h" + +/*==== EXPORT =====================================================*/ + +/*==== PRIVAT =====================================================*/ + +/*==== VARIABLES ==================================================*/ +GLOBAL USHORT stk_l_cmd = 0; +/*==== FUNCTIONS ===================================================*/ + +/* Implements Measure# 13 */ +/* ++---------------------------------------------------------------------+ +| PROJECT : GSM-PS (6302) MODULE : SIM_FKT | +| STATE : code ROUTINE : FKT_ChangeCHV_n_UnblockCHV | ++---------------------------------------------------------------------+ + + PURPOSE : Wrapping function for the SIM driver call SIM_ChangeCHV and + SIM_UnblockCHV + +*/ + +LOCAL USHORT FKT_ChangeCHV_n_UnblockCHV ( UBYTE * oldPin_UnblkCHV, + UBYTE * newPin_CHV, + UBYTE pinId_chvType, + UBYTE inst_code) +{ + USHORT size = 0; + USHORT sw1sw2; + + U8 reader_id; + U8 i; + U8 data[2*MAX_PIN_LEN]; + + UBYTE response[SIMDRV_MAX_RESULT]; + + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + TRACE_FUNCTION ("FKT_ChangeCHV_n_UnblockCHV()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = inst_code; + cmd_header.p1 = 0; + cmd_header.p2 = pinId_chvType; + + for (i=0;i<2*MAX_PIN_LEN;i++) + { + if (i < MAX_PIN_LEN) + data[i] = oldPin_UnblkCHV[i]; + else + data[i] = newPin_CHV[i-MAX_PIN_LEN]; + } + + data_info.data = (U8 *)data; + data_info.c_data = sizeof(data); + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2 = simdrv_xch_apdu(reader_id, cmd_header, data_info, &result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); +} + + +/* Implements Measure# 16 */ +/* ++------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6302) MODULE : SIM_FKT | +| STATE : code ROUTINE : FKT_Invalidate_n_Rehabilitate | ++------------------------------------------------------------------------+ + + PURPOSE : Wrapping function for the SIM driver call SIM_Invalidate and + SIM_Rehabilitate. + +*/ + +LOCAL USHORT FKT_Invalidate_n_Rehabilitate ( UBYTE inst_code) +{ + USHORT size = 0; + USHORT sw1sw2; + + U8 reader_id; + + UBYTE response[SIMDRV_MAX_RESULT]; + + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + TRACE_FUNCTION ("FKT_Invalidate_n_Rehabilitate()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = inst_code; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = NULL; + data_info.c_data = 0; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2 = simdrv_xch_apdu(reader_id,cmd_header,data_info,&result_info); + + if (sw1sw2 EQ 0x9810) /* already invalidated */ + return SIM_NO_ERROR; + + return FKT_convert_error (sw1sw2,result_info.c_result); +} + + +/* Implements Measure# 17 */ +/* ++----------------------------------------------------------------------+ +| PROJECT : GSM-PS (6302) MODULE : SIM_FKT | +| STATE : code ROUTINE : FKT_DisableCHV_n_EnableCHV | ++----------------------------------------------------------------------+ + + PURPOSE : Wrapping function for the SIM driver call SIM_DisableCHV and + SIM_EnableCHV + +*/ + +LOCAL USHORT FKT_DisableCHV_n_EnableCHV (UBYTE * pin, UBYTE inst_code) +{ + USHORT size = 0; + USHORT sw1sw2; + + U8 reader_id; + + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + UBYTE response[SIMDRV_MAX_RESULT]; + + TRACE_FUNCTION ("FKT_DisableCHV_n_EnableCHV()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = inst_code; + cmd_header.p1 = 0; + cmd_header.p2 = 1; + + data_info.data = (U8 *)pin; + data_info.c_data = MAX_PIN_LEN; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2 = simdrv_xch_apdu(reader_id, cmd_header, data_info, &result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); +} + + +/* ++--------------------------------------------------------------------+ +| 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 + */ +static const 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 + */ +static const 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_P1 ("Data returned from SIM, Size =%X", size); + 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: +//TISH, patch for OMAPS00115342&OMAPS00123717 +//start +#if 0 + /* Check whether PIN1 is entered/Verified */ + if (SIM_IS_FLAG_SET(PIN1_VERIFIED)) + return SIM_CAUSE_ACCESS_PROHIBIT; + else +#endif +//end + 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) +{ +/* Implements Measure# 13 */ + return (FKT_ChangeCHV_n_UnblockCHV (old_pin, new_pin, pin_id, SIMDRV_INS_CHANGE_CHV)); +} + + +/* ++--------------------------------------------------------------------+ +| 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) +{ +/* Implements Measure# 17 */ + return (FKT_DisableCHV_n_EnableCHV (pin, SIMDRV_INS_DISABLE_CHV)); +} + +/* ++--------------------------------------------------------------------+ +| 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) +{ +/* Implements Measure# 17 */ + return (FKT_DisableCHV_n_EnableCHV (pin, SIMDRV_INS_ENABLE_CHV)); +} + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + UBYTE response[SIMDRV_MAX_RESULT]; + + TRACE_FUNCTION ("FKT_Increase()"); + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE ; + cmd_header.ins = SIMDRV_INS_INCREASE; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = (U8 *)data; + data_info.c_data = 3; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2 = simdrv_xch_apdu(reader_id,cmd_header,data_info,&result_info); + return FKT_convert_error (sw1sw2,result_info.c_result); +} + + +/* ++--------------------------------------------------------------------+ +| 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) +{ +/* Implements Measure# 16 */ + return (FKT_Invalidate_n_Rehabilitate(SIMDRV_INS_INVALIDATE)); +} + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + U8 offset_high; + U8 offset_low; + + TRACE_FUNCTION ("FKT_ReadBinary()"); + offset_high = (U8)((offset &0x7F00)>>8); /* to make the 8th bit 0 as per 102.221 */ + offset_low = (U8)(offset & 0x00FF); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_READ_BINARY; + cmd_header.p1 =offset_high ; + cmd_header.p2 =offset_low ; + + data_info.data = NULL; + data_info.c_data = 0; + + result_info.result = (U8 *)data; + result_info.c_result = size; + result_info.len = (USHORT)length; + + sw1sw2= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info); + return FKT_convert_error (sw1sw2,result_info.c_result); +} + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + +#if !defined NTRACE +/* Implements Measure#32: Row 37 */ + TRACE_EVENT_P1("FKT_ReadRecord(): Nr. %hu", record); +#endif + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_READ_RECORD; + cmd_header.p1 = (U8)record; + cmd_header.p2 = (U8)mode; + + data_info.data = NULL; + data_info.c_data = 0; + + result_info.result = (U8 *)data ; + result_info.c_result = size; + result_info.len =(USHORT)length; + + sw1sw2= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info); + return FKT_convert_error (sw1sw2,result_info.c_result); +} + + +/* ++--------------------------------------------------------------------+ +| 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) +{ +/* Implements Measure# 16 */ + return (FKT_Invalidate_n_Rehabilitate(SIMDRV_INS_REHABILITATE)); +} + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + USHORT cause; + USHORT fileid; + union + { + T_DIR_STATUS status; + UBYTE response [40]; + } dir; + + TRACE_FUNCTION ("FKT_Status()"); + + memset (dir.response, 0, sizeof(dir.response)); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_STATUS; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = NULL; + data_info.c_data = 0; + + result_info.result = (U8 *)dir.response; + result_info.c_result = size; + result_info.len = sim_data.dir_status_len; + + sw1sw2 = simdrv_xch_apdu(reader_id, cmd_header, data_info, &result_info); + + cause = FKT_convert_error (sw1sw2,result_info.c_result); + + *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) +{ + USHORT sw1sw2; + USHORT size = 0; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + TRACE_FUNCTION ("FKT_RunGSMAlgo()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE ; + cmd_header.ins = SIMDRV_INS_AUTHENTICATE; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = (U8*)rand; + data_info.c_data = MAX_RAND; + + result_info.result = data; + result_info.c_result = size; + result_info.len = len; + + sw1sw2= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); + } + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + U8 field[2]; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + TRACE_EVENT_P1 ("fkt_select_one() : File id =%X ", id); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_SELECT; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + field[0] =(U8) (id>>8); /* high byte */ + field[1] =(U8) id; /* low byte */ + + data_info.data = field; + data_info.c_data = sizeof(field); + + result_info.result = data; + result_info.c_result = size; + result_info.len = len; + + TRACE_EVENT_P1 ("Expected result size from SIM =%X ", result_info.len); + + sw1sw2 = simdrv_xch_apdu(reader_id, cmd_header, data_info, &result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); + } + +/* ++--------------------------------------------------------------------+ +| 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 +/* Implements Measure#32: Row 39 */ + TRACE_EVENT_P1("FKT_Select(): id = %04X", 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; + + /* 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: + 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 + case SIM_PNN: + case SIM_OPL: + + /* + * Access to GSM + */ + directory = (SIM_IS_FLAG_SET (GSM_DATAFIELD))? + SIM_DF_GSM: SIM_DF_1800; + break; + + 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_SAI: + case SIM_SLL: + /* + * Access to SoLSA Directory + */ + directory = SIM_DF_SOLSA; + break; + } + } + + if (sim_data.act_directory NEQ directory) + { + /* + * select directory + */ + 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) +{ +/* Implements Measure# 13 */ + return (FKT_ChangeCHV_n_UnblockCHV (unblockCHV, new_CHV, chvType, SIMDRV_INS_UNBLOCK_CHV)); + } + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + U8 offset_high; + U8 offset_low; + UBYTE response[SIMDRV_MAX_RESULT]; + + TRACE_FUNCTION ("FKT_UpdateBinary()"); + + offset_high = (U8)((offset &0x7F00)>>8);/*to make the 8th bit 0 as per 102.221*/ + offset_low = (U8)(offset & 0x00FF); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE ; + cmd_header.ins = SIMDRV_INS_UPDATE_BINARY; + cmd_header.p1 = offset_high; + cmd_header.p2 = offset_low; + + data_info.data = (U8 *)data; + data_info.c_data = (U8)length; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info); + return FKT_convert_error (sw1sw2,result_info.c_result); + } + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + UBYTE response[SIMDRV_MAX_RESULT]; + +#if !defined NTRACE +/* Implements Measure#32: Row 40 */ + TRACE_EVENT_P1("FKT_UpdateRecord(): Nr. %hu", record); +#endif + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE ; + cmd_header.ins = SIMDRV_INS_UPDATE_RECORD; + cmd_header.p1 = (U8)record; + cmd_header.p2 = (U8)mode; + + data_info.data = (U8*)data; + data_info.c_data = (U8)length; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info); + return FKT_convert_error (sw1sw2,result_info.c_result); + } + + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + UBYTE response[SIMDRV_MAX_RESULT]; + + TRACE_FUNCTION ("FKT_VerifyCHV()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_VERIFY_CHV; + cmd_header.p1 = 0x00; + cmd_header.p2 = pin_id; + + data_info.data = (U8 *)pin; + data_info.c_data = MAX_PIN_LEN; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2 = simdrv_xch_apdu(reader_id, cmd_header, data_info, &result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); + } + +/* ++********************************************************************+ +| Moved from sim_stk.c - for CQ 34109 under feature flag SIM_TOOLKIT | ++********************************************************************+ +*/ + +#ifdef SIM_TOOLKIT + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (8419) MODULE : SIM_STK | +| STATE : code ROUTINE : FKT_TerminalResponse | ++--------------------------------------------------------------------+ + + PURPOSE : Wrapping function for the SIM driver call SIM_TerminalResponse + +*/ + +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; + +GLOBAL USHORT FKT_TerminalResponse (UBYTE * data, + USHORT length) +{ + USHORT size = 0; + USHORT sw1sw2; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + UBYTE response[SIMDRV_MAX_RESULT]; + UBYTE env[sizeof(timer_env)]; + USHORT index; + UBYTE dummy[4]; + USHORT error; + USHORT i; + + TRACE_FUNCTION ("FKT_TerminalResponse()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE ; + cmd_header.ins = SIMDRV_INS_TERMINAL_RESPONSE; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = data; + data_info.c_data = (U8)length; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2 = simdrv_xch_apdu(reader_id,cmd_header,data_info,&result_info); + + 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,result_info.c_result); + +} + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + TRACE_FUNCTION ("FKT_Envelope()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_ENVELOPE; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = data_in; + data_info.c_data = (U8)in_length; + + result_info.result = data_out; + result_info.c_result = size; + result_info.len = out_length; + + sw1sw2 = simdrv_xch_apdu(reader_id,cmd_header,data_info,&result_info); + + SIM_EM_ENVELOPE; + + sim_data.sim_data_len = 0; + TRACE_EVENT("sim_data.sim_data_len initialised as 0"); /* for debug only - to be removed */ + + error = FKT_convert_error (sw1sw2,result_info.c_result); + + stk_l_cmd = sim_data.sim_data_len << 3; + + 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + UBYTE response[SIMDRV_MAX_RESULT]; + + TRACE_FUNCTION ("FKT_TerminalProfile()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_TERMINAL_PROFILE; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = data; + data_info.c_data = (U8)length; + + result_info.result = response; + result_info.c_result = size; + result_info.len = NOT_PRESENT_16BIT; + + sw1sw2= simdrv_xch_apdu(reader_id,cmd_header,data_info,&result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); + +} + + +/* ++--------------------------------------------------------------------+ +| 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; + U8 reader_id; + T_SIMDRV_cmd_header cmd_header; + T_SIMDRV_data_info data_info; + T_SIMDRV_result_info result_info; + + TRACE_FUNCTION ("FKT_Fetch()"); + + reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN; + cmd_header.cla = SIMDRV_GSM_CLASS_BYTE; + cmd_header.ins = SIMDRV_INS_FETCH; + cmd_header.p1 = 0; + cmd_header.p2 = 0; + + data_info.data = NULL; + data_info.c_data = 0; + + result_info.result = cmd; + result_info.c_result = size; + result_info.len = (USHORT)length; + + sw1sw2 = simdrv_xch_apdu(reader_id,cmd_header,data_info,&result_info); + + return FKT_convert_error (sw1sw2,result_info.c_result); + +} + +#endif /* SIM_TOOLKIT */ + +#endif