view src/g23m-gsm/sim/sim_app.c @ 639:026c98f757a6

tpudrv12.h & targets/gtm900.h: our current support is for MGC2GSMT version only As it turns out, there exist two different Huawei-made hw platforms both bearing the marketing name GTM900-B: one is MG01GSMT, the other is MGC2GSMT. The two are NOT fw-compatible: aside from flash chip differences which should be handled by autodetection, the two hw platforms are already known to have different RFFEs with different control signals, and there may be other differences not yet known. Our current gtm900 build target is for MGC2GSMT only; we do not yet have a specimen of MG01GSMT on hand, hence no support for that version will be possible until and unless someone provides one.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 30 Jan 2020 18:19:01 +0000
parents 41f2cc21bca9
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  GSM-F&D (8411)
|  Modul   :  SIM_APP
+----------------------------------------------------------------------------- 
|  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 SIM Application.
+----------------------------------------------------------------------------- 
*/ 

#ifndef SIM_APP_C
#define SIM_APP_C

#define ENTITY_SIM

/*==== INCLUDES ===================================================*/

#include <string.h>
#include "typedefs.h"
#include "pcm.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"

#ifdef TI_PS_UICC_CHIPSET_15
#include "8010_136_SIMDRV_SAP_inline.h"
#endif

/*==== EXPORT =====================================================*/

/*==== PRIVAT =====================================================*/

/*==== VARIABLES ==================================================*/
GLOBAL T_FIELD_STATUS field_status;

/*==== FUNCTIONS ==================================================*/


LOCAL UBYTE app_read_sim_service_table (T_SIM_MMI_INSERT_IND * sim_mmi_insert_ind);
LOCAL USHORT app_get_ef_size(USHORT service, USHORT ef_name, UBYTE* res);
#ifdef TI_PS_UICC_CHIPSET_15
GLOBAL void app_sim_insert( T_SIMDRV_atr_string_info     *atr_string_info,
                            U8       config_requested,
                            T_SIMDRV_config_characteristics     *config_characteristics);

#ifdef _SIMULATION_
GLOBAL UBYTE sim_command_type;
#endif

#endif /* TI_PS_UICC_CHIPSET_15 */

#ifndef TI_PS_UICC_CHIPSET_15
#define SIMDRV_MAX_RESULT 0x100
#endif


/* Implements Measure# 2 to 8 */
/* Table */
#ifdef TI_PS_HCOMM_CHANGE
T_HANDLE const hComm_mux[] = {_hCommMMI, _hCommMM, _hCommSMS}; 
#else
T_HANDLE* const hComm_mux[] = {&sim_hCommMMI, &sim_hCommMM, &sim_hCommSMS}; 
#endif

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS              MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_get_ef_size            |
+--------------------------------------------------------------------+

  PURPOSE : Return size of the Elementory file. If Elementory file is 
            not present return 0.

*/

LOCAL USHORT app_get_ef_size(USHORT service, USHORT ef_name, UBYTE *res)
{

  if (SIM_IS_FLAG_SET (service))
  {      
    T_FIELD_STATUS field_status;
    
    if (FKT_Select (ef_name, FALSE, NULL, res, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
    {
      memcpy(&field_status, res, SIM_MIN_EF_ST_LEN);
      return((((USHORT)field_status.field_size[0]) << 8)
                   | (USHORT)field_status.field_size[1]);
    }
  }

  return 0;

}

/* Implements Measure# 18 */
/*
+----------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                          |
| STATE   : code            ROUTINE : app_sim_read_n_update_req        |
+----------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_READ_REQ and SIM_UPDATE_REQ

*/
LOCAL void app_sim_read_n_update_req(USHORT *cause, USHORT *datafield, UBYTE rd_upd_access, U8 *v_path_info, T_path_info *path_info)
{
  UBYTE response[SIMDRV_MAX_RESULT];  
  
    
  TRACE_FUNCTION ("app_sim_read_n_update_req()");

  
  /* if SIM is inserted, try to select the SIM card.*/
  *cause = FKT_Select (*datafield, *v_path_info, path_info, response, SIM_MIN_EF_ST_LEN);

    if (*cause EQ SIM_NO_ERROR)
    {
      memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);  
    
      sim_data.act_length = (USHORT)field_status.field_size[0] * 256 +
                              field_status.field_size[1];
  }

  if ((*cause EQ SIM_NO_ERROR) OR (*cause EQ SIM_NO_ERR_FILE_ALREADY_SELECTED))
  {
    /* field_status is global and has been updated either 
     * in "if" above or during previous operation on same file 
     */
      if (!(sim_data.act_access = app_check_access_conditions (rd_upd_access,
                                    &field_status)))
      {
      /* access not allowed */
         *cause = SIM_CAUSE_ACCESS_PROHIBIT;
      }
    else
    {
      *cause = SIM_NO_ERROR; 
    }
  }

}


/* Implements Measure# 14 */
/*
+-------------------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                                   |
| STATE   : code            ROUTINE : app_sim_activate_req_fdn_enable           |
+-------------------------------------------------------------------------------+

  PURPOSE : Process the SIM activate req for FDN ENABLE and FDN DISABLE cases

*/

LOCAL void app_sim_activate_req_fdn_enable(BOOL sim_fdn_en) 
{
  ULONG   support_flag, service_flag;
  USHORT  error, (*FKT_FuncPtr)(void);
  
  TRACE_FUNCTION ("app_sim_activate_req_fdn_enable()");
  
  if(sim_fdn_en EQ TRUE) 
  {
    support_flag = ADN_SUPPORT_BY_SIM;
    service_flag = SERVICE_3_SUPPORT;
    FKT_FuncPtr = FKT_Invalidate ;
  }
  else
  {
    support_flag = FDN_SUPPORT_BY_SIM;
    service_flag = SERVICE_2_SUPPORT;
    FKT_FuncPtr = FKT_Rehabilitate ;
  }
  
  if (SIM_IS_FLAG_SET (support_flag))
  {
    if (SIM_IS_FLAG_SET (service_flag))
    {
      sim_data.last_requested_pin_no = LRP_PIN_2;
      error = FKT_Select (SIM_ADN, FALSE, NULL, NULL, 0);
      if (error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
      { 
        error = FKT_FuncPtr();
        if (error EQ SIM_NO_ERROR)
        {
          if(sim_fdn_en EQ FALSE)  
          {
            if (!app_check_imsi_loci_validation())
            {
              if (!app_rehabilitate_imsi_loci())
              {
                app_sim_card_error (SIM_CAUSE_EF_INVALID);
                return ; /* return is replaced for break */
              }
            }
            SIM_SET_FLAG (ADN_SUPPORT_BY_SIM);
          }
          else
            SIM_SET_FLAG (FDN_SUPPORT_BY_SIM);
          SIM_CLEAR_FLAG (support_flag);   
          app_sim_card_error (SIM_NO_ERROR);
        }
        else
          app_sim_card_error (error);
      }
    else
      app_sim_card_error (error);
  
      if(sim_fdn_en EQ TRUE) 
      {
        SIM_EM_FDN_ENABLE;
      }
      else
      {
        SIM_EM_ADN_ENABLE;
      }
  
    }
    else
      app_sim_card_error (SIM_CAUSE_ACCESS_PROHIBIT);
  }
  else
    app_sim_card_error (SIM_NO_ERROR);
}
 



/*
 * -------------------------------------------------------------------
 * PRIMITIVE Processing functions
 * -------------------------------------------------------------------
 */
/*lint -e720 (boolean test of assignment) */
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_init_sim_data          |
+--------------------------------------------------------------------+

  PURPOSE : Initialize the SIM data for the module application.

*/

GLOBAL void app_init_sim_data (void)
{
#ifdef SIM_TOOLKIT
  int i;
#endif

  TRACE_FUNCTION ("app_init_sim_data()");
  /*
   * initialize all internal flags
   */
  sim_data.flags = 0;

  sim_data.last_requested_pin_no  = LRP_NONE;
  /* 
  sim_data.pin_no_puct            = NOT_PRESENT_8BIT;
  sim_data.pin_no_acm             = NOT_PRESENT_8BIT;
  sim_data.pin_no_acmmax          = NOT_PRESENT_8BIT;
  */

  sim_data.act_directory          = NOT_PRESENT_16BIT;
  sim_data.act_field              = NOT_PRESENT_16BIT;
  sim_data.remove_error           = SIM_CAUSE_CARD_REMOVED;

#ifdef SIM_TOOLKIT
  sim_data.sync_awaited           = 0;

  /* startup with idle polling, after 11.11[11.2.8] */
  sim_data.idle_polling           = TRUE;

  for (i = 0; i < MAX_SAT_TIMER; i++)
  {
    sim_data.timer[i].active = FALSE;
  }
#endif

#ifndef TI_PS_UICC_CHIPSET_15
  SIM_Init (app_sim_insert, app_sim_remove);
#else
  simdrv_register(app_sim_insert, app_sim_remove);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_read_req           |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_READ_REQ.

*/

GLOBAL void app_sim_read_req (T_SIM_READ_REQ * sim_read_req)
{
  USHORT         source;
  
  PALLOC (sim_read_cnf, SIM_READ_CNF);

  TRACE_FUNCTION ("app_sim_read_req()");

  // initialize answer
  source                = sim_read_req->source;
  sim_read_cnf->req_id  = sim_read_req->req_id;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    /*
     * If unknown length request, a Select must be
     * carried out in any case to determine real length
     */
    if (sim_read_req->length EQ NOT_PRESENT_8BIT)
    {
      sim_data.act_field = NOT_PRESENT_16BIT;
    }
  
    /* Implements Measure# 18 */
    app_sim_read_n_update_req(&sim_read_cnf->cause, &sim_read_req->datafield, ACCESS_READ,&sim_read_req->v_path_info ,&sim_read_req->path_info);

   
    if (sim_read_cnf->cause EQ SIM_NO_ERROR)
    {
      if (sim_read_req->length EQ NOT_PRESENT_8BIT)
      {
        // unknown length, must be calculated by the entity
        if (sim_read_req->offset < sim_data.act_length)
        {
          sim_read_cnf->length = (UBYTE)(sim_data.act_length - sim_read_req->offset);
        }
        else
        {
          // incorrect offset
          sim_read_cnf->cause = SIM_CAUSE_PARAM_WRONG;
        }
      }
      else
      {
        sim_read_cnf->length = sim_read_req->length;
        // check given length
        if (((USHORT)sim_read_req->offset + sim_read_req->length) <= sim_data.act_length)
        {
          sim_read_cnf->length = sim_read_req->length;
        }
        else
        {
          // incorrect offset and/or length
          sim_read_cnf->cause = SIM_CAUSE_PARAM_WRONG;
        }
      }
    }
  }
  else
  {
    // sim is not inserted
    sim_read_cnf->cause = SIM_CAUSE_CARD_REMOVED;
  }

  if (sim_read_cnf->cause EQ SIM_NO_ERROR)
  {
    // cut length if needed
    if ((sim_read_req->max_length > 0) AND
        (sim_read_cnf->length > sim_read_req->max_length))
      sim_read_cnf->length = sim_read_req->max_length;
    // length is available then read and start status timer again
    sim_read_cnf->cause = FKT_ReadBinary (sim_read_cnf->trans_data,
                                          sim_read_req->offset,
                                          (USHORT)sim_read_cnf->length);
    app_start_status_timer (FALSE);
  }
  else
  {
    sim_read_cnf->length = 0;
    memset (sim_read_cnf->trans_data, 0, sizeof (sim_read_cnf->trans_data));
  }

  SIM_EM_READ_BINARY_FILE;

  // free incoming primitive
  PFREE (sim_read_req);

  /* Implements Measure# 2 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_read_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_read_cnf FILE_LINE_MACRO);
#endif

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_read_record_req    |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_READ_RECORD_REQ.

*/

GLOBAL void app_sim_read_record_req (T_SIM_READ_RECORD_REQ * sim_read_record_req)
{
  USHORT         source;
  UBYTE response[SIMDRV_MAX_RESULT];
  
  PALLOC (sim_read_record_cnf, SIM_READ_RECORD_CNF);

  TRACE_FUNCTION ("app_sim_read_record_req()");

  source = sim_read_record_req->source;
  sim_read_record_cnf->req_id     = sim_read_record_req->req_id;

  sim_read_record_cnf->max_record = 0;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    sim_read_record_cnf->cause = FKT_Select (sim_read_record_req->datafield,
                                             sim_read_record_req->v_path_info, &sim_read_record_req->path_info,
                                             response, SIM_MIN_EF_ST_LEN);

      if (sim_read_record_cnf->cause EQ SIM_NO_ERROR)
    {
      USHORT total_length;
        memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
        sim_data.field_type = field_status.field_type;
        sim_data.act_length = (USHORT)field_status.record_length;
        total_length = (USHORT)field_status.field_size[0] * 256 +
                         field_status.field_size[1];
        if (field_status.record_length)
        {
            sim_read_record_cnf->max_record =
                               total_length / field_status.record_length;
        }
        else
        {
            sim_read_record_cnf->max_record = 1;  /* don't divide by zero */
        }
          sim_data.max_record = sim_read_record_cnf->max_record;
    }

    if ((sim_read_record_cnf->cause EQ SIM_NO_ERROR) OR
        (sim_read_record_cnf->cause EQ SIM_NO_ERR_FILE_ALREADY_SELECTED))
    {
      /* field_status is global and has been updated either 
       * in "if" above or during previous operation on same file 
       */
        if (!(sim_data.act_access = app_check_access_conditions (ACCESS_READ,
                                      &field_status)))
        {
          sim_read_record_cnf->cause = SIM_CAUSE_ACCESS_PROHIBIT;
        }
        else if ((sim_read_record_req->record EQ 0) OR
              (sim_read_record_req->record > sim_data.max_record))
        {
          sim_read_record_cnf->cause = SIM_CAUSE_ADDR_WRONG;
        }
        else
        {
        sim_read_record_cnf->cause = SIM_NO_ERROR;
         sim_read_record_cnf->max_record = sim_data.max_record;
         sim_read_record_cnf->length = (sim_read_record_req->length > (UBYTE)sim_data.act_length)?
                                    (UBYTE)sim_data.act_length: sim_read_record_req->length;
        }
      }
    }
  else
  {
    sim_read_record_cnf->cause = SIM_CAUSE_CARD_REMOVED;
  }

  if (sim_read_record_cnf->cause EQ SIM_NO_ERROR)
  {
    sim_read_record_cnf->cause =
          FKT_ReadRecord (sim_read_record_cnf->linear_data,
                          4,
                          sim_read_record_req->record,
                          (USHORT)sim_data.act_length);
    app_start_status_timer (FALSE);
  }
  else
  {
    sim_read_record_cnf->length = 0;
    memset (sim_read_record_cnf->linear_data, 0, sizeof (sim_read_record_cnf->linear_data));
  }

  SIM_EM_READ_RECORD_FILE;

  PFREE (sim_read_record_req);


  /* Implements Measure# 2 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_read_record_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_read_record_cnf FILE_LINE_MACRO);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_update_req         |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_UPDATE_REQ.

*/
GLOBAL void app_sim_update_req (T_SIM_UPDATE_REQ * sim_update_req)
{
  USHORT          source;
  PALLOC (sim_update_cnf, SIM_UPDATE_CNF);

  TRACE_FUNCTION ("app_sim_update_req()");

  source = sim_update_req->source;
  sim_update_cnf->req_id = sim_update_req->req_id;
  sim_update_cnf->cause = SIM_NO_ERROR;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
  
    /* Implements Measure# 18 */
    app_sim_read_n_update_req(&sim_update_cnf->cause, &sim_update_req->datafield, ACCESS_UPDATE,&sim_update_req->v_path_info ,&sim_update_req->path_info) ;
  
    if (sim_update_cnf->cause EQ SIM_NO_ERROR)
    {
      if ((sim_update_req->offset + (USHORT)sim_update_req->length)
           > sim_data.act_length)
      {		    
        sim_update_cnf->cause = SIM_CAUSE_PARAM_WRONG;
      }
      else
	  {
        sim_update_cnf->cause =
             FKT_UpdateBinary (sim_update_req->trans_data,
                           (USHORT)sim_update_req->length,
                           sim_update_req->offset);

        app_start_status_timer (FALSE);

        if ((sim_update_cnf->cause EQ SIM_NO_ERROR) AND (sim_update_req->v_path_info EQ FALSE))
		{
          switch(sim_update_req->datafield) 
		  {
            case SIM_PLMNSEL:
              if (SIM_IS_FLAG_SET (SERVICE_7_SUPPORT))
			  {
                /*
                 * MM should be notified about the changed file so that MM can read this file.
                 */
                PALLOC (sim_mm_info_ind, SIM_MM_INFO_IND);
                sim_mm_info_ind->datafield = sim_update_req->datafield;
                PSENDX (MM, sim_mm_info_ind);
			  }
              break;
#ifdef REL99
            case SIM_UCPS_ACTEC:
              if (SIM_IS_FLAG_SET (SERVICE_43_SUPPORT))
			  {
                /*
                 * MM should be notified about the changed file so that MM can read this file.
                 */
                PALLOC (sim_mm_info_ind, SIM_MM_INFO_IND);
                sim_mm_info_ind->datafield = sim_update_req->datafield;
                PSENDX (MM, sim_mm_info_ind);
			  }
              break;
#endif
            default:
              break;
		  }
		}
	  }
    }
  }
  else
  {
    sim_update_cnf->cause = SIM_CAUSE_CARD_REMOVED;
  }

  SIM_EM_UPDATE_BINARY_FILE;

  PFREE (sim_update_req);

#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_update_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_update_cnf FILE_LINE_MACRO);
#endif
  /* Implements Measure# 3 */
}
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_update_record_req  |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_UPDATE_RECORD_REQ.

*/

GLOBAL void app_sim_update_record_req (T_SIM_UPDATE_RECORD_REQ * sim_update_record_req)
{
  USHORT         source;
  UBYTE response[SIMDRV_MAX_RESULT];

  PALLOC (sim_update_record_cnf, SIM_UPDATE_RECORD_CNF);

  TRACE_FUNCTION ("app_sim_update_record_req()");

  source = sim_update_record_req->source;

  sim_update_record_cnf->req_id = sim_update_record_req->req_id;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    sim_update_record_cnf->cause = FKT_Select (sim_update_record_req->datafield,
                                               sim_update_record_req->v_path_info, &sim_update_record_req->path_info,
                                               response,SIM_MIN_EF_ST_LEN);

      if (sim_update_record_cnf->cause EQ SIM_NO_ERROR)
      {
        USHORT total_length;
        memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
        sim_data.field_type = field_status.field_type;
        sim_data.act_length = (USHORT)field_status.record_length;
        total_length = (USHORT)field_status.field_size[0] * 256 +
                       (USHORT)field_status.field_size[1];
        if (field_status.record_length)
        {
            sim_data.max_record = (UBYTE)(total_length / field_status.record_length);
        }
        else
        {
          sim_data.max_record = 1;  /* don't divide by zero */
        }
    }

    if ((sim_update_record_cnf->cause EQ SIM_NO_ERROR) OR 
        (sim_update_record_cnf->cause EQ SIM_NO_ERR_FILE_ALREADY_SELECTED))
    {
      /* field_status is global and has been updated either 
       * in "if" above or during previous operation on same file 
       */
        if (!(sim_data.act_access = app_check_access_conditions (ACCESS_UPDATE,
                                    &field_status)))
        {
          sim_update_record_cnf->cause = SIM_CAUSE_ACCESS_PROHIBIT;
        }
        else if ((sim_update_record_req->length > sim_data.act_length) OR
        ((sim_data.field_type EQ LINEAR_FIXED) AND
         (sim_update_record_req->record EQ 0)) OR
         (sim_update_record_req->record > sim_data.max_record))
        {
          sim_update_record_cnf->cause = SIM_CAUSE_ADDR_WRONG;
        }
        else 
        {
        if (sim_data.field_type EQ LINEAR_FIXED)
          {
            sim_update_record_cnf->cause =
               FKT_UpdateRecord (sim_update_record_req->linear_data,
                            (USHORT)sim_update_record_req->length,
                            4,
                            sim_update_record_req->record);
          }
          else
          {
            /*
             * Cyclic file
             */
            sim_update_record_cnf->cause =
                  FKT_UpdateRecord (sim_update_record_req->linear_data,
                            (USHORT)sim_update_record_req->length,
                            3,
                            0);
         }
        app_start_status_timer (FALSE);
      }
    }		
  }
  else
  {
    sim_update_record_cnf->cause = SIM_CAUSE_CARD_REMOVED;
  }

  SIM_EM_UPDATE_RECORD;

  PFREE (sim_update_record_req);

  /* Implements Measure# 4 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_update_record_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_update_record_cnf FILE_LINE_MACRO);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_increment_req      |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_INCREMENT_REQ.

*/

GLOBAL void app_sim_increment_req (T_SIM_INCREMENT_REQ * sim_increment_req)
{
  USHORT         source;
  UBYTE response[SIMDRV_MAX_RESULT];

  PALLOC (sim_increment_cnf, SIM_INCREMENT_CNF);

  TRACE_FUNCTION ("app_sim_increment_req()");

  source = sim_increment_req->source;
  sim_increment_cnf->req_id     = sim_increment_req->req_id;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    sim_increment_cnf->cause = FKT_Select (sim_increment_req->datafield,
                                           sim_increment_req->v_path_info, &sim_increment_req->path_info,
                                           response,SIM_MIN_EF_ST_LEN );

      if (sim_increment_cnf->cause EQ SIM_NO_ERROR)
    {
      memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
      sim_data.field_type = field_status.field_type;
    }
    if ((sim_increment_cnf->cause EQ SIM_NO_ERROR) OR 
        (sim_increment_cnf->cause EQ SIM_NO_ERR_FILE_ALREADY_SELECTED))
    {
      /* field_status is global and has been updated either 
       * in "if" above or during previous operation on same file 
       */
        if (!(sim_data.act_access = app_check_access_conditions (ACCESS_INCREASE, &field_status)))
        {
          sim_increment_cnf->cause = SIM_CAUSE_ACCESS_PROHIBIT;
        }
      else
      {
        sim_increment_cnf->cause = SIM_NO_ERROR;
      }
    }
  }
  else
  {
    sim_increment_cnf->cause = SIM_CAUSE_CARD_REMOVED;
  }

  if (sim_increment_cnf->cause EQ SIM_NO_ERROR)
  {
    sim_increment_cnf->cause = FKT_Increase (sim_increment_req->linear_data);
    sim_increment_cnf->length = 0; /* sim_increment_req ->length; */

    app_start_status_timer (FALSE);
  }
  else
  {
    memset (&sim_increment_cnf->linear_data, 0, sizeof (sim_increment_cnf->linear_data));
    sim_increment_cnf->length = 0;
  }

  SIM_EM_INCREMENT_FILE;

  PFREE (sim_increment_req);

  /* Implements Measure# 5 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_increment_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_increment_cnf FILE_LINE_MACRO);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_verify_pin_req     |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_VERIFY_PIN_REQ.

*/

GLOBAL void app_sim_verify_pin_req (T_SIM_VERIFY_PIN_REQ * sim_verify_pin_req)
{
  USHORT source;             /* which entity has requested */
  USHORT error;              /* result of operation        */
  /*
   * allocate buffer for answer
   */
  PALLOC (sim_verify_pin_cnf, SIM_VERIFY_PIN_CNF);

  TRACE_FUNCTION ("app_sim_verify_pin_req()");

  SIM_EM_VERIFY_PIN;

  /*
   * fill the answer
   */
  memset (sim_verify_pin_cnf, 0, sizeof(T_SIM_VERIFY_PIN_CNF));
  source = sim_verify_pin_req->source;
  sim_verify_pin_cnf->pin_id = sim_verify_pin_req->pin_id;
  sim_data.last_requested_pin_no = sim_verify_pin_req->pin_id;
  /*
   * use SIM driver call for verification
   */
  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    error = FKT_VerifyCHV (sim_verify_pin_req->pin,
                           sim_verify_pin_req->pin_id);
  }
  else
    error = SIM_CAUSE_CARD_REMOVED;

  /*
   * deallocate incoming primitive
   */
  PFREE (sim_verify_pin_req);

  /*
   * check actual pin/puk counts
   */
  FKT_Status (&sim_verify_pin_cnf->pin_cnt,
              &sim_verify_pin_cnf->pin2_cnt,
              &sim_verify_pin_cnf->puk_cnt,
              &sim_verify_pin_cnf->puk2_cnt);

  /*
   * fill results for answer
   */
  sim_verify_pin_cnf->cause = error;

  /* Implements Measure# 6 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_verify_pin_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_verify_pin_cnf FILE_LINE_MACRO);
#endif
  /*
   * during initialization start
   * remaining part of initialisation procedure
   *
   */
  if (error EQ SIM_NO_ERROR)
  {
    if (SIM_IS_FLAG_CLEARED (MM_KNOWS_FROM_SIM))
    {
      app_sim_read_parameters ();
      app_start_status_timer (TRUE);
    }
    else
      app_start_status_timer (FALSE);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_change_pin_req     |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_CHANGE_PIN_REQ.

*/

GLOBAL void app_sim_change_pin_req (T_SIM_CHANGE_PIN_REQ * sim_change_pin_req)
{
  USHORT source;

  PALLOC (sim_change_pin_cnf, SIM_CHANGE_PIN_CNF);

  TRACE_FUNCTION ("app_sim_change_pin_req()");

  SIM_EM_CHANGE_PIN;

  source = sim_change_pin_req->source;
  sim_change_pin_cnf->pin_id = sim_change_pin_req->pin_id;
  sim_data.last_requested_pin_no = sim_change_pin_req->pin_id;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    sim_change_pin_cnf->cause = FKT_ChangeCHV (sim_change_pin_req->old_pin,
                                               sim_change_pin_req->new_pin,
                                               sim_change_pin_req->pin_id);
    app_start_status_timer (FALSE);
  }
  else
    sim_change_pin_cnf->cause = SIM_CAUSE_CARD_REMOVED;

  PFREE (sim_change_pin_req);

  /*
   * check actual pin/puk counts
   */
  FKT_Status (&sim_change_pin_cnf->pin_cnt,
              &sim_change_pin_cnf->pin2_cnt,
              &sim_change_pin_cnf->puk_cnt,
              &sim_change_pin_cnf->puk2_cnt);

  /* Implements Measure# 7 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_change_pin_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_change_pin_cnf FILE_LINE_MACRO);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_disable_pin_req    |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_DISABLE_PIN_REQ.

*/

GLOBAL void app_sim_disable_pin_req (T_SIM_DISABLE_PIN_REQ * sim_disable_pin_req)
{
  USHORT source;

  PALLOC (sim_disable_pin_cnf, SIM_DISABLE_PIN_CNF);

  TRACE_FUNCTION ("app_sim_disable_pin_req()");

  SIM_EM_DISABLE_PIN;

  /*
   * store source of request
   */
  source = sim_disable_pin_req->source;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    /*
     * only if a SIM card is inserted
     */
    if (SIM_IS_FLAG_SET (SIM_PIN_FLAG))
    {
      /*
       * CHV1 entering was necessary, that means not disabled
       */
      if (SIM_IS_FLAG_SET (SERVICE_1_SUPPORT))
      {
        /*
         * SIM card supports disabling of CHV1
         */
        sim_data.last_requested_pin_no = LRP_PIN_1;
        sim_disable_pin_cnf->cause = FKT_DisableCHV (sim_disable_pin_req->pin);
        app_start_status_timer (FALSE);
      }
      else
        sim_disable_pin_cnf->cause = SIM_CAUSE_ACCESS_PROHIBIT;
    }
    else
      sim_disable_pin_cnf->cause = SIM_NO_ERROR;
  }
  else
    sim_disable_pin_cnf->cause = SIM_CAUSE_CARD_REMOVED;

  if (sim_disable_pin_cnf->cause EQ SIM_NO_ERROR)
  {
    SIM_CLEAR_FLAG (SIM_PIN_FLAG);
  }

  PFREE (sim_disable_pin_req);

  /*
   * check actual pin/puk counts
   */
  FKT_Status (&sim_disable_pin_cnf->pin_cnt,
              &sim_disable_pin_cnf->pin2_cnt,
              &sim_disable_pin_cnf->puk_cnt,
              &sim_disable_pin_cnf->puk2_cnt);

  /* Implements Measure# 2 to 8 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_disable_pin_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_disable_pin_cnf FILE_LINE_MACRO);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_enable_pin_req     |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_ENABLE_PIN_REQ.

*/

GLOBAL void app_sim_enable_pin_req (T_SIM_ENABLE_PIN_REQ * sim_enable_pin_req)
{
  USHORT source;

  PALLOC (sim_enable_pin_cnf, SIM_ENABLE_PIN_CNF);

  TRACE_FUNCTION ("app_sim_enable_pin_req()");

  SIM_EM_ENABLE_PIN;

  source = sim_enable_pin_req->source;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    if (SIM_IS_FLAG_SET (SIM_PIN_FLAG))
      sim_enable_pin_cnf->cause = SIM_NO_ERROR;
    else
    {
      sim_data.last_requested_pin_no = LRP_PIN_1;
      sim_enable_pin_cnf->cause = FKT_EnableCHV (sim_enable_pin_req->pin);
      app_start_status_timer (FALSE);
    }
  }
  else
    sim_enable_pin_cnf->cause = SIM_CAUSE_CARD_REMOVED;

  if (sim_enable_pin_cnf->cause EQ SIM_NO_ERROR)
  {
    SIM_SET_FLAG (SIM_PIN_FLAG);
  }

  PFREE (sim_enable_pin_req);

  /*
   * check actual pin/puk counts
   */
  FKT_Status (&sim_enable_pin_cnf->pin_cnt,
              &sim_enable_pin_cnf->pin2_cnt,
              &sim_enable_pin_cnf->puk_cnt,
              &sim_enable_pin_cnf->puk2_cnt);

  /* Implements Measure# 2 to 8 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_enable_pin_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_enable_pin_cnf FILE_LINE_MACRO);
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_unblock_req        |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_UNBLOCK_REQ.

*/

GLOBAL void app_sim_unblock_req (T_SIM_UNBLOCK_REQ * sim_unblock_req)
{
  USHORT source;
  USHORT error;

  PALLOC (sim_unblock_cnf, SIM_UNBLOCK_CNF);

  TRACE_FUNCTION ("app_sim_unblock_req()");

  SIM_EM_UNBLOCK_PIN;

  /*
   * fill the answer
   */
  memset (sim_unblock_cnf, 0, sizeof(T_SIM_VERIFY_PIN_CNF));
  source = sim_unblock_req->source;
  sim_unblock_cnf->pin_id = sim_unblock_req->pin_id;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    if (sim_unblock_req->pin_id EQ PHASE_2_PUK_2)
    {
      sim_unblock_req->pin_id = UNBL_CHV2;      /* PUK2 */
      sim_data.last_requested_pin_no = LRP_PUK_2;
    }
    else
    {
      sim_unblock_req->pin_id = UNBL_CHV1;      /* PUK1 */
      sim_data.last_requested_pin_no = LRP_PUK_1;
    }
    error = FKT_UnblockCHV (sim_unblock_req->unblock_key,
                            sim_unblock_req->pin,
                            sim_unblock_req->pin_id);
  }
  else
    error = SIM_CAUSE_CARD_REMOVED;

  /*
   * deallocate incoming primitive
   */
  PFREE (sim_unblock_req);

  /*
   * check actual pin/puk counts regardless the outcome of
   * of the UNBLOCK operation
   */
  FKT_Status (&sim_unblock_cnf->pin_cnt,
              &sim_unblock_cnf->pin2_cnt,
              &sim_unblock_cnf->puk_cnt,
              &sim_unblock_cnf->puk2_cnt);

  /*
   * after a successful UNBLOCK of CHV1 the PIN is enabled,
   * otherwise its state remains unchanged
   */
  if (error EQ SIM_NO_ERROR AND
      sim_data.last_requested_pin_no EQ LRP_PUK_1)
  {
    SIM_SET_FLAG (SIM_PIN_FLAG);
  }
  /*
   * fill results for answer
   */
  sim_unblock_cnf->cause = error;

  /* Implements Measure# 8 */
#ifdef TI_PS_HCOMM_CHANGE
  vsi_c_psend (hComm_mux[source], (T_VOID_STRUCT*) sim_unblock_cnf FILE_LINE_MACRO);
#else
  vsi_c_psend (*hComm_mux[source], (T_VOID_STRUCT*) sim_unblock_cnf FILE_LINE_MACRO);
#endif
  /*
   * during initialization start
   * remaining part of initialisation procedure
   *
   */
  if (error EQ SIM_NO_ERROR)
  {
    if (SIM_IS_FLAG_CLEARED (MM_KNOWS_FROM_SIM))
    {
      app_sim_read_parameters ();
      app_start_status_timer (TRUE);
    }
    else
      app_start_status_timer (FALSE);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_auth_req           |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_AUTHENTICATION_REQ.

*/

GLOBAL void app_sim_auth_req (T_SIM_AUTHENTICATION_REQ * sim_authentication_req)
{
  USHORT     error;
  USHORT     source;
  T_SRES_KC  sres_kc;
  T_kc_n     kc_n;
  UBYTE response[SIMDRV_MAX_RESULT];

  PALLOC (sim_authentication_cnf, SIM_AUTHENTICATION_CNF);

  TRACE_FUNCTION ("app_sim_auth_req()");

  SIM_EM_AUTHENTICATION;

  memset(response, 0, SIMDRV_MAX_RESULT);
  source = sim_authentication_req->source;
  kc_n.kc[MAX_KC] = sim_authentication_req->cksn;

  sim_authentication_cnf->req_id = sim_authentication_req->req_id;

  if (SIM_IS_FLAG_SET (GSM_DATAFIELD))
    error = FKT_Select (SIM_DF_GSM, FALSE, NULL, NULL, 0);
  else
    error = FKT_Select (SIM_DF_1800, FALSE, NULL, NULL, 0);

  if ((error EQ SIM_NO_ERROR) OR (error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED))
    error = FKT_RunGSMAlgo (sim_authentication_req->rand, response, SIM_GSM_ALG_LEN);

  if (error EQ SIM_NO_ERROR)
  {
     memcpy(&sres_kc,response,SIM_GSM_ALG_LEN);
     app_start_status_timer (FALSE);
  }
  if (error EQ SIM_NO_ERROR)
  {
    int i;
    /*lint -e{645} (when if statement TRUE, then 'sres_kc' valid) */
    memcpy (sim_authentication_cnf->sres, sres_kc.sres, 4);

    for (i = 0; i < MAX_KC; i++)
      sim_authentication_cnf->kc[(MAX_KC-1)-i] = kc_n.kc[i] = sres_kc.kc[i];

    switch (source)
    {
#if defined (GPRS)
      case SRC_GMM:
        PSENDX (GMM, sim_authentication_cnf);
        if (SIM_IS_FLAG_SET (SERVICE_38_SUPPORT))
        {
          error = FKT_Select (SIM_KCGPRS, FALSE, NULL, NULL, 0);  /* use SIM */
          if(error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
            error = SIM_NO_ERROR;
        }
        else
        {                                   /* use PCM */
          T_imsi_field sim_imsi;
            error = FKT_Select (SIM_IMSI, FALSE, NULL, NULL, 0);
          if ((error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
               AND
               FKT_ReadBinary ((UBYTE *)&sim_imsi, 0, MAX_IMSI)
               EQ SIM_NO_ERROR)
          {
            if (gprs_check_pcm_data (&sim_imsi))
              pcm_WriteFile((UBYTE *)EF_KCGPRS_ID, SIZE_EF_KCGPRS,
                            (UBYTE *)kc_n.kc);
          }
          PFREE (sim_authentication_req);
          return;
        }
        break;
#endif
       default:
         PSENDX (MM, sim_authentication_cnf);
         error = FKT_Select (SIM_KC, FALSE, NULL, NULL, 0);
         if(error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
             error = SIM_NO_ERROR;
         break;
    }
  }

  PFREE (sim_authentication_req);

  if (error EQ SIM_NO_ERROR)
  {
    kc_n.c_kc = MAX_KC_N;
    FKT_UpdateBinary (kc_n.kc, (USHORT)kc_n.c_kc, 0);
  }
//TISH, OMAPS00133714
//start
	else
	{
		  sim_data.remove_error = error;
      app_sim_remove ();
      sim_data.remove_error = SIM_CAUSE_CARD_REMOVED;
	} 
//end
}

#ifdef TI_PS_UICC_CHIPSET_15
LOCAL void app_require_uicc_characteristics(T_SIMDRV_config_characteristics *config_characteristics)
{
  UBYTE clock_stop = 0;
  UBYTE voltage_class = 0;

  TRACE_FUNCTION("app_require_uicc_characteristics()");
  TRACE_EVENT_P1 ("SIMDRV - GSM SIM File Characteristics : 0x%02X", config_characteristics->uicc_characteristics);

  clock_stop = (config_characteristics->uicc_characteristics & 0x0D);/*get bit 1,3 and 4*/
  voltage_class = (config_characteristics->uicc_characteristics & 0x30);/*get bit 5 and 6*/

  switch(voltage_class) 
  {
    case 0x00:/*8GSM 5V - No voltage class bits set.*/
      voltage_class = 0x10; /*UMTS CLASS A - Bit 5 set*/
    break;
    case 0x10:/*GSM 3V - Voltage class bit 5 set.*/
      voltage_class = 0x20;/*UMTS CLASS B - Bit 6 set*/
    break;
    case 0x30:/*GSM 1.8V - Voltage class bit 5 and 6 set.*/
      voltage_class = 0x40;/*UMTS CLASS C - Bit 7 set*/
    break;
    default:
      voltage_class = 0x00;
    break;
  }
  config_characteristics->uicc_characteristics = (voltage_class | clock_stop);
  TRACE_EVENT_P1 ("SIMDRV - SIM File Characteristics (Converted) : 0x%02X", config_characteristics->uicc_characteristics);
  /* Clear traces of the fact that we have already used the card */
  sim_data.act_directory = NOT_PRESENT_16BIT;
  sim_data.act_field = NOT_PRESENT_16BIT;
}
#endif
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_insert             |
+--------------------------------------------------------------------+

  PURPOSE : Hook function for SIM driver after SIM insertion.

*/

#ifndef TI_PS_UICC_CHIPSET_15
GLOBAL void app_sim_insert (T_SIM_CARD *p_atr)
#else /*!TI_PS_UICC_CHIPSET_15*/
GLOBAL void app_sim_insert( T_SIMDRV_atr_string_info     *atr_string_info,
                            U8       config_requested,
                            T_SIMDRV_config_characteristics     *config_characteristics)
#endif /*!TI_PS_UICC_CHIPSET_15*/
{
  USHORT       error;
  USHORT       length;
  T_DIR_STATUS dir_status;
  T_FIELD_STATUS field_status;
  UBYTE response[SIMDRV_MAX_RESULT];

  TRACE_FUNCTION ("app_sim_insert()");

#ifdef TI_PS_UICC_CHIPSET_15
  if (atr_string_info NEQ NULL)
  {
    /*
     * stop card detection timer
    */
    vsi_t_stop (VSI_CALLER SIM_TIMER);
  }
  else
  {
    /* SIM reinsert has been automatically detect and hence
       inform ACI */
    T_SIM_ACTIVATE_CNF * sim_activate_cnf;

    PALLOC (sim_activate, SIM_ACTIVATE_IND);
    sim_activate_cnf = (T_SIM_ACTIVATE_CNF *)sim_activate;

    sim_activate_cnf->cause = SIM_CAUSE_SIM_REINSERTED;

    PSENDX (MMI, sim_activate_cnf);

    return;
  }
#else
  /*
     * stop card detection timer
    */
  vsi_t_stop (VSI_CALLER SIM_TIMER);
#endif


#ifdef FF_DUAL_SIM
  if(sim_data.SIM_Selection)
  {
    T_SIM_ACTIVATE_CNF * sim_activate_cnf;

    PALLOC (sim_activate, SIM_ACTIVATE_CNF);
    sim_activate_cnf = sim_activate;

    sim_data.sim_num = SIM_GetSIM();

    sim_activate_cnf->cause = SIM_NO_ERROR;
    sim_activate_cnf->sim_num = (UBYTE)sim_data.sim_num;

    TRACE_EVENT_P1("SIM Selected is %d",sim_activate_cnf->sim_num);

    PSENDX (MMI, sim_activate_cnf);

    SIM_SET_FLAG (SIM_INSERT);

    return;
  }
#endif /*FF_DUAL_SIM*/
  
  /*
   * As per the section 6.5 of 3GPP TS 11.11, After the Answer To Reset (ATR), 
   * the Master File (MF) is implicitly selected and becomes the Current Directory.
   * 
   * Set Current Dir to MF, this makes the selection hit the DF_GSM as it is supposed to !
   */
  sim_data.act_directory = SIM_MF;
    
  /*
   * Read Datafield GSM
   */
  error = FKT_Select (SIM_DF_GSM, FALSE, NULL, response, SIM_MIN_DMF_ST_LEN);
  if (error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
  {
      length = (sim_data.sim_data_len < SIM_MIN_DMF_ST_LEN)?
             sim_data.sim_data_len: SIM_MIN_DMF_ST_LEN;
      memcpy(&dir_status,response,SIM_MIN_DMF_ST_LEN);
      #ifdef TI_PS_UICC_CHIPSET_15
       if (config_requested EQ SIMDRV_REQUEST_CONFIG_CHARACTERISTICS)
       {
         config_characteristics->uicc_characteristics = dir_status.characteristics;
         app_require_uicc_characteristics(config_characteristics);
         memset ((UBYTE *)&dir_status + length, 0, SIM_MIN_DMF_ST_LEN - length);
         return;
       }
      #endif
      memset ((UBYTE *)&dir_status + length, 0, SIM_MIN_DMF_ST_LEN - length);
  }
  if (error NEQ SIM_NO_ERROR)
  {
    /*
     * If not possible read Datafield DCS1800
     * for backward compatibility reasons
     */
    error = FKT_Select (SIM_DF_1800, FALSE, NULL, response, SIM_MIN_DMF_ST_LEN);
    if (error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
    {
      length = (sim_data.sim_data_len < SIM_MIN_DMF_ST_LEN)?
               sim_data.sim_data_len: SIM_MIN_DMF_ST_LEN;
      memcpy(&dir_status,response,SIM_MIN_DMF_ST_LEN);
      #ifdef TI_PS_UICC_CHIPSET_15
       if (config_requested EQ SIMDRV_REQUEST_CONFIG_CHARACTERISTICS)
       {
         config_characteristics->uicc_characteristics = dir_status.characteristics;
         app_require_uicc_characteristics(config_characteristics);
         memset ((UBYTE *)&dir_status + length, 0, SIM_MIN_DMF_ST_LEN - length);
         return;
       }
      #endif
      memset ((UBYTE *)&dir_status + length, 0, SIM_MIN_DMF_ST_LEN - length);
    }
    SIM_CLEAR_FLAG (GSM_DATAFIELD);
  }
  else
    SIM_SET_FLAG (GSM_DATAFIELD);

  if (error NEQ SIM_NO_ERROR)
  {
    /*
     * datafields are not readable
     */
    if (SIM_IS_FLAG_SET (ACTIVATION_STARTED))
    {
      app_sim_card_error ((USHORT)((SIM_IS_FLAG_SET(DRV_FAILED_RETRY))?
                           SIM_CAUSE_DRV_TEMPFAIL: SIM_CAUSE_OTHER_ERROR));
      SIM_CLEAR_FLAG (ACTIVATION_STARTED);
    }
    return;
  }

  {
    T_SIM_ACTIVATE_CNF * sim_activate_cnf;

    if (SIM_IS_FLAG_SET (ACTIVATION_STARTED))
    {
      PALLOC (sim_activate, SIM_ACTIVATE_CNF);
      sim_activate_cnf = sim_activate;
    }
    else
    {
      PALLOC (sim_activate, SIM_ACTIVATE_IND);
      sim_activate_cnf = (T_SIM_ACTIVATE_CNF *)sim_activate;
    }
    /*
     * Read Emergency Call Codes
     */
    memset (sim_activate_cnf->ec_code, NOT_PRESENT_8BIT, MAX_ECC);
    if (FKT_Select (SIM_ECC, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
    {
      memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
      {
        length = (USHORT)field_status.field_size[0] * 256 +
                  field_status.field_size[1];
        if (length > MAX_ECC)
          length = MAX_ECC;
        FKT_ReadBinary (sim_activate_cnf->ec_code, 0, length);
      }
    }
    /*
     * Read Preferred Language
     */
    memset (sim_activate_cnf->pref_lang, NOT_PRESENT_8BIT, MAX_LNG_PREF);
    if (FKT_Select (SIM_LP, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
    {
      memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
      {
        length = (USHORT)field_status.field_size[0] * 256 +
                  field_status.field_size[1];
        if (length > MAX_LNG_PREF)
          length = MAX_LNG_PREF;
        FKT_ReadBinary (sim_activate_cnf->pref_lang, 0, length);
      }
    }
    sim_activate_cnf->cause = SIM_NO_ERROR;
    /*
     * get ATR data
     */
     
    #ifndef TI_PS_UICC_CHIPSET_15
    length = MINIMUM(p_atr->atr_size, MAX_SIM_ATR);
    sim_activate_cnf->c_atr = (UBYTE)length;
    memcpy (sim_activate_cnf->atr, p_atr->atr_data, length);
    #else /*!TI_PS_UICC_CHIPSET_15*/
    length = MINIMUM(atr_string_info->c_atr_string, MAX_SIM_ATR);
    sim_activate_cnf->c_atr = (UBYTE)length;
    memcpy (sim_activate_cnf->atr, atr_string_info->atr_string, length);
    #endif /*!TI_PS_UICC_CHIPSET_15*/

    /*
     * check PIN/PUK status
     */
    SIM_CLEAR_FLAG (SIM_PIN_FLAG);
    /*lint -e{644} (only reachable when SIM_NO_ERROR, then 'dir_status' valid) */
    sim_activate_cnf->pin_cnt  = FKT_check_pin_count (dir_status.pinstatus);
    sim_activate_cnf->puk_cnt  = FKT_check_pin_count (dir_status.unbstatus);
    sim_activate_cnf->pin2_cnt = FKT_check_pin_count (dir_status.pin2status);
    sim_activate_cnf->puk2_cnt = FKT_check_pin_count (dir_status.unb2status);

    
    if (sim_activate_cnf->pin_cnt > 0)
    {
      /*
       * card is not blocked
       */
      if ((dir_status.characteristics & 0x80) EQ 0)
      {
      /*
       * PIN is enabled
       */
        sim_activate_cnf->cause = SIM_CAUSE_PIN1_EXPECT;
        SIM_SET_FLAG (SIM_PIN_FLAG);
      }
    }
    else if (sim_activate_cnf->puk_cnt > 0)
    {
      /*
       * SIM card is blocked, unblock attempts available
       */
      sim_activate_cnf->cause = SIM_CAUSE_PUK1_EXPECT;
      SIM_SET_FLAG (SIM_PIN_FLAG);
    }
    else
    {
      /*
       * SIM card is blocked, no unblock attempts available
       */
      TRACE_EVENT ("Card blocked");
      sim_activate_cnf->cause = SIM_CAUSE_PUK1_BLOCKED;

      SIM_EM_SIM_ACTIVATION_RESULT;

      PSENDX (MMI, sim_activate_cnf);
      SIM_CLEAR_FLAG (ACTIVATION_STARTED);
      return;
    }
    

    SIM_EM_SIM_ACTIVATION_RESULT;

    PSENDX (MMI, sim_activate_cnf);
    SIM_CLEAR_FLAG (ACTIVATION_STARTED);
  }

  SIM_SET_FLAG (SIM_INSERT);

  if (SIM_IS_FLAG_CLEARED (SIM_PIN_FLAG))
    /*
     * PIN entering is not necessary
     */
  {
    TRACE_EVENT ("Read the rest of Parameters");
    app_sim_read_parameters ();
    app_start_status_timer (TRUE);
  }
  else
  {
    TRACE_EVENT ("Wait for PIN/PUK entering");
    SIM_CLEAR_FLAG (MM_KNOWS_FROM_SIM);
    TIMER_STOP (sim_handle, SIM_TIMER);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_read_parameters    |
+--------------------------------------------------------------------+

  PURPOSE : Start the rest of the initialisation procedure.

*/

GLOBAL void app_sim_read_parameters (void)
{
  UBYTE result;

  PALLOC (sim_mmi_insert_ind, SIM_MMI_INSERT_IND);

  TRACE_FUNCTION ("app_sim_read_parameters()");

  app_sim_phase ();

  switch (sim_data.sim_phase)
  {
    case 1:
      // try to read the SIM service table
      if (!app_read_sim_service_table(sim_mmi_insert_ind))
      {
        app_sim_mmi_insert_ind (sim_mmi_insert_ind, SIM_NO_OPERATION);
        return;
      }
      if (app_sim_mm_insert_ind (sim_mmi_insert_ind) EQ FALSE)
        app_sim_mmi_insert_ind (sim_mmi_insert_ind, SIM_NO_OPERATION);
      else
        app_sim_mmi_insert_ind (sim_mmi_insert_ind, SIM_ADN_ENABLED) ;

      PSENDX (MMI, sim_mmi_insert_ind);
      app_sim_sms_insert_ind ();
      break;
    case 3:
#if defined SIM_TOOLKIT
      stk_perform_profile_download ();

       /* Update the Terminal Support table*/
      {
        T_path_info tmp_path;
        tmp_path.df_level1 = SIM_DF_CING;
        tmp_path.v_df_level2 = FALSE;

        if(FKT_Select(SIM_CING_TRMST, TRUE, &tmp_path, NULL, 0) EQ SIM_NO_ERROR)
        {
          FKT_UpdateBinary (sim_data.trmst, MAX_TRMST, 0);
        }
      }
      SIM_EM_SIM_TOOLKIT_ACTIVATION;

#endif
    /* no break;*/
    /*lint -fallthrough*/
    case 2:
      /* includes reading of the SIM service table*/
      result = app_fdn_bdn_procedures (sim_mmi_insert_ind);
      if ((result EQ SIM_NO_OPERATION) OR
          !app_sim_mm_insert_ind (sim_mmi_insert_ind))
        app_sim_mmi_insert_ind (sim_mmi_insert_ind, SIM_NO_OPERATION);
      else
        app_sim_mmi_insert_ind (sim_mmi_insert_ind, result);

      PSENDX (MMI, sim_mmi_insert_ind);
      if (result NEQ SIM_NO_OPERATION)
        app_sim_sms_insert_ind ();
      break;
    default:
      break;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_phase              |
+--------------------------------------------------------------------+

  PURPOSE : Read the phase identification.

*/

GLOBAL void app_sim_phase (void)
{
  USHORT error;

  TRACE_FUNCTION ("app_sim_phase()");
  error = FKT_Select (SIM_PHASE, FALSE, NULL, NULL, 0);
  if (error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
    error = FKT_ReadBinary (&sim_data.sim_phase, 0, 1);

  /*
   * Default is phase 1 SIM card
   * G23 interpretation is
   * 1: Phase 1
   * 2: Phase 2
   * 3: Phase 2+
   */
  if (error NEQ SIM_NO_ERROR)
    sim_data.sim_phase = 1;
  else
  {
    if (sim_data.sim_phase EQ 0)
      sim_data.sim_phase = 1;
//TISH, patch for OMAPS00122397
//start
     else if (sim_data.sim_phase EQ 0xFF)
          sim_data.sim_phase = 3;
//end
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_read_sim_service_table |
+--------------------------------------------------------------------+

  PURPOSE : Read the SIM Service Table.

*/

LOCAL UBYTE app_read_sim_service_table (T_SIM_MMI_INSERT_IND * sim_mmi_insert_ind)
{
  USHORT length;
  USHORT error;
  T_FIELD_STATUS field_status;
  UBYTE response[SIMDRV_MAX_RESULT];

  /*
   * read SIM service table
   * Currently selected EF information is reset to force the selection 
   */
  sim_data.act_field = NOT_PRESENT_16BIT;

  error = FKT_Select (SIM_SST, FALSE, NULL, response, SIM_MIN_EF_ST_LEN);
  if (error EQ SIM_NO_ERROR)
  {
     memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);

     length = (USHORT)field_status.field_size[0] * 256
               + field_status.field_size[1];
     if (length > MAX_SRV_TBL)

       length = MAX_SRV_TBL;
     memset (sim_mmi_insert_ind->sim_serv, 0, MAX_SRV_TBL);
     if (FKT_ReadBinary (sim_mmi_insert_ind->sim_serv, 0, length) NEQ SIM_NO_ERROR)
       return FALSE;
  }
  else
    return FALSE;

 /*
  * set flags according to the allocated and activated services
  */
  if (SERVICE(1,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_1_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_1_SUPPORT);

  if (SERVICE(2,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_2_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_2_SUPPORT);

  if (SERVICE(3,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_3_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_3_SUPPORT);

  if (SERVICE(4,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_4_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_4_SUPPORT);

  if (SERVICE(7,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_7_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_7_SUPPORT);

  if (SERVICE(26,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_26_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_26_SUPPORT);

  if (SERVICE(31,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_31_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_31_SUPPORT);

  if (SERVICE(35,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_35_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_35_SUPPORT);
  
  if ((SERVICE(39,sim_mmi_insert_ind->sim_serv) & ALLOCATED)
       AND FKT_Select (SIM_DF_GRAPHICS, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
    SIM_SET_FLAG (DF_GRAPHICS_EXISTENT);
  else
    SIM_CLEAR_FLAG (DF_GRAPHICS_EXISTENT);
  
  if ((SERVICE(40,sim_mmi_insert_ind->sim_serv) & ALLOCATED)
       AND FKT_Select (SIM_DF_SOLSA, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
    SIM_SET_FLAG (DF_SOLSA_EXISTENT);
  else
    SIM_CLEAR_FLAG (DF_SOLSA_EXISTENT);

  /* @@TODO -- CHECK THE SERVICE NUMBER */
  if (FKT_Select (SIM_DF_ORANGE, FALSE,NULL, NULL, 0) EQ SIM_NO_ERROR)
    SIM_SET_FLAG (DF_ORANGE_EXISTENT);
  else
    SIM_CLEAR_FLAG (DF_ORANGE_EXISTENT);

#ifdef REL99
  /*
   * SET SERVICE FLAG for SERVICE 43 if "user controlled PLMN Selector with 
   * Access Technology" is supported
   */
  if (SERVICE(43,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_43_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_43_SUPPORT);

  /*
   * SET SERVICE FLAG for SERVICE 44 if "Operator controlled PLMN Selector with 
   * Access Technology" is supported
   */  
  if (SERVICE(44,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_44_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_44_SUPPORT);
#endif /* REl99 */

#if defined (GPRS)
  if (SERVICE(38,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (SERVICE_38_SUPPORT);
  else
    SIM_CLEAR_FLAG (SERVICE_38_SUPPORT);
#endif

#ifdef SIM_TOOLKIT
  if (SERVICE(29,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
    SIM_SET_FLAG (PRO_ACTIVE_SIM);
  else
    SIM_CLEAR_FLAG (PRO_ACTIVE_SIM);
#endif
  return TRUE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_mm_insert_ind      |
+--------------------------------------------------------------------+

  PURPOSE : Reads some fields and build SIM_MM_INSERT_IND.

*/

GLOBAL UBYTE app_sim_mm_insert_ind (T_SIM_MMI_INSERT_IND * sim_mmi_insert_ind)
{
  UBYTE  kc_n [MAX_KC_N];
  int    i;
  USHORT error;
  USHORT  length;
  T_FIELD_STATUS field_status;
  USHORT FileSelRes;
  UBYTE response[SIMDRV_MAX_RESULT];
  T_path_info  tmp_path;
  
  /*
   * Read remaining parameters for mobility management
   */
  PALLOC (sim_mm_insert_ind, SIM_MM_INSERT_IND);

  TRACE_FUNCTION ("app_sim_mm_insert_ind()");

  SIM_EM_READ_MM_PARAMETER;

  SIM_CLEAR_FLAG (TEST_SIM_INSERTED);
#if defined SIM_TOOLKIT
  SIM_CLEAR_FLAG (TEST_MODE_POLLING);
#endif
  /*
   * read administrative data
   */
  memset (&sim_mmi_insert_ind->ad, 0, MAX_AD);
  error = FKT_Select (SIM_AD, FALSE, NULL, response, SIM_MIN_EF_ST_LEN);

  if ( error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
  {
    memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);
    {
      length = field_status.field_size[0] * 256 +
                  field_status.field_size[1];
      
      if(length > MAX_AD)
        length = MAX_AD;
      
      sim_mm_insert_ind->c_ad = (UBYTE)length;
      if(FKT_ReadBinary ((UBYTE *)&sim_mm_insert_ind->ad, 0, length) EQ SIM_NO_ERROR)
      {
        TRACE_EVENT_P1("The length of AD is %d", length);
      }
      else
      {
        PFREE (sim_mm_insert_ind);
        return FALSE;
      }
    }

    sim_mmi_insert_ind->c_ad = sim_mm_insert_ind->c_ad;
    memcpy (&sim_mmi_insert_ind->ad, &sim_mm_insert_ind->ad,sim_mmi_insert_ind->c_ad);


    if(sim_mm_insert_ind->ad[0] & 0x80)
    {
      SIM_SET_FLAG (TEST_SIM_INSERTED);
#if defined SIM_TOOLKIT
      TRACE_EVENT("REG POLLING");
      SIM_SET_FLAG (TEST_MODE_POLLING);
#endif
    }

  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }

  /*
   * read IMSI (set to zero in case of error)
   */
  memset (&sim_mmi_insert_ind->imsi_field, 0, sizeof (T_imsi_field));
  if (FKT_Select (SIM_IMSI, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    if (FKT_ReadBinary ((UBYTE *)&sim_mm_insert_ind->imsi_field, 0, MAX_IMSI)
        NEQ SIM_NO_ERROR)
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
    /*
     * Check length of IMSI for validity
     */
    if ((sim_mm_insert_ind->imsi_field.c_field <= 3) OR
        (sim_mm_insert_ind->imsi_field.c_field > MAX_IMSI-1))
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
    memcpy (&sim_mmi_insert_ind->imsi_field, &sim_mm_insert_ind->imsi_field,
            sizeof (T_imsi_field));
    /*
     * Modify polling algorithm in case of HPLMN == Test Network
     */
    if ((sim_mm_insert_ind->imsi_field.c_field >= 3) AND
        ((sim_mm_insert_ind->imsi_field.field[0] & 0xF7) EQ 0x01) AND
        (sim_mm_insert_ind->imsi_field.field[1] EQ 0x10) AND
        (sim_mm_insert_ind->imsi_field.field[2] EQ 0x10))
    {
      SIM_SET_FLAG (TEST_SIM_INSERTED);
#if defined SIM_TOOLKIT
      TRACE_EVENT("REG POLLING");
      SIM_SET_FLAG (TEST_MODE_POLLING);
#endif
    }
  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }

  /*
   * read location information
   */
  if (FKT_Select (SIM_LOCI, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    sim_mm_insert_ind->loc_info.c_loc = MAX_LOC_INFO;
    if (FKT_ReadBinary ((UBYTE *)sim_mm_insert_ind->loc_info.loc, 0,
                         MAX_LOC_INFO) NEQ SIM_NO_ERROR)
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }

  /*
   * Access control classes
   */
  if (FKT_Select (SIM_ACC, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    sim_mm_insert_ind->acc_ctrl.c_acc = MAX_ACCESS_CONTROL;
    if (FKT_ReadBinary ((UBYTE *)sim_mm_insert_ind->acc_ctrl.acc, 0,
                         MAX_ACCESS_CONTROL) NEQ SIM_NO_ERROR)
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }

  /*
   * BCCH information
   */
  if (FKT_Select (SIM_BCCH, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    sim_mm_insert_ind->bcch_inf.c_bcch = MAX_BCCH_INFO;
    if (FKT_ReadBinary ((UBYTE *)sim_mm_insert_ind->bcch_inf.bcch, 0,
                        MAX_BCCH_INFO) NEQ SIM_NO_ERROR)
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }

  /*
   * KC and cipher key sequence number
   */
  if (FKT_Select (SIM_KC, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    if (FKT_ReadBinary ((UBYTE *)kc_n, 0, MAX_KC_N) NEQ SIM_NO_ERROR)
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
    else
    {
      sim_mm_insert_ind->kc_n.c_kc = MAX_KC_N;
      /*
       * Store KC in opposite order
       */
      for (i = 0; i < MAX_KC; i++)
        sim_mm_insert_ind->kc_n.kc[(MAX_KC-1)-i] = kc_n[i];
      /*
       * Store cipher key sequence number
       */
      sim_mm_insert_ind->kc_n.kc[MAX_KC]   = kc_n[MAX_KC];
    }
  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }
  
  /*
   * Read Preferred PLMN information
   * Initialize preferred plmn information is not present
   */
  sim_mm_insert_ind->pref_plmn_list_sz = 
     app_get_ef_size(SERVICE_7_SUPPORT, SIM_PLMNSEL,response);

  /*
   * Read forbidden PLMNs
   */
  if (FKT_Select (SIM_FPLMN, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    sim_mm_insert_ind->forb_plmn.c_forb = MAX_FORB_PLMN;
    if (FKT_ReadBinary ((UBYTE *)sim_mm_insert_ind->forb_plmn.forb, 0,
                        MAX_FORB_PLMN) NEQ SIM_NO_ERROR)
    {
      PFREE (sim_mm_insert_ind);
      return FALSE;
    }
  }
  else
  {
    PFREE (sim_mm_insert_ind);
    return FALSE;
  }

#ifdef REL99
  /*
   * Extract "User controlled PLMN Selector with Access Technology" Information
   * Initially set 'usr ctrl plmn selector with Access Technology informaiton' is not present
   */
  sim_mm_insert_ind->u_ctl_plmn_sel_actech_list_sz = 
    app_get_ef_size(SERVICE_43_SUPPORT, SIM_UCPS_ACTEC,response);

  /*
   * Extract "Operator controlled PLMN Selector with Access Technology" Information
   * Initailly set 'operator ctrl plmn with Access Technology informaiton' is not present
   */
  sim_mm_insert_ind->o_ctl_plmn_sel_actech_list_sz = 
    app_get_ef_size(SERVICE_44_SUPPORT, SIM_OCPS_ACTEC,response);

#endif /* REl99 */

  /*
   * Read Acting HPLMN 
   */
  tmp_path.df_level1   = SIM_DF_CING;
  tmp_path.v_df_level2 = TRUE;
  tmp_path.df_level2   = SIM_DF2_CING;

  FileSelRes = FKT_Select(SIM_CING_AHPLMN, TRUE, &tmp_path, NULL, 0);

  if( FileSelRes EQ SIM_NO_ERROR)
  {
    sim_mm_insert_ind->v_act_hplmn = TRUE;
    if(FKT_ReadBinary ((UBYTE *)sim_mm_insert_ind->act_hplmn, 0,
                       MAX_SIM_PLMN_SIZE) NEQ SIM_NO_ERROR)
    {
      sim_mm_insert_ind->v_act_hplmn = FALSE;
    }
  }
  else
  {
    sim_mm_insert_ind->v_act_hplmn = FALSE;
  }
  
  
  /*
   * set phase identification and
   * default value for hplmn search period
   * for phase 1 card.
   */
  sim_mm_insert_ind->phase = sim_data.sim_phase;
  /*
   * 3GPP 23.122 clause 4.4.3.3 states the default search period
   * is now 60 minutes. This is different from ETSI 03.22
   * clause 4.4.3.3 where the default value was only 30 minutes.
   */
  sim_mm_insert_ind->hplmn = 10;

  if (sim_data.sim_phase NEQ PHASE_1_SIM)
  {
    if (FKT_Select (SIM_HPLMN, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
    {
      if (FKT_ReadBinary (&sim_mm_insert_ind->hplmn, 0, 1)
          NEQ SIM_NO_ERROR)
        sim_mm_insert_ind->hplmn = 10;
    }
  }

#if defined (GPRS)
  gprs_gmm_insert_ind (sim_mm_insert_ind);
#endif

  /*
   * send information to mobility management
   */
  PSENDX (MM, sim_mm_insert_ind);
  SIM_SET_FLAG (MM_KNOWS_FROM_SIM);

  return TRUE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_mmi_insert_ind     |
+--------------------------------------------------------------------+

  PURPOSE : Build the primitive SIM_MMI_INSERT_IND.
*/

GLOBAL void app_sim_mmi_insert_ind (T_SIM_MMI_INSERT_IND * sim_mmi_insert_ind, UBYTE func)
{
  T_FIELD_STATUS field_status;
  USHORT  length;
  UBYTE response[SIMDRV_MAX_RESULT];

  TRACE_FUNCTION ("app_sim_mmi_insert_ind()");

  SIM_EM_READ_MMI_PARAMETER;

  /*
   * copy parameters known from MM INSERT reading
   */

  sim_mmi_insert_ind->func = func;

  if (func & 1)
    SIM_SET_FLAG (ADN_SUPPORT_BY_SIM);
  else
    SIM_CLEAR_FLAG (ADN_SUPPORT_BY_SIM);

  if (func & 2)
    SIM_SET_FLAG (FDN_SUPPORT_BY_SIM);
  else
    SIM_CLEAR_FLAG (FDN_SUPPORT_BY_SIM);

  if (func & 4)
    SIM_SET_FLAG (BDN_SUPPORT_BY_SIM);
  else
    SIM_CLEAR_FLAG (BDN_SUPPORT_BY_SIM);

  sim_mmi_insert_ind->phase = sim_data.sim_phase;

  /*
   * check access conditions for AoC fields
   * Currently selected EF information is reset to force the selection
   */

  sim_data.act_field = NOT_PRESENT_16BIT;
  sim_mmi_insert_ind->access_acm = NOT_PRESENT_8BIT;
  if (FKT_Select (SIM_ACM, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
  {
    memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);
    sim_mmi_insert_ind->access_acm = field_status.access_1 & 0x0F;
  }
  
  sim_mmi_insert_ind->access_acmmax = NOT_PRESENT_8BIT;
  if (FKT_Select (SIM_ACMMAX, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
  {
    memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);
    sim_mmi_insert_ind->access_acmmax = field_status.access_1 & 0x0F;
  }
  
  sim_mmi_insert_ind->access_puct   = NOT_PRESENT_8BIT;
  if (FKT_Select (SIM_PUCT, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
  {
    memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);
    sim_mmi_insert_ind->access_puct = field_status.access_1 & 0x0F;
  }

  TRACE_EVENT_P1 ("Access ACM    = %d", sim_mmi_insert_ind->access_acm);
  TRACE_EVENT_P1 ("Access ACMMAX = %d", sim_mmi_insert_ind->access_acmmax);
  TRACE_EVENT_P1 ("Access PUCT   = %d", sim_mmi_insert_ind->access_puct);

#ifdef SIM_TOOLKIT
  if ( (SERVICE(25,sim_mmi_insert_ind->sim_serv) EQ ALLOCATED_AND_ACTIVATED)
        AND  (sim_data.stk_profile[0] & SAT_TP1_CB_DNL) )
  {
    if (FKT_Select (SIM_CBMID, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
    {
      memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);
      {
        length = field_status.field_size[0] * 256 +
                    field_status.field_size[1];
      
        length =  MINIMUM(length, MAX_CBMID_REC);

        sim_mmi_insert_ind->cbmid_rec.c_rec = (UBYTE)length;
      
        if(FKT_ReadBinary ((UBYTE *)sim_mmi_insert_ind->cbmid_rec.rec, 0, length) 
              EQ SIM_NO_ERROR)
        {
          TRACE_EVENT_P1("The length of CBMID is %d", length);
        }
      }
    }
  }
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_sms_insert_ind     |
+--------------------------------------------------------------------+

  PURPOSE : Build the primitive SIM_SMS_INSERT_IND.
*/

GLOBAL void app_sim_sms_insert_ind (void)
{
  PALLOC (sim_sms_insert_ind, SIM_SMS_INSERT_IND);

  TRACE_FUNCTION ("app_sim_sms_insert_ind()");

  SIM_EM_READ_SMS_PARAMETER;

  memset (sim_sms_insert_ind, 0, sizeof(T_SIM_SMS_INSERT_IND));
  sim_sms_insert_ind->mem_cap_avail = SIM_SMS_NO_MEM;
  /*
   * Read SMS Status
   */
  if (SIM_IS_FLAG_SET (SERVICE_4_SUPPORT))
  {
    USHORT     error;
    error = FKT_Select (SIM_SMSS, FALSE, NULL, NULL, 0);
    if (error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
    {
      if (FKT_ReadBinary (&sim_sms_insert_ind->tp_mr, 0, 2)
                           EQ SIM_NO_ERROR)
      {
        sim_sms_insert_ind->mem_cap_avail &= 1;
      }
      else
      {
        sim_sms_insert_ind->mem_cap_avail = SIM_SMS_MEM_AVAIL;
      }
    }
    else if (sim_data.sim_phase < PHASE_2_SIM)
    {
      sim_sms_insert_ind->mem_cap_avail = SIM_SMS_MEM_AVAIL;
    }
  }
  /*
   * check SIM phase and determine support of SMS data download
   */
  sim_sms_insert_ind->phase = sim_data.sim_phase;

  switch (sim_data.sim_phase)
  {
    case 1:
    case 2:
      sim_sms_insert_ind->download_sms = DOWNLOAD_SMS_NO;
      break;
    case 3:
#ifdef SIM_TOOLKIT
      /*
       * check service 26: data download via point-to-point SMS
       */
      if (SIM_IS_FLAG_SET (SERVICE_26_SUPPORT))
        sim_sms_insert_ind->download_sms = DOWNLOAD_SMS_YES;
      else
#endif
        sim_sms_insert_ind->download_sms = DOWNLOAD_SMS_NO;
      break;
  }
  /*
   * check service 35: store SM Status Reports
   */
  if (SIM_IS_FLAG_SET (SERVICE_35_SUPPORT))
    sim_sms_insert_ind->smsr_mem_cap = SIM_SMSR_ENABLE;
  else
    sim_sms_insert_ind->smsr_mem_cap = SIM_SMSR_DISABLE;

  /*
   * send information to short message service
   */
  PSENDX (SMS, sim_sms_insert_ind);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_remove             |
+--------------------------------------------------------------------+

  PURPOSE : Hook function for SIM driver after SIM remove.

*/

GLOBAL void app_sim_remove (void)
{
  TRACE_FUNCTION ("app_sim_remove()");
#ifdef SIM_TOOLKIT
  stk_stop_all_sat_timers ();
#endif
  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    {
      PALLOC (sim_remove_ind_to_mm , SIM_REMOVE_IND);
      sim_remove_ind_to_mm->cause = sim_data.remove_error;
      PSENDX (MM, sim_remove_ind_to_mm);
    }
#ifdef GPRS
    {
      PALLOC (sim_remove_ind_to_gmm , SIM_REMOVE_IND);
      sim_remove_ind_to_gmm->cause = sim_data.remove_error;
      PSENDX (GMM, sim_remove_ind_to_gmm);
    }
#endif
    {
      PALLOC (sim_remove_ind_to_mmi, SIM_REMOVE_IND);
      sim_remove_ind_to_mmi->cause = sim_data.remove_error;
      PSENDX (MMI, sim_remove_ind_to_mmi);
    }
    {
      PALLOC (sim_remove_ind_to_sms, SIM_REMOVE_IND);
      sim_remove_ind_to_sms->cause = sim_data.remove_error;
      PSENDX (SMS, sim_remove_ind_to_sms);
    }
    SIM_EM_SIM_REMOVE;
  }
  SIM_CLEAR_FLAG (SIM_INSERT);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_timeout            |
+--------------------------------------------------------------------+

  PURPOSE : A timeout has occured.

*/

GLOBAL void app_sim_timeout (U16 timer)
{
  USHORT error;
  UBYTE pin_cnt, pin2_cnt, puk_cnt, puk2_cnt;

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    /*
     * Presence check all thirty seconds
     */
     if (timer EQ SLEEP_TIMER AND sim_data.sat_session EQ TRUE)
     {
       TRACE_EVENT("STK SESSION RUNNING");
       return;
     }
     	
    if ((error = FKT_Status (&pin_cnt, &pin2_cnt, &puk_cnt, &puk2_cnt))
        NEQ SIM_NO_ERROR)
    {
    /* stop Poll Timer*/
      TIMER_STOP (sim_handle, SIM_TIMER);

      sim_data.remove_error = error;
      app_sim_remove ();
      sim_data.remove_error = SIM_CAUSE_CARD_REMOVED;
    }
  
#ifdef TI_PS_FF_SIM_POLL_ALWAYS
  
    else
    {
#if defined SIM_TOOLKIT
      if(SIM_IS_FLAG_SET (PRO_ACTIVE_SIM))
      {
      stk_proactive_polling();
      }
      else
#endif
      {
          TRACE_FUNCTION ("Restarting timer for polling non-proactive SIMs");
          app_start_status_timer(FALSE);
      }
    }
  
#else
  
#if defined SIM_TOOLKIT
    else
      stk_proactive_polling();
#endif
  
#endif
  
  }
  else if (SIM_IS_FLAG_SET (ACTIVATION_STARTED))
  {
    /*
     * Timeout indicates no recognition of
     * a SIM card by the driver
     */
    app_sim_card_error (SIM_CAUSE_CARD_REMOVED);
    SIM_CLEAR_FLAG (ACTIVATION_STARTED);
  }
  else if (SIM_IS_FLAG_SET(DRV_FAILED_RETRY))
  {
    /*
     * Timeout indicates failed recovery after
     * a SIM driver retry failure
     */
    app_sim_remove();
    SIM_CLEAR_FLAG(DRV_FAILED_RETRY);
  }
  else
  {
    /*
     * Timer may still run in case of auto-restart
     */
    TIMER_STOP (sim_handle, SIM_TIMER);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_card_error         |
+--------------------------------------------------------------------+

  PURPOSE : An error is signalled to MMI.

*/

GLOBAL void app_sim_card_error (USHORT error)
{
  PALLOC (sim_activate_cnf, SIM_ACTIVATE_CNF);

  memset (sim_activate_cnf, NOT_PRESENT_8BIT, sizeof (T_SIM_ACTIVATE_CNF));

#ifdef FF_DUAL_SIM
  if(sim_data.SIM_Selection)
  {
    sim_activate_cnf->sim_num = SIM_NUM_0;
    sim_activate_cnf->cause = error;

    PSENDX (MMI, sim_activate_cnf);

    return;
  }
#endif /*FF_DUAL_SIM*/

  sim_activate_cnf->pin_cnt = sim_activate_cnf->puk_cnt = 0;
  sim_activate_cnf->pin2_cnt = sim_activate_cnf->puk2_cnt = 0;
  sim_activate_cnf->cause = error;
  sim_activate_cnf->c_atr = 0;

  SIM_EM_SIM_ACTIVATION_RESULT;

  PSENDX (MMI, sim_activate_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_mm_update_req      |
+--------------------------------------------------------------------+

  PURPOSE : Process of the primitive SIM_MM_UPDATE_REQ.

*/

GLOBAL void app_sim_mm_update_req (T_SIM_MM_UPDATE_REQ * sim_mm_update_req)
{
  int    i;
  USHORT error;
  T_kc_n kc_n;
  BOOL all_upd = TRUE;

  TRACE_FUNCTION ("app_sim_mm_update_req()");

  /*
   * check location information
   */
  if (sim_mm_update_req->loc_info.c_loc > 0)
  {
#if defined SIM_TOOLKIT
    memcpy (&sim_data.location_info, &sim_mm_update_req->loc_info,
            sizeof (sim_data.location_info));
#endif
    if(sim_mm_update_req->ef_indicator & 0x01)
    {
      error = FKT_Select (SIM_LOCI, FALSE, NULL, NULL, 0);
      if (error EQ SIM_NO_ERROR)
        error = FKT_UpdateBinary (sim_mm_update_req->loc_info.loc,
                                  (USHORT)sim_mm_update_req->loc_info.c_loc, 0);
      if (error NEQ SIM_NO_ERROR)
      {
  #ifdef REL99
        if (error EQ SIM_CAUSE_MEM_PROBLEM)
        {
          /*
           * In case when updating EF LOCI with data containing the 
           * TMSI value and the card reports the error '92 40' (Memory Problem),
           * the ME shall terminate GSM operation.
           */
          sim_data.remove_error = SIM_CAUSE_MEM_PROBLEM;
          app_sim_remove();
          PFREE (sim_mm_update_req);
          return;
        }
  #endif /* end of ifdef REL99 */
        all_upd = FALSE;
      }
    }
#if defined SIM_TOOLKIT
    sim_data.cell_identity = sim_mm_update_req->cell_identity;
    /*
     * Modify polling algorithm if connected to Test Network
     */
    if ((sim_mm_update_req->loc_info.c_loc >= 7) AND
        (sim_mm_update_req->loc_info.loc[4] EQ 0x00) AND
        ((sim_mm_update_req->loc_info.loc[5] & 0x0F) EQ 0x1) AND
        (sim_mm_update_req->loc_info.loc[6] EQ 0x10))
    {
      TRACE_EVENT("REG POLLING");
      SIM_SET_FLAG (TEST_MODE_POLLING);
    }
    else if (SIM_IS_FLAG_CLEARED (TEST_SIM_INSERTED))
    {
      TRACE_EVENT("STD POLLING");
      SIM_CLEAR_FLAG (TEST_MODE_POLLING);
    }
#endif
  }

  /*
   * check bcch information
   */
  if(sim_mm_update_req->ef_indicator & 0x02)
  {
    if (sim_mm_update_req->bcch_inf.c_bcch > 0)
    {
      error = FKT_Select (SIM_BCCH, FALSE, NULL, NULL, 0);
      if (error EQ SIM_NO_ERROR)
        error = FKT_UpdateBinary (sim_mm_update_req->bcch_inf.bcch,
                                  (USHORT)sim_mm_update_req->bcch_inf.c_bcch, 0);
      if (error NEQ SIM_NO_ERROR)
        all_upd = FALSE;
    }
  }

  /*
   * check forbidden PLMN
   */
  if(sim_mm_update_req->ef_indicator & 0x04)
  {
    if (sim_mm_update_req->forb_plmn.c_forb > 0)
    {
      error = FKT_Select (SIM_FPLMN, FALSE, NULL, NULL, 0);
      if (error EQ SIM_NO_ERROR)
        error = FKT_UpdateBinary (sim_mm_update_req->forb_plmn.forb,
                                  (USHORT)sim_mm_update_req->forb_plmn.c_forb, 0);
      if (error NEQ SIM_NO_ERROR)
        all_upd = FALSE;
    }
  }

  /*
   * check kc and cksn
   */
  if(sim_mm_update_req->ef_indicator & 0x08)
  {
    error = FKT_Select (SIM_KC, FALSE, NULL, NULL, 0);
    if (error EQ SIM_NO_ERROR)
    {
      kc_n.c_kc = 9;
      kc_n.kc[8] = sim_mm_update_req->cksn;
      for (i = 0; i < 8; i++)
        kc_n.kc[7-i] = sim_mm_update_req->kc[i];
      error = FKT_UpdateBinary (kc_n.kc, (USHORT)kc_n.c_kc, 0);
    }
    if (error NEQ SIM_NO_ERROR)
      all_upd = FALSE;
  }

  SIM_EM_PARAMETER_UPDATE;

  PFREE (sim_mm_update_req);

  if (all_upd)
    app_start_status_timer (FALSE);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_sync_req           |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_SYNC_REQ.

*/

GLOBAL void app_sim_sync_req (T_SIM_SYNC_REQ * sim_sync_req)
{
  #ifdef TI_PS_UICC_CHIPSET_15
  U8 reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN;
  #endif
  PALLOC (sim_sync_cnf, SIM_SYNC_CNF);
  sim_sync_cnf->cause = SIM_NO_ERROR;

  TRACE_FUNCTION ("app_sim_sync_req()");

  SIM_EM_PARAMETER_SYNCHRONISATION;

  switch (sim_sync_req->synccs)
  {
    case SYNC_START_CALL:
      SIM_SET_FLAG (CALL_ACTIVE);
      PSENDX (MMI, sim_sync_cnf);
      app_sim_timeout (SIM_TIMER);               /* checks SIM status!*/
      app_start_status_timer (TRUE);    /* restart SIM presence detection*/
      break;

    case SYNC_STOP_CALL:
      SIM_CLEAR_FLAG (CALL_ACTIVE);
      /*
       * only if SIM inserted
       */
      if (SIM_IS_FLAG_SET (SIM_INSERT))
      {
#if defined SIM_TOOLKIT
        /*
         * if SIM Toolkit is active, idle polling
         * might be needed, additionally
         */
        if (SIM_IS_FLAG_CLEARED (PRO_ACTIVE_SIM))
#endif
        {
        /*
         * Stop presence detection polling, after Call
         */
          TIMER_STOP (sim_handle, SIM_TIMER);
        }
#if defined SIM_TOOLKIT
        else if (sim_data.idle_polling)
        {
          app_start_status_timer (TRUE);
        }
#endif
      }
      else
        sim_sync_cnf->cause = SIM_CAUSE_CARD_REMOVED;

      PSENDX (MMI, sim_sync_cnf);
      break;


    case SYNC_MM_FINISHED_READING:
#if defined SIM_TOOLKIT
      if(sim_data.sync_awaited & SIM_SYNC_AWAIT_MM_READ)
      {
        sim_data.sync_awaited &= ~SIM_SYNC_AWAIT_MM_READ;
        /* Check if both MM and MMI have sent SYNC_REQ */
        if(sim_data.sync_awaited EQ 0 AND sim_data.stk_resp_len NEQ 0)
        {
          FKT_TerminalResponse (sim_data.stk_response, (USHORT)sim_data.stk_resp_len);
          sim_data.stk_resp_len = 0;
        }
      }
#endif /* SIM_TOOLKIT */
      PSENDX (MM, sim_sync_cnf);
      break;

    case SYNC_MMI_FINISHED_READING:
#if defined SIM_TOOLKIT
      if(sim_data.sync_awaited & SIM_SYNC_AWAIT_MMI_READ)
      {
        sim_data.sync_awaited &= ~SIM_SYNC_AWAIT_MMI_READ;
        /* Check if both MM and MMI have sent SYNC_REQ */
        if(sim_data.sync_awaited EQ 0 AND sim_data.stk_resp_len NEQ 0)
        {
          FKT_TerminalResponse (sim_data.stk_response, (USHORT)sim_data.stk_resp_len);
          sim_data.stk_resp_len = 0;
        }
      }
#endif /* SIM_TOOLKIT */
      PSENDX (MMI, sim_sync_cnf);
      break;

    case SYNC_DEACTIVATE:
      TIMER_STOP (sim_handle, SIM_TIMER);
#ifdef SIM_TOOLKIT
      stk_stop_all_sat_timers ();
#endif
      PSENDX (MMI, sim_sync_cnf);
      /*
       * switch off SIM driver
       */
#ifndef TI_PS_UICC_CHIPSET_15
      SIM_PowerOff ();
#else
      simdrv_poweroff( reader_id );
#endif
      SIM_CLEAR_FLAG (SIM_INSERT);
      /*
       * Initialize SIM for next Power On
       */
      app_init_sim_data ();
      break;

    default:
      sim_sync_cnf->cause = SIM_CAUSE_PARAM_WRONG;
      PSENDX (MMI, sim_sync_cnf);
      break;
  }
  PFREE (sim_sync_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_activate_req       |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_ACTIVATE_REQ.

*/

GLOBAL void app_sim_activate_req (T_SIM_ACTIVATE_REQ * sim_activate_req)
{
  USHORT     retcode;

#ifdef TI_PS_UICC_CHIPSET_15
  U8 reader_id =SIMDRV_VAL_READER_ID__RANGE_MIN;
  U8 voltage_select = SIMDRV_REQ_VOLTAGE_SEL;
#endif  /* TI_PS_UICC_CHIPSET_15 */
#if defined  FF_DUAL_SIM OR (!defined TI_PS_UICC_CHIPSET_15)
  T_SIM_CARD sim_info;
#endif  /* FF_DUAL_SIM  OR TI_PS_UICC_CHIPSET_15*/

  TRACE_FUNCTION ("app_sim_activate_req()");

  switch (sim_activate_req->proc)
  {
    case SIM_INITIALISATION:
      SIM_SET_FLAG (ACTIVATION_STARTED);
      SIM_CLEAR_FLAG (CALL_ACTIVE);
      sim_data.act_directory = NOT_PRESENT_16BIT;
      sim_data.act_field     = NOT_PRESENT_16BIT;
      sim_data.status_time   = THIRTY_SECONDS;
      sim_data.cust_mode     = sim_activate_req->cust_mode;

      if (sim_activate_req->mmi_pro_file & SIM_MMI_BDN)
        SIM_SET_FLAG (BDN_SUPPORT_BY_MMI);
      else
        SIM_CLEAR_FLAG (BDN_SUPPORT_BY_MMI);

      if (sim_activate_req->mmi_pro_file & SIM_MMI_FDN)
        SIM_SET_FLAG (FDN_SUPPORT_BY_MMI);
      else
        SIM_CLEAR_FLAG (FDN_SUPPORT_BY_MMI);

      SIM_CLEAR_FLAG (CC_WITH_STK);

#if defined SIM_TOOLKIT
      stk_check_tp (sim_data.stk_profile, sim_activate_req->stk_pro_file,
                    MINIMUM(sizeof sim_data.stk_profile, sizeof sim_activate_req->stk_pro_file));
      if (sim_data.stk_profile[1] & SAT_TP2_CC)
        SIM_SET_FLAG (CC_WITH_STK);

      if(sim_activate_req->v_trmst_file)
      {
        memcpy (sim_data.trmst, sim_activate_req->trmst_file, sizeof(sim_activate_req->trmst_file));
      }
      else
      {
        memset (sim_data.trmst, FALSE, MAX_TRMST);
      }
#endif

      TIMER_START (sim_handle, SIM_TIMER, T_DETECT_VALUE);
  #ifndef TI_PS_UICC_CHIPSET_15
      retcode = SIM_Reset (&sim_info);   
  #else
      retcode = simdrv_reset( reader_id, voltage_select);
  #endif

      TRACE_EVENT_P1 ("Result SIM Reset = %d", (int)retcode);

      switch (retcode)
      {
        case 0:
          /*
           * No problem
           */
          break;
        case 1:
        case 3:
        case 8:
        case 9:
          /*
           * No card inserted
           */
          TIMER_STOP (sim_handle, SIM_TIMER);

          app_sim_card_error (SIM_CAUSE_CARD_REMOVED);
          SIM_CLEAR_FLAG (SIM_INSERT);
          SIM_CLEAR_FLAG (ACTIVATION_STARTED);
          break;
        default:
          /*
           * other card problems
           */
          TIMER_STOP (sim_handle, SIM_TIMER);
          app_sim_card_error (CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS,
                                         SIM_ORIGINATING_ENTITY, retcode));
          SIM_CLEAR_FLAG (SIM_INSERT);
          SIM_CLEAR_FLAG (ACTIVATION_STARTED);
          break;
      }

      break;

    case SIM_FDN_ENABLE:
       /* Implements Measure# 14 */
       app_sim_activate_req_fdn_enable(TRUE); 
      break;
    
    case SIM_FDN_DISABLE:
       /* Implements Measure# 14 */
       app_sim_activate_req_fdn_enable(FALSE); 
      break;

#ifdef FF_DUAL_SIM
    case SIM_SELECT:

      if(sim_activate_req->sim_num < 0 OR sim_activate_req->sim_num > 2)
      {
        app_sim_card_error (SIM_CAUSE_PARAM_WRONG);
        break;
      }
 
      sim_data.SIM_Selection = TRUE;

      if(SIM_IS_FLAG_SET (SIM_INSERT))
      {
        SIM_PowerOff ();
        app_init_sim_data ();
        SIM_CLEAR_FLAG (SIM_INSERT);
      }
      retcode = SIM_SwitchDualSIM(sim_activate_req->sim_num);
    
      if(!retcode)
      {
        sim_data.sim_num = sim_activate_req->sim_num;

        TIMER_START (sim_handle, SIM_TIMER, T_DETECT_VALUE);

        retcode = SIM_Reset (&sim_info);
        TRACE_EVENT_P1 ("Result SIM Reset = %d", (int)retcode);

        switch (retcode)
        {
          case 0:
            /*
             * No problem
             */
            break;
          case 1:
          case 3:
          case 8:
          case 9:
            /*
             * No card inserted
             */
            TIMER_STOP (sim_handle, SIM_TIMER);

            app_sim_card_error (SIM_CAUSE_CARD_REMOVED);
            SIM_CLEAR_FLAG (SIM_INSERT);
            break;
          default:
            /*
             * other card problems
             */
            TIMER_STOP (sim_handle, SIM_TIMER);

            app_sim_card_error (CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS,
                                       SIM_ORIGINATING_ENTITY, retcode));
            SIM_CLEAR_FLAG (SIM_INSERT);
            break;
        }
      }
      else
      {
        app_sim_card_error (CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS,
                                         SIM_ORIGINATING_ENTITY, retcode));
      }
      sim_data.SIM_Selection = FALSE;
      break;
#endif /*FF_DUAL_SIM*/

    default:
      app_sim_card_error (SIM_CAUSE_PARAM_WRONG);  /* wrong parameter */

      SIM_EM_SIM_ACTIVATION_STARTED;

      break;
  }

  PFREE (sim_activate_req);

}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_check_service      |
+--------------------------------------------------------------------+

  PURPOSE : Checks a service status.

*/

GLOBAL UBYTE app_sim_check_service (UBYTE nr, UBYTE * serv_table)
{
  UBYTE value;

  TRACE_FUNCTION ("app_check_sim_service()");

  serv_table = serv_table + (nr-1)/4;
  value = * serv_table;

  value = value >> (((nr-1) & 3) * 2);
  value = value & 3;

  return value;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_fdn_bdn_procedures     |
+--------------------------------------------------------------------+

  PURPOSE : Processing of the FDN/BDN procedures according annex B
            of GSM 11.11.

*/

static const UBYTE op [9] =
{
    SIM_ADN_ENABLED,             /* no BDN, no FDN             */
    SIM_ADN_BDN_ENABLED,         /* BDN enabled, no FDN        */
    SIM_ADN_ENABLED,             /* BDN disabled, no FND       */
    SIM_FDN_ENABLED,             /* no BDN, FDN enabled        */
    SIM_FDN_BDN_ENABLED,         /* BDN enabled, FDN enabled   */
    SIM_FDN_ENABLED,             /* BDN disabled, FND enabled  */
    SIM_ADN_ENABLED,             /* no BDN, FDN disabled       */
    SIM_ADN_BDN_ENABLED,         /* BDN enabled, FDN disabled  */
    SIM_ADN_ENABLED              /* BDN disabled, FND disabled */
};

GLOBAL UBYTE app_fdn_bdn_procedures (T_SIM_MMI_INSERT_IND *sim_mmi_insert_ind)
{
  UBYTE bdn_capability;
  UBYTE fdn_capability;
  UBYTE check_imsi_loci;

  TRACE_FUNCTION ("app_fdn_bdn_procedures()");

  /*
   * IMSI and Location Information are
   * both not invalidated
   */
  check_imsi_loci = app_check_imsi_loci_validation ();

  if (!app_read_sim_service_table(sim_mmi_insert_ind))
    return SIM_NO_OPERATION;

  if (check_imsi_loci)
    return SIM_ADN_ENABLED;
  
  bdn_capability = app_bdn_capability_request ();
  fdn_capability = app_fdn_capability_request ();
  
  if (SIM_IS_FLAG_SET (CC_WITH_STK))
  {
    /*
     * ME supports Call control with SIM Toolkit
     */

    /*
     * if mobile has no BDN capability, but the SIM card
     */
    if (bdn_capability EQ BDN_ENABLED AND
        SIM_IS_FLAG_CLEARED (BDN_SUPPORT_BY_MMI))
       return SIM_NO_OPERATION;
    /*
     * if mobile has no FDN capability, but the SIM card
     */
    if (fdn_capability EQ FDN_ENABLED AND
        SIM_IS_FLAG_CLEARED (FDN_SUPPORT_BY_MMI))
      return SIM_NO_OPERATION;

    /*
     * Try rehabilitation of IMSI and Location Information
     */

    if (app_rehabilitate_imsi_loci ())
      return op [bdn_capability + 3 * fdn_capability];
    else
      return SIM_NO_OPERATION;
  }
  else
  {
    /*
     * ME doesn´t support Call control with SIM Toolkit
     */

    /*
     * if mobile has no FDN capability or FDN is not enabled on the SIM card
     */
    if (fdn_capability NEQ FDN_ENABLED OR
        SIM_IS_FLAG_CLEARED (FDN_SUPPORT_BY_MMI))
      return SIM_NO_OPERATION;

    /*
     * Try rehabilitation of IMSI and Location Information
     */
    if (app_rehabilitate_imsi_loci ())
      return SIM_FDN_ENABLED;
    else
      return SIM_NO_OPERATION;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                        |
| STATE   : code            ROUTINE : app_check_imsi_loci_validation |
+--------------------------------------------------------------------+

  PURPOSE : Checks the validation flag of IMSI and Location information.

*/

GLOBAL UBYTE app_check_imsi_loci_validation (void)
{
  UBYTE response[SIMDRV_MAX_RESULT];
  T_FIELD_STATUS field_status;

  TRACE_FUNCTION ("app_check_imsi_loci_validation()");

  
  /* Currently selected EF information is reset to force the selection */
  sim_data.act_field = NOT_PRESENT_16BIT;

  /*
   * check IMSI
   */
  if (FKT_Select (SIM_LOCI, FALSE, NULL,response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
    memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
  else
    return FALSE;

  /*
   * check invalidation flag
   */
  if ((field_status.file_status & 1) EQ 0)
    return FALSE;

  /*
   * check Location Information
   */
  if (FKT_Select (SIM_IMSI, FALSE, NULL,response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)
    memcpy(&field_status,response,SIM_MIN_EF_ST_LEN);
  else
    return FALSE;

  /*
   * check invalidation flag
   */
  if ((field_status.file_status & 1) EQ 0)
    return FALSE;

  /*
   * both fields are not invalidated
   */
  return TRUE;
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                        |
| STATE   : code            ROUTINE : app_bdn_capability_request     |
+--------------------------------------------------------------------+

  PURPOSE : Checks the BDN capability of the SIM card.

*/

GLOBAL UBYTE app_bdn_capability_request (void)
{
  T_FIELD_STATUS field_status;
  UBYTE response[SIMDRV_MAX_RESULT];

  TRACE_FUNCTION ("app_bdn_capability_request()");

  /*
   * check service in sim service table
   */
  if (SIM_IS_FLAG_CLEARED (SERVICE_31_SUPPORT))
    return NO_BDN_SIM;

  /*
   * Select BDN field and check invalidation flag
   */
  /* Currently selected EF information is reset to force the selection */
  sim_data.act_field = NOT_PRESENT_16BIT;

  if (FKT_Select (SIM_BDN, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)

    memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);

  else
    return NO_BDN_SIM;

  if ((field_status.file_status & 1) EQ 0)
    return BDN_DISABLED;
  else
    return BDN_ENABLED;
   
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                        |
| STATE   : code            ROUTINE : app_fdn_capability_request     |
+--------------------------------------------------------------------+

  PURPOSE : Checks the FDN capability of the SIM card.

*/

GLOBAL UBYTE app_fdn_capability_request (void)
{
  T_FIELD_STATUS field_status;
  UBYTE response[SIMDRV_MAX_RESULT];
  
  TRACE_FUNCTION ("app_fdn_capability_request()");

  /*
   * check service in sim service table
   */
  if (SIM_IS_FLAG_CLEARED (SERVICE_3_SUPPORT))
    return NO_FDN_SIM;

  /*
   * FDN is allocated and activated. Check against ADN.
   * Only ADN or FDN is possible.
   */
  if (SIM_IS_FLAG_CLEARED (SERVICE_2_SUPPORT))
    return FDN_ENABLED;

  /*
   * Select ADN field and check invalidation flag
   */
 /* Currently selected EF information is reset to force the selection */
  sim_data.act_field = NOT_PRESENT_16BIT;

  if (FKT_Select (SIM_ADN, FALSE, NULL, response, SIM_MIN_EF_ST_LEN) EQ SIM_NO_ERROR)

    memcpy(&field_status, response, SIM_MIN_EF_ST_LEN);

  else
    return FDN_ENABLED;

  if ((field_status.file_status & 1) EQ 0)
    return FDN_ENABLED;
  else
    return FDN_DISABLED;
}
  

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                        |
| STATE   : code            ROUTINE : app_rehabilitate_imsi_loci     |
+--------------------------------------------------------------------+

  PURPOSE : Tries to rehabilitate IMSI and location information.

*/

GLOBAL UBYTE app_rehabilitate_imsi_loci (void)
{
  USHORT error;
  TRACE_FUNCTION ("app_rehabilitate_imsi_loci()");

  /*
   * rehabilitate IMSI
   */
  error = FKT_Select (SIM_LOCI, FALSE, NULL, NULL, 0);
  if (error EQ SIM_NO_ERROR OR error EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)

  {
    if (FKT_Rehabilitate () NEQ SIM_NO_ERROR)
      return FALSE;
  }
  else
    return FALSE;

  /*
   * rehabilitate Location Information
   */
  if (FKT_Select (SIM_IMSI, FALSE, NULL, NULL, 0) EQ SIM_NO_ERROR)
  {
    if (FKT_Rehabilitate () NEQ SIM_NO_ERROR)
      return FALSE;
  }
  else
    return FALSE;

  return TRUE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                        |
| STATE   : code            ROUTINE : app_start_status_timer         |
+--------------------------------------------------------------------+

  PURPOSE : (Re-)Start the timer for periodical status requests to the
            SIM card. If parameter 'condx' is set TRUE, then the timer
            is (re-)started regardless of the SIM being a test SIM, or
            not. Also entry point for SIM toolkit commands.
*/

GLOBAL void app_start_status_timer (BOOL condx)
{
  T_TIME t_val;
  TRACE_FUNCTION ("app_start_status_timer()");
  /*
   * start status timer if call is active and SIM is inserted
   * for periodic status polling of SIM toolkit polling
   */
  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    if (SIM_IS_FLAG_SET (CALL_ACTIVE)
#if defined SIM_TOOLKIT
         OR (SIM_IS_FLAG_SET (PRO_ACTIVE_SIM) AND
         (SIM_IS_FLAG_CLEARED (TEST_MODE_POLLING) OR condx))
#endif
#ifdef TI_PS_FF_SIM_POLL_ALWAYS	 
         OR SIM_IS_FLAG_CLEARED (PRO_ACTIVE_SIM)
#endif	 
       )
    { /* when idle polling is enabled, use that timer value (as long as 
       * it's not more than 30s); else, we're only SIM presence 
       * detecting, during the call, with an interval of those 30s.
       * This will be disabled, at the end of the call, again.
       */
#if defined SIM_TOOLKIT
      if (sim_data.idle_polling)
      {
        t_val = (SIM_IS_FLAG_SET (CALL_ACTIVE) AND
               sim_data.status_time > THIRTY_SECONDS)?
              THIRTY_SECONDS: sim_data.status_time;
      }
      else
#endif
      {
        t_val = THIRTY_SECONDS;
      }
      /*
       * Start Status Polling during Call
       */
      TIMER_PSTART (sim_handle, SIM_TIMER, t_val, t_val);
    }
#if defined SIM_TOOLKIT
    sim_data.chk_sat_avail = TRUE;
    /* stk_proactive_polling();*/
#endif
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)   MODULE  : SIM_APP                        |
| STATE   : code            ROUTINE : app_check_access_conditions    |
+--------------------------------------------------------------------+

  PURPOSE : The function checks the access conditions. It sets the
            last requested pin number derived from the field status
            of the selected file. It returns whether access is
            possible or not.
*/

GLOBAL BOOL app_check_access_conditions (UBYTE proc, T_FIELD_STATUS *field_status)
{
  UBYTE  access;

  TRACE_FUNCTION ("app_check_access_conditions()");

  switch (proc)
  {
    case ACCESS_READ:
      access = field_status->access_1 >> 4;
      break;
    case ACCESS_UPDATE:
      access = field_status->access_1 & 0x0F;
      break;
    case ACCESS_INCREASE:
      access = field_status->access_2 >> 4;
      break;
    case ACCESS_REHABILITATE:
      access = field_status->access_3 >> 4;
      break;
    case ACCESS_INVALIDATE:
      access = field_status->access_3 & 0x0F;
      break;
    default:
      sim_data.last_requested_pin_no = LRP_NEVER;
      return FALSE;
  }

  switch (access)
  {
    case ALWAYS:
    case PIN_1:
    case PIN_2:
      sim_data.last_requested_pin_no = access;
      return TRUE;
    default:      /* ADM or NEVER */
      sim_data.last_requested_pin_no = LRP_NEVER;
      return FALSE;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6302)       MODULE  : SIM_APP                    |
| STATE   : code                ROUTINE : app_sim_access_req         |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_ACCESS_REQ.

*/

GLOBAL void app_sim_access_req (T_SIM_ACCESS_REQ * sim_access_req_org)
{
  USHORT result;
  USHORT offset;
  USHORT size = 0,length; 
  USHORT rcvLen = 0;

  #ifdef TI_PS_UICC_CHIPSET_15
  T_SIMDRV_cmd_header cmd_header;
  U8 reader_id = SIMDRV_VAL_READER_ID__RANGE_MIN;
  T_SIMDRV_data_info  data_info;
  T_SIMDRV_result_info    result_info;
  U8 offset_high;
  U8 offset_low;
  #endif

  static UBYTE get_resp[SIM_TPDU_HEADER_LEN] = {0x00, 0xC0, 0x00, 0x00, 0x00};
  T_SIM_ACCESS_CNF *sim_access_cnf;
  PPASS (sim_access_req_org, sim_access_req, SIM_ACCESS_REQ);

  sim_access_cnf = P_ALLOC (SIM_ACCESS_CNF);

  TRACE_FUNCTION ("app_sim_access_req()");

  /*
   * initialize answer
   */
  sim_access_cnf->req_id = sim_access_req->req_id;
  sim_access_cnf->c_trans_data = 0;
  sim_access_cnf->sw1 = sim_access_cnf->sw2 = 0;
  memset (sim_access_cnf->trans_data, 0, sizeof (sim_access_cnf->trans_data));
  sim_data.sw1 = sim_data.sw2 = 0; /* delete previous result code */

  if (SIM_IS_FLAG_SET (SIM_INSERT))
  {
    /*
     * if SIM is inserted, try to select the SIM card.
     */
    switch (sim_access_req->sim_command)
    {
    case SIM_GET_RESPONSE:
      sim_data.act_directory = NOT_PRESENT_16BIT;
      sim_data.act_field = NOT_PRESENT_16BIT;
    case SIM_READ_BINARY:
    case SIM_READ_RECORD:
    case SIM_UPDATE_BINARY:
    case SIM_UPDATE_RECORD:
      length = (sim_access_req->p3 > 0)?
      sim_access_req->p3: NOT_PRESENT_16BIT; 
      /* Access request coming from AT Command is only for standard files. Hence 
         path info can be set as NULL */
      sim_access_cnf->cause = FKT_Select (sim_access_req->datafield, FALSE, NULL,sim_access_cnf->trans_data, length);
      if(sim_access_cnf->cause EQ SIM_NO_ERR_FILE_ALREADY_SELECTED)
        sim_access_cnf->cause = SIM_NO_ERROR;
      sim_access_cnf->c_trans_data = (USHORT)sim_data.sim_data_len - SIM_TI_DRV_X_BYTES;
      sim_access_cnf->sw1 = (UBYTE)(sim_access_cnf->cause >> 8);
      sim_access_cnf->sw2 = (UBYTE)sim_access_cnf->cause;
      break;
    case SIM_TRANSP_CMD:
      if (sim_access_req->c_trans_data < 4 OR sim_access_req->c_trans_data > 261
#ifndef ALLOW_CSIM_GSM
           OR sim_access_req->trans_data[0] EQ GSM_CLASS
#endif
         )
      {
        sim_access_cnf->cause = SIM_CAUSE_PARAM_WRONG;
        break;
      }
      /* no break */
    case SIM_STATUS:
      sim_access_cnf->cause = SIM_NO_ERROR;
      break;
    default:
      sim_access_cnf->cause = SIM_CAUSE_PARAM_WRONG;
      break;
    }
    if (sim_access_cnf->cause EQ SIM_NO_ERROR)
    {
      /*
       * switch depending on SIM command
       */
      switch (sim_access_req->sim_command)
      {
      case SIM_READ_BINARY:
      /*
       * calculate offset from P1 and P2
       */
        offset = (sim_access_req->p1 << 8) + sim_access_req->p2;
      /*
       * call SIM driver
       */
       
       #ifndef TI_PS_UICC_CHIPSET_15
        result= SIM_ReadBinary (sim_access_cnf->trans_data,
                                offset,
                                (USHORT)sim_access_req->p3,
                                &size);
       #else /* !TI_PS_UICC_CHIPSET_15 */
        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 *)sim_access_cnf->trans_data;
        result_info.c_result = size;
        result_info.len  = (USHORT)sim_access_req->p3;
    
        result= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info);
        size = result_info.c_result; /* c_result will be updated by SIMDRV */
       #endif  /* !TI_PS_UICC_CHIPSET_15 */

      /*
       * fill response primitive
       */
        sim_access_cnf->c_trans_data = (USHORT)size - SIM_TI_DRV_X_BYTES;
        sim_access_cnf->sw1 = (UBYTE)(result >> 8);
        sim_access_cnf->sw2 = (UBYTE)result;
        break;

      case SIM_READ_RECORD:
      /*
       * call SIM driver
       */
       #ifndef TI_PS_UICC_CHIPSET_15
        result = SIM_ReadRecord (sim_access_cnf->trans_data,
                                 sim_access_req->p2,
                                 sim_access_req->p1,
                                 (USHORT)sim_access_req->p3,
                                 &size);
       #else /* !TI_PS_UICC_CHIPSET_15 */
        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)sim_access_req->p1;
        cmd_header.p2 = (U8)sim_access_req->p2;
        data_info.data   = NULL;
        data_info.c_data = 0;
        result_info.result   = (U8 *)sim_access_cnf->trans_data ;
        result_info.c_result = size;
        result_info.len  =(USHORT)sim_access_req->p3;
  
        result= simdrv_xch_apdu (reader_id,cmd_header,data_info, &result_info);
        size = result_info.c_result; /* c_result will be updated by SIMDRV */
      #endif  /* !TI_PS_UICC_CHIPSET_15 */
      /*
       * fill response primitive
       */
        sim_access_cnf->c_trans_data = (USHORT)size - SIM_TI_DRV_X_BYTES;
        sim_access_cnf->sw1 = (UBYTE)(result >> 8);
        sim_access_cnf->sw2 = (UBYTE)result;
        break;

       case SIM_GET_RESPONSE:
      /*
       * call SIM driver
       */
       #ifndef TI_PS_UICC_CHIPSET_15
        length = (sim_access_req->p3 > 0)?
                  sim_access_req->p3: sim_data.sim_data_len;
    
        result = SIM_GetResponse (sim_access_cnf->trans_data,
                                  length,
                                  &size);
        sim_access_cnf->c_trans_data = (USHORT)size - SIM_TI_DRV_X_BYTES;
        sim_access_cnf->sw1 = (UBYTE)(result >> 8);
        sim_access_cnf->sw2 = (UBYTE)result;
       #endif
        break; 

      case SIM_UPDATE_BINARY:
      /*
       * calculate offset from P1 and P2
       */
        offset = (sim_access_req->p1 << 8) + sim_access_req->p2;
      /*
       * call SIM driver
       */
       #ifndef TI_PS_UICC_CHIPSET_15
        result= SIM_UpdateBinary (sim_access_cnf->trans_data,
                                  sim_access_req->trans_data,
                                  offset,
                                  (USHORT)sim_access_req->p3,
                                  &size);
   
       #else /* !TI_PS_UICC_CHIPSET_15 */
        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 *)sim_access_req->trans_data;
        data_info.c_data = (U8)sim_access_req->p3;
        result_info.result = sim_access_cnf->trans_data;
        result_info.c_result = size;
        result_info.len  = NOT_PRESENT_16BIT;
   
        result= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info);
        size = result_info.c_result; /* c_result will be updated by SIMDRV */
       #endif  /* !TI_PS_UICC_CHIPSET_15 */
      /*
       * fill response primitive
       */
        sim_access_cnf->sw1 = (UBYTE)(result >> 8);
        sim_access_cnf->sw2 = (UBYTE)result;
        break;

      case SIM_UPDATE_RECORD:
      /*
       * call SIM driver
       */
       #ifndef TI_PS_UICC_CHIPSET_15
        result = SIM_UpdateRecord (sim_access_cnf->trans_data,
                                   sim_access_req->trans_data,
                                   sim_access_req->p2,
                                   sim_access_req->p1,
                                   (USHORT)sim_access_req->p3,
                                   &size);
  
       #else /* !TI_PS_UICC_CHIPSET_15 */
        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)sim_access_req->p1;
        cmd_header.p2 = (U8)sim_access_req->p2;
        data_info.data   = (U8*)sim_access_req->trans_data;
        data_info.c_data = (U8)sim_access_req->p3;
        result_info.result = sim_access_cnf->trans_data;
        result_info.c_result = size;
        result_info.len  = NOT_PRESENT_16BIT;
  
        result= simdrv_xch_apdu (reader_id,cmd_header,data_info,&result_info);
        size = result_info.c_result; /* c_result will be updated by SIMDRV */
       #endif  /* !TI_PS_UICC_CHIPSET_15 */
      /*
       * fill response primitive
       */
        sim_access_cnf->sw1 = (UBYTE)(result >> 8);
        sim_access_cnf->sw2 = (UBYTE)result;
        break;

      case SIM_STATUS:
      /*
       * call SIM driver
       */
        length = (sim_access_req->p3 > 0)?
                 (USHORT)sim_access_req->p3: sim_data.dir_status_len;
    
      #ifndef TI_PS_UICC_CHIPSET_15
        result = SIM_Status_Extended (sim_access_cnf->trans_data,
                                      length,
                                      &size);
      #else /* !TI_PS_UICC_CHIPSET_15 */
        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 *)sim_access_cnf->trans_data;
        result_info.len = length;
        result_info.c_result = size;

        result =  simdrv_xch_apdu(reader_id, cmd_header, data_info, &result_info);
        size = result_info.c_result; /* c_result will be updated by SIMDRV */
      #endif /* !TI_PS_UICC_CHIPSET_15 */

        sim_access_cnf->c_trans_data = (USHORT)size - SIM_TI_DRV_X_BYTES;
        sim_access_cnf->sw1 = (UBYTE)(result >> 8);
        sim_access_cnf->sw2 = (UBYTE)result;
        break;

      case SIM_TRANSP_CMD:
      /*
       * transparent SIM access
       */
       #ifdef  TI_PS_UICC_CHIPSET_15 
	  #ifdef  _SIMULATION_ 
             sim_command_type = SIM_TRANSP_CMD;
	  #endif
       #endif
        if (sim_access_req->c_trans_data EQ 4)
        {
          sim_access_req->trans_data[4] = '\0';
          sim_access_req->c_trans_data = 5;

          #ifndef TI_PS_UICC_CHIPSET_15
            result = SIM_XchTPDU (sim_access_req->trans_data,
                                sim_access_req->c_trans_data,
                                sim_access_cnf->trans_data,
                                0, &sim_access_cnf->c_trans_data);
         #else /* !TI_PS_UICC_CHIPSET_15 */
           cmd_header.cla = sim_access_req->trans_data[0];
           cmd_header.ins = sim_access_req->trans_data[1];
           cmd_header.p1 = sim_access_req->trans_data[2];
           cmd_header.p2 = sim_access_req->trans_data[3];

           data_info.data = &sim_access_req->trans_data[5];
           data_info.c_data = (U8)sim_access_req->c_trans_data;

           result_info.result = sim_access_cnf->trans_data;
           result_info.len = (USHORT)sim_access_req->trans_data[4];
           result_info.c_result = sim_access_cnf->c_trans_data;

           result = simdrv_xch_apdu (reader_id, cmd_header, data_info, &result_info);
           sim_access_cnf->c_trans_data = result_info.c_result;
         #endif   /* !TI_PS_UICC_CHIPSET_15 */

        }
        else if (sim_access_req->c_trans_data EQ 5)
        {
          rcvLen = (USHORT)sim_access_req->trans_data[4];
          if (rcvLen EQ 0)
            rcvLen = 256;
         #ifndef TI_PS_UICC_CHIPSET_15
          result = SIM_XchTPDU (sim_access_req->trans_data,
                                sim_access_req->c_trans_data,
                                sim_access_cnf->trans_data,
                                rcvLen, &sim_access_cnf->c_trans_data);
         #else  /* !TI_PS_UICC_CHIPSET_15 */
           cmd_header.cla = sim_access_req->trans_data[0];
           cmd_header.ins = sim_access_req->trans_data[1];
           cmd_header.p1 = sim_access_req->trans_data[2];
           cmd_header.p2 = sim_access_req->trans_data[3];

           data_info.data = &sim_access_req->trans_data[5];
           data_info.c_data = (U8)sim_access_req->c_trans_data;

           result_info.result = sim_access_cnf->trans_data;
           result_info.len = (USHORT)sim_access_req->trans_data[4];
           result_info.c_result = sim_access_cnf->c_trans_data;

           result = simdrv_xch_apdu (reader_id, cmd_header, data_info, &result_info);
           sim_access_cnf->c_trans_data = result_info.c_result;
         #endif  /* !TI_PS_UICC_CHIPSET_15 */
        }
        else
        {
          if (sim_access_req->c_trans_data EQ ((USHORT)sim_access_req->trans_data[4] + 6))
          {
            rcvLen = (USHORT)sim_access_req->trans_data[--sim_access_req->c_trans_data];
            if (rcvLen EQ 0)
              rcvLen = 256;
          }
          #ifndef TI_PS_UICC_CHIPSET_15
           result = SIM_XchTPDU (sim_access_req->trans_data,
                                sim_access_req->c_trans_data,
                                sim_access_cnf->trans_data,
                                0, &sim_access_cnf->c_trans_data);
          #else /* !TI_PS_UICC_CHIPSET_15 */
           cmd_header.cla = sim_access_req->trans_data[0];
           cmd_header.ins = sim_access_req->trans_data[1];
           cmd_header.p1 = sim_access_req->trans_data[2];
           cmd_header.p2 = sim_access_req->trans_data[3];

           data_info.data = &sim_access_req->trans_data[5];
           data_info.c_data = (U8)sim_access_req->c_trans_data;

           result_info.result = sim_access_cnf->trans_data;
           result_info.len = (USHORT)sim_access_req->trans_data[4];
           result_info.c_result = sim_access_cnf->c_trans_data;

           result = simdrv_xch_apdu (reader_id, cmd_header, data_info, &result_info);
           sim_access_cnf->c_trans_data = result_info.c_result;
          #endif /* !TI_PS_UICC_CHIPSET_15 */
          {
            USHORT sw1, sw2;

            sw1 = (result >> 8);
            sw2 = result & 0xFF;

            if (sw1 EQ 0x61)
            {
              if ((rcvLen <= 0) OR (sw2 < rcvLen))
                rcvLen = sw2;
            }
            else if (sw1 NEQ 0x90)
            {
              rcvLen = 0;
            }
            if (rcvLen > 0)
            {
              TRACE_EVENT_P2 ("SW1=%02X SW2=%02X", (int)sw1, (int)sw2);

              get_resp[0] = sim_access_req->trans_data[0];
              get_resp[4] = (UBYTE)rcvLen;

           #ifndef TI_PS_UICC_CHIPSET_15
              result = SIM_XchTPDU (get_resp, SIM_TPDU_HEADER_LEN,
                                    sim_access_cnf->trans_data,
                                    rcvLen,
                                    &sim_access_cnf->c_trans_data);
           #else /* !TI_PS_UICC_CHIPSET_15 */
             cmd_header.cla = get_resp[0];
             cmd_header.ins = get_resp[1];
             cmd_header.p1 = get_resp[2];
             cmd_header.p2 = get_resp[3];

             data_info.data = &get_resp[5];
             data_info.c_data = SIM_TPDU_HEADER_LEN;

             result_info.result = sim_access_cnf->trans_data;
             result_info.len = (USHORT)get_resp[4];
             result_info.c_result = sim_access_cnf->c_trans_data;

             result = simdrv_xch_apdu (reader_id, cmd_header, data_info, &result_info);
             sim_access_cnf->c_trans_data = result_info.c_result;
           #endif /* !TI_PS_UICC_CHIPSET_15 */

            }
          }
        }
        size = (sim_access_cnf->c_trans_data -= SIM_TI_DRV_X_BYTES);

        if ((result & 0xF000) EQ 0x6000 OR
            (result & 0xF000) EQ 0x9000)
        {
          sim_access_cnf->sw1 = (UBYTE)(result >> 8);
          sim_access_cnf->sw2 = (UBYTE)result;
        }
        else if ((result & 0xFF00) EQ 0)
        {
          sim_access_cnf->cause = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS,
                                             SIM_ORIGINATING_ENTITY, result);
        }
        else
        {
          sim_access_cnf->cause = SIM_CAUSE_OTHER_ERROR;
        }
        break;

      default:
        sim_access_cnf->cause = SIM_CAUSE_PARAM_WRONG;
        break;
      }
      TRACE_EVENT_P3 ("SW1=%02X SW2=%02X SIZE=%d", sim_access_cnf->sw1,
                      sim_access_cnf->sw2, (int)size);
      /*
       * start status timer again
       */
      app_start_status_timer (FALSE);
    }
    else
    {
      sim_access_cnf->sw1 = sim_data.sw1;
      sim_access_cnf->sw2 = sim_data.sw2;
    }
  }
  else
  /*
   * sim is not inserted
   */
    sim_access_cnf->cause = SIM_CAUSE_CARD_REMOVED;

  /*
   * free incoming primitive
   */
  PFREE (sim_access_req);

  /*
   * send result to MMI
   */
  PSENDX (MMI, sim_access_cnf);
}


#endif