view src/g23m-gsm/sim/uicc_fkt.c @ 287:3dee79757ae4

UI fw: load handheld audio mode on boot We have now reached the point where use of audio mode config files should be considered mandatory. In ACI usage we can tell users that they need to perform an AT@AUL of some appropriate audio mode, but in UI-enabled fw we really need to have the firmware load audio modes on its own, so that correct audio config gets established when the handset or development board runs on its own, without a connected host computer. Once have FC Venus with both main and headset audio channels and headset plug insertion detection, our fw will need to automatically load the handheld mode or the headset mode depending on the plug insertion state. For now we load only the handheld mode, which has been tuned for FC-HDS4 on FC Luna.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 13 Nov 2021 03:20:57 +0000
parents fa8dc04885d8
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"
#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