view src/aci2/aci/cmh_simq.c @ 662:8cd8fd15a095

SIM speed enhancement re-enabled and made configurable TI's original code supported SIM speed enhancement, but Openmoko had it disabled, and OM's disabling of speed enhancement somehow caused certain SIM cards to start working which didn't work before (OM's bug #666). Because our FC community is much smaller in year 2020 than OM's community was in their day, we are not able to find one of those #666-affected SIMs, thus the real issue they had encountered remains elusive. Thus our solution is to re-enable SIM speed enhancement and simply wait for if and when someone runs into a #666-affected SIM once again. We provide a SIM_allow_speed_enhancement global variable that allows SIM speed enhancement to be enabled or disabled per session, and an /etc/SIM_spenh file in FFS that allows it to enabled or disabled on a non-volatile basis. SIM speed enhancement is now enabled by default.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 May 2020 05:02:28 +0000
parents 93999a60b835
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  GSM-PS (6147)
|  Modul   :  CMH_SIMQ
+----------------------------------------------------------------------------- 
|  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 module provides the query functions related to the 
|             protocol stack adapter for subscriber identity module.
+----------------------------------------------------------------------------- 
*/ 

#ifndef CMH_SIMQ_C
#define CMH_SIMQ_C
#endif

#include "aci_all.h"

#include "aci_cmh.h"

#ifdef FAX_AND_DATA
#include "aci_fd.h"
#endif    /* of #ifdef FAX_AND_DATA */

#ifdef UART
#include "dti.h"
#include "dti_conn_mng.h"
#endif

#include "psa.h"
#include "psa_sim.h"
#include "cmh.h"
#include "cmh_sim.h"
#include "cmh_sms.h"

/* To include AciSLockShrd */
#include "aci_ext_pers.h"
#include "aci_slock.h"


#include "aoc.h"

/*==== CONSTANTS ==================================================*/

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

/*==== VARIABLES ==================================================*/

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


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
| STATE   : code                  ROUTINE : qAT_PercentSECS             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %SECS? AT command
            which is responsible to query the status of the Security Code.

*/
                             

GLOBAL T_ACI_RETURN qAT_PercentSECS ( T_ACI_CMD_SRC srcId,T_ACI_SECS_STA *status)
{
    T_SIMLOCK_STATUS result = SIMLOCK_FAIL;

    TRACE_FUNCTION ("qAT_PercentSECS()");

    result = aci_ext_personalisation_CS_get_status();

    switch (result)
    {
      case SIMLOCK_ENABLED:
        *status = SECS_STA_Enable;
        return AT_CMPL;
      case SIMLOCK_DISABLED:
       *status = SECS_STA_Disable;
        return AT_CMPL;
      default:
       *status = SECS_STA_NotPresent;
        return AT_FAIL;
    }
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCFUN             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CFUN? AT command
            which returns the current setting for phone functionality.

            <fun>:   phone functionality.
*/

GLOBAL T_ACI_RETURN qAT_PlusCFUN  ( T_ACI_CMD_SRC  srcId,
                                    T_ACI_CFUN_FUN *fun )
{
  TRACE_FUNCTION ("qAT_PlusCFUN()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * fill in parameters
 *-------------------------------------------------------------------
 */  
  *fun = CFUNfun;

  return( AT_CMPL );
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCPIN             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CPIN? AT command
            which returns the current PIN status.

            <code>:   PIN status.
*/

GLOBAL T_ACI_RETURN qAT_PlusCPIN   (T_ACI_CMD_SRC srcId, 
                                    T_ACI_CPIN_RSLT *code)
{
  T_SIM_SET_PRM * pSIMSetPrm; /* points to SIM parameter set */

  TRACE_FUNCTION ("qAT_PlusCPIN()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pSIMSetPrm = &simShrdPrm.setPrm[srcId];

/*
 *-------------------------------------------------------------------
 * check SIM status
 *-------------------------------------------------------------------
 */
  if( simShrdPrm.SIMStat NEQ SS_OK AND
      simShrdPrm.SIMStat NEQ SS_BLKD   )
  {
    pSIMSetPrm -> actProc = SIM_INITIALISATION;

    simEntStat.curCmd = AT_CMD_CPIN;
    simEntStat.entOwn = simShrdPrm.owner = srcId;
    simShrdPrm.PINQuery = 1;

    if( psaSIM_ActivateSIM() < 0 )   /* activate SIM card */
    {
      TRACE_EVENT( "FATAL RETURN psaSIM in +CPIN" );
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
      simShrdPrm.PINQuery = 0;
      return( AT_FAIL );
    }
    return( AT_EXCT );
  }

#ifdef SIM_PERS
/*
 *-------------------------------------------------------------------
 * check PIN status
 *-------------------------------------------------------------------
 */
  /* OVK Check first if any Personalisations are active */
    if ( AciSLockShrd.blocked EQ TRUE)
  {
    TRACE_EVENT_P3("qAT_PlusCPIN: Curr Lock = %d, Status = %d %s", AciSLockShrd.current_lock, AciSLockShrd.status[AciSLockShrd.current_lock],"" );
      
    switch (AciSLockShrd.current_lock)
    {
      case SIMLOCK_NETWORK:
        if (AciSLockShrd.status[AciSLockShrd.current_lock] EQ SIMLOCK_BLOCKED)
          *code = CPIN_RSLT_PhNetPukReq;
        else
          *code = CPIN_RSLT_PhNetPinReq;
        break;
      case SIMLOCK_NETWORK_SUBSET:
        if (AciSLockShrd.status[AciSLockShrd.current_lock] EQ SIMLOCK_BLOCKED)
          *code = CPIN_RSLT_PhNetSubPukReq;
        else
          *code = CPIN_RSLT_PhNetSubPinReq;
        break;
      case SIMLOCK_SERVICE_PROVIDER:
        if (AciSLockShrd.status[AciSLockShrd.current_lock] EQ SIMLOCK_BLOCKED)
          *code = CPIN_RSLT_PhSPPukReq;
        else
          *code = CPIN_RSLT_PhSPPinReq;
        break;
      case SIMLOCK_CORPORATE:
        if (AciSLockShrd.status[AciSLockShrd.current_lock] EQ SIMLOCK_BLOCKED)
          *code = CPIN_RSLT_PhCorpPukReq;
        else
          *code = CPIN_RSLT_PhCorpPinReq;
        break;
      case SIMLOCK_SIM:
        
          *code = CPIN_RSLT_PhSimPinReq;
          break;
      case SIMLOCK_FIRST_SIM:
        if (AciSLockShrd.status[AciSLockShrd.current_lock] EQ SIMLOCK_BLOCKED)
          *code = CPIN_RSLT_PhFSimPukReq;
        else
          *code = CPIN_RSLT_PhFSimPinReq;
        break;
      default:
        *code = CPIN_RSLT_NotPresent;
        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
        return( AT_FAIL );
    }
  }
  else
#endif
  {
    switch( simShrdPrm.PINStat )
    {
      case( PS_RDY ):

        *code = CPIN_RSLT_SimReady;
        break;

      case( PS_PIN1 ):

        *code = CPIN_RSLT_SimPinReq;
        break;

      case( PS_PUK1 ):

        *code = CPIN_RSLT_SimPukReq;
        break;

      case( PS_PIN2 ):

        *code = CPIN_RSLT_SimPin2Req;
        break;

      case( PS_PUK2 ):

        *code = CPIN_RSLT_SimPuk2Req;
        break;

      default:

        TRACE_EVENT("UNEXPECTED PIN STATUS");
        *code = CPIN_RSLT_NotPresent;
        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
        return( AT_FAIL );
    }


  }

  return( AT_CMPL );
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCAOC             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CAOC AT command
            which is responsible to query the current call meter value.
            
            <ccm>   : CCM value.
*/

GLOBAL T_ACI_RETURN qAT_PlusCAOC  ( T_ACI_CMD_SRC srcId,
                                    LONG * ccm)
{
  TRACE_FUNCTION ("qAT_PlusCAOC ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_CCM, (void *)ccm);
  
  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCACM             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CACM AT command
            which is responsible to query the accumulated call meter value.
            
            <acm>   : ACM value.
*/

GLOBAL T_ACI_RETURN qAT_PlusCACM  ( T_ACI_CMD_SRC srcId,
                                    LONG * acm)
{
  TRACE_FUNCTION ("qAT_PlusCACM ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_ACM, (ULONG *)acm);
  
  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCAMM             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CAMM AT command
            which is responsible to query the maximum of the 
            accumulated call meter value.
            
            <acmmax>   : ACMMax value.
*/

GLOBAL T_ACI_RETURN qAT_PlusCAMM  ( T_ACI_CMD_SRC srcId,
                                    LONG * acmmax)
{
  TRACE_FUNCTION ("qAT_PlusCAMM ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_ACMMAX, (ULONG *)acmmax);
  
  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCPUC             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CPUC AT command
            which is responsible to query the price per unit and 
            currency.
            
            <cuurency>   : Currency
            <ppu>        : Price per Unit
*/

GLOBAL T_ACI_RETURN qAT_PlusCPUC  ( T_ACI_CMD_SRC srcId,
                                    CHAR          *currency,
                                    CHAR          *ppu)
{
  T_puct puct;

  TRACE_FUNCTION ("qAT_PlusCPUC ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_PUCT, (void *)&puct);
  
  strcpy ((char *) currency, (char *) puct.currency);
  strcpy ((char *) ppu, (char *) puct.value);

  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
| STATE   : code                  ROUTINE : sAT_PlusCIMI             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CIMI AT command
            which is responsible to request the IMSI.

*/

GLOBAL T_ACI_RETURN qAT_PlusCIMI ( T_ACI_CMD_SRC  srcId,
                                   CHAR * imsi )
{
  T_SIM_SET_PRM * pSIMSetPrm; /* points to SIM parameter set */

  TRACE_FUNCTION ("qAT_PlusCIMI()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pSIMSetPrm = &simShrdPrm.setPrm[srcId];

/*
 *-------------------------------------------------------------------
 * check entity status
 *-------------------------------------------------------------------
 */  
  switch( simShrdPrm.SIMStat )
  {
    case( SS_OK ):
    /*
     *-----------------------------------------------------------------
     * check if command executable
     *-----------------------------------------------------------------
     */
    if((simShrdPrm.PINStat NEQ PS_RDY) AND (!cmhSMS_checkSIM ()))
    {
      return AT_FAIL;
    }

    /*
     * Check required for CIMI after SIM_REMOVE_IND and SIM_ACTIVATE_IND
     * with SIMStat as SS_OK and PINStat as PS_RDY
     * but before receiving SIM_MMI_INSERT_IND
     */
    else if(simShrdPrm.imsi.c_field EQ 0)
    {
      ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_Unknown);
      return AT_FAIL; 
    }
    else
    {
      psaSIM_cnvrtIMSI2ASCII( imsi );
      return( AT_CMPL );
    }

    case( NO_VLD_SS ):

      if( simEntStat.curCmd NEQ AT_CMD_NONE ) return( AT_BUSY );

      pSIMSetPrm -> actProc = SIM_INITIALISATION;

      simEntStat.curCmd = AT_CMD_CIMI;
      simEntStat.entOwn = simShrdPrm.owner = srcId;

      if( psaSIM_ActivateSIM() < 0 )   /* activate SIM card */
      {
        simEntStat.curCmd = AT_CMD_NONE;
        TRACE_EVENT( "FATAL RETURN psaSIM in +CIMI" );
        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_Unknown);
        return( AT_FAIL );
      }

      return( AT_EXCT );

    default:                     /* SIM failure */
      ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimFail );
      return( AT_FAIL );
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PercentCACM          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %CACM AT command
            which is responsible to query the accumulated call meter value
            using PUCT.
            
            <cur>   : currency.
            <val>   : ACM value.
*/

GLOBAL T_ACI_RETURN qAT_PercentCACM( T_ACI_CMD_SRC    srcId,
                                     CHAR            *cur,
                                     CHAR            *val)
{
  T_puct puct;

  TRACE_FUNCTION ("qAT_PercentCACM ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_ACM_PUCT, (T_puct *)&puct);
  
  strcpy (cur, (char *) puct.currency);
  strcpy (val, (char *) puct.value);

  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PercentCAOC          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %CAOC AT command
            which is responsible to query the current call meter value
            using PUCT.
            
            <cur>   : currency.
            <val>   : CCM value.
*/

GLOBAL T_ACI_RETURN qAT_PercentCAOC( T_ACI_CMD_SRC    srcId,
                                     CHAR            *cur,
                                     CHAR            *val)
{
  T_puct puct;

  TRACE_FUNCTION ("qAT_PercentCAOC ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_CCM_PUCT, (T_puct *)&puct);
  
  strcpy (cur, (char *) puct.currency);
  strcpy (val, (char *) puct.value);

  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PercentCTV           |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %CTV AT command
            which is responsible to query the current call timer value.
            
            <ctv>   : CTV value.
*/

GLOBAL T_ACI_RETURN qAT_PercentCTV  ( T_ACI_CMD_SRC srcId,
                                      LONG * ctv)
{
  TRACE_FUNCTION ("qAT_PercentCTV ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_CTV, (void *)ctv);
  
  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PercentRPCT          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %RPCT AT command
            which is responsible to query the raw SIM data for PUCT.
            
            <rpuct>   : PUCT values.
*/

GLOBAL T_ACI_RETURN qAT_PercentRPCT( T_ACI_CMD_SRC    srcId,
                                     T_ACI_RPCT_VAL  *rpuct)
{
  T_puct_raw raw_puct;

  TRACE_FUNCTION ("qAT_PercentRPCT ()");

/*
 *-------------------------------------------------------------------
 * request value from advice of charge module.
 *-------------------------------------------------------------------
 */  
  aoc_get_values (AOC_PUCT_RAW, (T_puct_raw *)&raw_puct);
  
  memcpy(rpuct->currency, raw_puct.currency, MAX_CUR_LEN);
  rpuct->eppu = raw_puct.eppu;
  rpuct->exp  = raw_puct.exp;
  rpuct->sexp = raw_puct.sexp;

  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PercentPVRF          |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %PVRF AT command
            which is responsible to query the current counter for
            PIN and PUK.
            
            <pn1Cnt>   : PIN 1 counter.
            <pn2Cnt>   : PIN 2 counter.
            <pk1Cnt>   : PUK 1 counter.
            <pk2Cnt>   : PUK 2 counter.
            <ps1>      : PIN 1 status.
            <ps2>      : PIN 2 status.
*/

GLOBAL T_ACI_RETURN qAT_PercentPVRF( T_ACI_CMD_SRC srcId, 
                                     SHORT        *pn1Cnt,
                                     SHORT        *pn2Cnt,
                                     SHORT        *pk1Cnt,
                                     SHORT        *pk2Cnt,
                                     T_ACI_PVRF_STAT *ps1,
                                     T_ACI_PVRF_STAT *ps2 )
{
  TRACE_FUNCTION ("qAT_PercentPVRF ()");

/*
 *-------------------------------------------------------------------
 * read PIN/PUK counter values
 *-------------------------------------------------------------------
 */  
  if( simShrdPrm.SIMStat NEQ SS_OK AND
      simShrdPrm.SIMStat NEQ SS_BLKD   )
  {
    *pn1Cnt = ACI_NumParmNotPresent;
    *pn2Cnt = ACI_NumParmNotPresent;
    *pk1Cnt = ACI_NumParmNotPresent;
    *pk2Cnt = ACI_NumParmNotPresent;
    *ps1    = PVRF_STAT_NotPresent;
    *ps2    = PVRF_STAT_NotPresent;
  }
  else
  {
    *pn1Cnt = simShrdPrm.pn1Cnt;
    *pn2Cnt = simShrdPrm.pn2Cnt;
    *pk1Cnt = simShrdPrm.pk1Cnt;
    *pk2Cnt = simShrdPrm.pk2Cnt;

    switch( simShrdPrm.pn1Stat )
    {
      case( PS_RDY  ): *ps1 = PVRF_STAT_NotRequired; break;
      case( PS_PIN1 ): *ps1 = PVRF_STAT_Required;    break;
      default:         *ps1 = PVRF_STAT_NotPresent;
    }

    switch( simShrdPrm.pn2Stat )
    {
      case( PS_RDY  ): *ps2 = PVRF_STAT_NotRequired; break;
      case( PS_PIN2 ): *ps2 = PVRF_STAT_Required;    break;
      default:         *ps2 = PVRF_STAT_NotPresent;
    }
  }

  return( AT_CMPL );        
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
| STATE   : code                  ROUTINE : qAT_PlusCNUM             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CNUM AT command
            which is responsible for reading the  subscriber number.

            <mode>:   indicates whether reading starts or continues
*/
GLOBAL T_ACI_RETURN qAT_PlusCNUM ( T_ACI_CMD_SRC  srcId,
                                   T_ACI_CNUM_MOD mode )
{
  T_SIM_CMD_PRM * pSIMCmdPrm; /* points to SIM command parameters */

  UBYTE i;                    /* used for counting                */

  TRACE_FUNCTION ("qAT_PlusCNUM()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pSIMCmdPrm = &cmhPrm[srcId].simCmdPrm;

/*
 *-------------------------------------------------------------------
 * check entity status
 *-------------------------------------------------------------------
 */  
  if( simEntStat.curCmd NEQ AT_CMD_NONE )

    return( AT_BUSY );

/*
 *-------------------------------------------------------------------
 * check whether there are more EF to read
 *-------------------------------------------------------------------
 */  
  if ( mode                     EQ CNUM_MOD_NextRead AND
       pSIMCmdPrm -> CNUMActRec EQ CNUMMaxRec            )
  {
    return ( AT_CMPL );
  }

/*
 *-------------------------------------------------------------------
 * process parameter <mode>
 *-------------------------------------------------------------------
 */  
  switch ( mode )
  {
    case ( CNUM_MOD_NewRead  ): 
      pSIMCmdPrm -> CNUMActRec = 1;
      pSIMCmdPrm -> CNUMOutput = 0;
      break;

    case ( CNUM_MOD_NextRead ): 
      pSIMCmdPrm -> CNUMActRec++;
      break;

    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * reset to start of MSISDN list
 *-------------------------------------------------------------------
 */  
  CNUMMsisdnIdx = 0;

/*
 *-------------------------------------------------------------------
 * invalidate contents of MSISDN list
 *-------------------------------------------------------------------
 */  
  for ( i = 0; i < MAX_MSISDN; i++ )
    
    CNUMMsisdn[i].vldFlag = FALSE;

/*
 *-------------------------------------------------------------------
 * request EF MSISDN from SIM
 *-------------------------------------------------------------------
 */  
  return cmhSIM_ReqMsisdn ( srcId, pSIMCmdPrm -> CNUMActRec );
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMS           |
| STATE   : code                        ROUTINE : cmhSIM_ReqMsisdn   |
+--------------------------------------------------------------------+

  PURPOSE : This function starts reading of EF MSISDN from SIM.
*/

GLOBAL T_ACI_RETURN cmhSIM_ReqMsisdn ( T_ACI_CMD_SRC srcId,
                                       UBYTE         record )
{
  UBYTE length;

  TRACE_FUNCTION ("cmhSIM_ReqMsisdn()");

  if (record EQ 1)
    length = NOT_PRESENT_8BIT;
  else
    length = CNUMLenEfMsisdn;

  return cmhSIM_ReadRecordEF (srcId, AT_CMD_CNUM, SIM_MSISDN,
                              record, length, NULL, cmhSIM_CnfMsisdn);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : CMH_SIMS           |
| STATE   : code                        ROUTINE : cmhSIM_ReqCcp      |
+--------------------------------------------------------------------+

  PURPOSE : This function starts reading of EF CCP from SIM.
*/

GLOBAL T_ACI_RETURN cmhSIM_ReqCcp ( T_ACI_CMD_SRC srcId, 
                                    UBYTE         record )
{
  TRACE_FUNCTION ("cmhSIM_ReqCcp()");

  return cmhSIM_ReadRecordEF (srcId, AT_CMD_CNUM, SIM_CCP, record,
                              ACI_SIZE_EF_CCP, NULL, cmhSIM_CnfCcp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : qAT_PlusCPOL             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CPOL AT command
            which is responsible for reading the preferred operator
            list.
            
            <startIdx>: start index to read from
            <lastIdx>:  buffer for last index read
            <operLst>:  buffer for operator list
            <mode>:     supplemental read mode
*/

GLOBAL T_ACI_RETURN qAT_PlusCPOL  ( T_ACI_CMD_SRC srcId,
                                    SHORT              startIdx,
                                    SHORT             *lastIdx,
                                    T_ACI_CPOL_OPDESC *operLst,
                                    T_ACI_CPOL_MOD     mode )

{
  T_SIM_CMD_PRM * pSIMCmdPrm; /* points to SIM command parameters */

  TRACE_FUNCTION ("qAT_PlusCPOL()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pSIMCmdPrm = &cmhPrm[srcId].simCmdPrm;

/*
 *-------------------------------------------------------------------
 * check <mode> parameter
 *-------------------------------------------------------------------
 */  
  switch( mode )
  {
    case( CPOL_MOD_NotPresent ):
    case( CPOL_MOD_CompactList ):

      break;

    case( CPOL_MOD_Insert ):
    default:
      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
      return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * check if PLMNsel EF has to be read
 *-------------------------------------------------------------------
 */  
  if( startIdx EQ 0 OR EfPLMNselStat EQ EF_STAT_UNKNWN )
  {
    /*
     *-------------------------------------------------------------
     * check entity status
     *-------------------------------------------------------------
     */  
    if( simEntStat.curCmd NEQ AT_CMD_NONE )

      return( AT_BUSY );

    pSIMCmdPrm -> CPOLidx  = (startIdx EQ 0)?1:startIdx;
    pSIMCmdPrm -> CPOLmode = mode;
    pSIMCmdPrm -> CPOLact  = CPOL_ACT_Read;

    /*
     *-------------------------------------------------------------
     * request EF PLMN SEL from SIM
     *-------------------------------------------------------------
     */  
    return cmhSIM_ReqPlmnSel ( srcId );
  }

  /*
   *-------------------------------------------------------------
   * fill PLMN SEL list
   *-------------------------------------------------------------
   */
  if( startIdx * ACI_LEN_PLMN_SEL_NTRY > CPOLSimEfDataLen )
  {
    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx );
    return( AT_FAIL );
  }

  if( mode EQ CPOL_MOD_CompactList ) 
  {  
    cmhSIM_CmpctPlmnSel( CPOLSimEfDataLen, CPOLSimEfData );
  }

  *lastIdx = cmhSIM_FillPlmnSelList((UBYTE)startIdx,
                                    pSIMCmdPrm->CPOLfrmt,
                                    operLst,
                                    CPOLSimEfDataLen,
                                    CPOLSimEfData);
  return ( AT_CMPL );

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SSQ                  |
| STATE   : code                  ROUTINE : tAT_PlusCPOL             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the +CPOL AT command
            which is responsible for testing the supported preferred 
            operator list length.
            
            <lastIdx>:   maximum number of entries
            <usdNtry>:   number of used entries
*/

GLOBAL T_ACI_RETURN tAT_PlusCPOL  ( T_ACI_CMD_SRC srcId,
                                    SHORT * lastIdx,
                                    SHORT * usdNtry      )
{
  T_SIM_CMD_PRM * pSIMCmdPrm; /* points to SIM command parameters */

  TRACE_FUNCTION ("tAT_PlusCPOL()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  pSIMCmdPrm = &cmhPrm[srcId].simCmdPrm;

/*
 *-------------------------------------------------------------------
 * check if PLMNsel EF has to be read
 *-------------------------------------------------------------------
 */  
  if( EfPLMNselStat EQ EF_STAT_UNKNWN )
  {
    /*
     *-------------------------------------------------------------
     * check entity status
     *-------------------------------------------------------------
     */  
    if( simEntStat.curCmd NEQ AT_CMD_NONE )

      return( AT_BUSY );

    pSIMCmdPrm -> CPOLact = CPOL_ACT_Test;

    /*
     *-------------------------------------------------------------
     * request EF PLMN SEL from SIM
     *-------------------------------------------------------------
     */  
    return cmhSIM_ReqPlmnSel ( srcId );
  }

  /*
   *-------------------------------------------------------------
   * return number of supported entries
   *-------------------------------------------------------------
   */
  *lastIdx = CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY;

  *usdNtry = cmhSIM_UsdPlmnSelNtry( CPOLSimEfDataLen, CPOLSimEfData );

  return ( AT_CMPL );

}


/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMQ                |
|                                 ROUTINE : qAT_PercentCPRI         |
+-------------------------------------------------------------------+

 PURPOSE : This is the functional counterpart to the %CPRI AT command
           which is responsible for reading the ciphering indicator 
           mode.
*/
GLOBAL T_ACI_RETURN qAT_PercentCPRI( T_ACI_CMD_SRC srcId,
                                     UBYTE *mode  )
{
  TRACE_FUNCTION ("qAT_PercentCPRI()");

  if( !cmh_IsVldCmdSrc( srcId ) ) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }
  *mode = simShrdPrm.ciSIMEnabled;
  return( AT_CMPL );
}


/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMQ                |
|                                 ROUTINE : qAT_PercentATR          |
+-------------------------------------------------------------------+

 PURPOSE : This is the functional counterpart to the %ATR AT command
           which is responsible for reading the SIM phase and ATR 
           (answer to reset information).
*/
GLOBAL T_ACI_RETURN qAT_PercentATR( T_ACI_CMD_SRC  srcId,
                                     UBYTE        *phase,
                                     UBYTE        *atr_len,
                                     UBYTE        *atr_info)
{
  TRACE_FUNCTION ("qAT_PercentATR()");

  if( !cmh_IsVldCmdSrc( srcId ) ) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

  *phase = simShrdPrm.crdPhs; /* SIM Phase... value is 0xFF if no phase is available*/
  

  *atr_len = simShrdPrm.atr.len; /* ATR length... 0 if no ATR data is available*/
  if (simShrdPrm.atr.len)
  {
    memcpy(atr_info, simShrdPrm.atr.data, simShrdPrm.atr.len);
  }
  
  return( AT_CMPL );
}

#ifdef FF_DUAL_SIM
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMQ                  |
| STATE   : code                  ROUTINE : qAT_PercentSIM             |
+--------------------------------------------------------------------+

  PURPOSE : This is the functional counterpart to the %SIM? AT command
            which returns the currently powered on SIM Number.

            <sim_num>:   sim_number.
*/

GLOBAL T_ACI_RETURN qAT_PercentSIM  ( T_ACI_CMD_SRC  srcId,
                                    UBYTE *sim_num )
{
  TRACE_FUNCTION ("qAT_PercentSIM()");

/*
 *-------------------------------------------------------------------
 * check command source
 *-------------------------------------------------------------------
 */  
  if(!cmh_IsVldCmdSrc (srcId)) 
  { 
    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
    return( AT_FAIL );
  }

/*
 *-------------------------------------------------------------------
 * fill in parameters
 *-------------------------------------------------------------------
 */  
  *sim_num = simShrdPrm.SIM_Powered_on;

  return( AT_CMPL );
}
#endif /*FF_DUAL_SIM*/
/*==== EOF ========================================================*/