diff g23m/condat/ms/src/aci/cmh_sims.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m/condat/ms/src/aci/cmh_sims.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,1660 @@
+/*
++-----------------------------------------------------------------------------
+|  Project :  GSM-PS (6147)
+|  Modul   :  CMH_SIMS
++-----------------------------------------------------------------------------
+|  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 set functions related to the
+|             protocol stack adapter for the subscriber identity
+|             module.
++-----------------------------------------------------------------------------
+*/
+
+#ifndef CMH_SIMS_C
+#define CMH_SIMS_C
+#endif
+
+#include "aci_all.h"
+/*==== INCLUDES ===================================================*/
+#include "aci_cmh.h"
+
+#ifdef UART
+#include "dti.h"      /* functionality of the dti library */
+#include "dti.h"
+#include "dti_conn_mng.h"
+#endif
+
+#include "ati_cmd.h"
+
+#ifdef FF_ATI
+#include "aci_io.h"
+#endif /* of #ifdef FF_ATI */
+
+#ifdef FAX_AND_DATA
+#include "aci_fd.h"
+#endif    /* of #ifdef FAX_AND_DATA */
+
+#include "psa.h"
+#include "psa_sim.h"
+#include "psa_mm.h"
+#include "cmh.h"
+#include "cmh_sim.h"
+#include "cmh_mm.h"
+
+#ifdef GPRS
+  #include "dti_cntrl_mng.h"
+  #include "gaci.h"
+  #include "gaci_cmh.h"
+  #include "psa_gmm.h"
+  #include "cmh_gmm.h"
+#endif
+
+/* #include "m_fac.h" */
+#include "aoc.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+#include "phb.h"
+
+#include "aci_ext_pers.h"
+#include "aci_slock.h"
+
+#include "cl_imei.h"
+
+
+#ifdef SIM_PERS
+#include "general.h" // included for compilation error UNIT8 in sec_drv.h
+#include "sec_drv.h" 
+#include "cmh.h"
+#include "aci_cmh.h"
+
+EXTERN T_SIM_MMI_INSERT_IND *last_sim_mmi_insert_ind;
+EXTERN T_SEC_DRV_CATEGORY *personalisation_nw;
+EXTERN T_SEC_DRV_CATEGORY *personalisation_ns;
+EXTERN T_SEC_DRV_CATEGORY *personalisation_sp;
+EXTERN T_SEC_DRV_CATEGORY *personalisation_cp;
+EXTERN T_SEC_DRV_CATEGORY *personalisation_sim;
+EXTERN T_SEC_DRV_CONFIGURATION *cfg_data ;
+#endif
+
+/*==== CONSTANTS ==================================================*/
+
+/*==== EXPORT =====================================================*/
+
+/*==== VARIABLES ==================================================*/
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCFUN             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CFUN AT command
+            which is responsible to set the phone functionality.
+
+            <fun>:    defines the level of functionality to switch to.
+            <rst>:    reset mode
+*/
+
+GLOBAL T_ACI_RETURN sAT_PlusCFUN ( T_ACI_CMD_SRC  srcId,
+                                   T_ACI_CFUN_FUN fun,
+                                   T_ACI_CFUN_RST rst )
+{
+  T_SIM_SET_PRM * pSIMSetPrm; /* points to MM parameter set */
+  T_ACI_RETURN    retCd;      /* holds return code */
+  UBYTE           idx;        /* holds index value */
+
+  /* variables for IMEI control mechanism */
+#ifndef _SIMULATION_
+  BYTE         retVal;                     /* holds return value */
+  UBYTE        dummyIMEIBuf[CL_IMEI_SIZE]; /* dummy IMEI buffer */
+#endif /* if NOT defined windows simulation */
+
+  TRACE_FUNCTION ("sAT_PlusCFUN()");
+
+#ifndef _SIMULATION_
+/*
+ *-------------------------------------------------------------------
+ * check IMEI
+ *-------------------------------------------------------------------
+ */
+
+ retVal = cl_get_imeisv(CL_IMEI_SIZE, dummyIMEIBuf, CL_IMEI_CONTROL_IMEI);
+
+ if( retVal NEQ CL_IMEI_OK )
+ {
+   ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_IMEICheck );
+   TRACE_EVENT("IMEI not valid");
+   simShrdPrm.imei_blocked = TRUE;
+   /*return( AT_FAIL ); We dont return here to enable the stack to go to the state of "Limited Service' to enable emergency calls. */ 
+ }
+#endif /* if NOT defined windows simulation */
+
+/*
+ *-------------------------------------------------------------------
+ * 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
+ *-------------------------------------------------------------------
+ */
+  if( simEntStat.curCmd NEQ AT_CMD_NONE )
+  {
+    TRACE_EVENT("Entity SIM is busy: cannot proceed command...");
+    return( AT_BUSY );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * process the <rst> parameter
+ *-------------------------------------------------------------------
+ */
+  switch( rst )
+  {
+    case( CFUN_RST_NotPresent ):  /* default value */
+    case( CFUN_RST_NoReset ):
+
+    break;
+
+    default:                      /* unexpected parameter */
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * process the <fun> parameter
+ *-------------------------------------------------------------------
+ */
+  if( fun EQ CFUN_FUN_NotPresent ) fun = CFUNfun;
+
+  switch( fun )
+  {
+    case( CFUN_FUN_Minimum ):    /* set ME to minimum functionality */
+      CFUNfun           = fun;
+      simEntStat.curCmd = AT_CMD_CFUN;
+      simEntStat.entOwn = simShrdPrm.owner = srcId;
+
+    /* Turn off all possible ringing */
+#ifdef FF_ATI
+    io_setRngInd ( IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */
+#endif
+    for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+    {
+      R_AT( RAT_CRING_OFF, idx )( 0 );  /* Turn of all ringing */
+    }
+
+
+    /* We have to wait for both entities to finish in CFUN. So both EntStat are set to AT_CMD_CFUN and
+       when a certain entity finished it also emits AT_OK if the other entity has already finished */
+
+    simEntStat.curCmd = AT_CMD_CFUN;
+    simEntStat.entOwn = simShrdPrm.owner = srcId;
+
+    mmEntStat.curCmd  = AT_CMD_CFUN;
+    mmEntStat.entOwn  = mmShrdPrm.owner = srcId;
+
+    pb_exit();
+
+/*    simShrdPrm.synCs = SYNC_DEACTIVATE;  */   /* This is moved to pb_exit */
+/*    psaSIM_SyncSIM(); */
+
+
+#if defined (GPRS) AND defined (DTI)
+    mmShrdPrm.nrgCs = GMMREG_DT_POWER_OFF;
+    if( psaG_MM_CMD_DEREG ( mmShrdPrm.nrgCs ) < 0 )  /* deregister from network */
+#else
+    mmShrdPrm.nrgCs = CS_POW_OFF;
+    if( psaMM_DeRegistrate () < 0 )  /* deregister from network */
+#endif
+    {
+      TRACE_EVENT( "FATAL RETURN psaMM_DeRegistrate in +COPS" );
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+      return( AT_FAIL );
+    }
+
+    percentCSTAT_indication(STATE_MSG_SMS,   ENTITY_STATUS_NotReady);
+
+    retCd = AT_EXCT;
+    break;
+
+  case( CFUN_FUN_Full ):       /* set ME to full functionality */
+    if ( (CFUNfun EQ CFUN_FUN_Minimum) OR (simShrdPrm.PINStat NEQ PS_RDY) )
+    {
+      CFUNfun               = fun;
+      pSIMSetPrm -> actProc = SIM_INITIALISATION;
+
+      simEntStat.curCmd = AT_CMD_CFUN;
+      simEntStat.entOwn = simShrdPrm.owner = srcId;
+
+      if( psaSIM_ActivateSIM() < 0 )   /* activate SIM card */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in +CFUN" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+    }
+
+#ifdef SIM_PERS
+   else if (CFUNfun EQ CFUN_FUN_Full ) 
+   {
+   TRACE_EVENT("This is for if MMI calls sAT_PlusCFUN repetedly for verification of LOCKS");
+     CFUNfun               = fun;
+      pSIMSetPrm -> actProc = SIM_INITIALISATION;
+
+      simEntStat.curCmd = AT_CMD_CFUN;
+      simEntStat.entOwn = simShrdPrm.owner = srcId;
+
+      if( psaSIM_ActivateSIM() < 0 )   /* activate SIM card */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in +CFUN" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+   }
+#endif
+  else
+    {
+      TRACE_EVENT("Switch mobile back on after radio low (CFUN=4)");
+      CFUNfun  = fun;
+      retCd    = AT_CMPL;
+    }
+    break;
+
+  case (CFUN_FUN_Disable_TX_RX_RF):
+    if (CFUNfun EQ CFUN_FUN_Minimum)
+    {
+      TRACE_EVENT("Not possible to proceed when mobile is switched off");
+      ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+      return (AT_FAIL);
+    }
+    CFUNfun           = fun;
+
+    /* Turn off all possible ringing */
+#ifdef FF_ATI
+    io_setRngInd ( IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */
+#endif
+    for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+    {
+      R_AT( RAT_CRING_OFF, idx )( 0 );  /* Turn of all ringing */
+    }
+
+    if( mmEntStat.curCmd NEQ AT_CMD_BAND )
+    {
+      /* If sAT_PlusCFUN has been called by sAT_PercentBAND !!! */
+      mmEntStat.curCmd  = AT_CMD_CFUN;
+    }
+    mmEntStat.entOwn  = mmShrdPrm.owner = srcId;
+
+#if defined (GPRS) AND defined (DTI)
+    mmShrdPrm.nrgCs = GMMREG_DT_SOFT_OFF;
+    if( psaG_MM_CMD_DEREG ( mmShrdPrm.nrgCs ) < 0 )  /* deregister from network */
+#else
+    mmShrdPrm.nrgCs = CS_SOFT_OFF;
+    if( psaMM_DeRegistrate () < 0 )  /* deregister from network */
+#endif
+    {
+      TRACE_EVENT( "FATAL RETURN psaMM_DeRegistrate in +COPS" );
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+      return( AT_FAIL );
+    }
+
+    retCd = AT_EXCT;
+    break;
+
+  default:                     /* unexpected parameter */
+
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * log command execution
+ *-------------------------------------------------------------------
+ */
+#if defined SMI OR defined MFW OR defined FF_MMI_RIV
+  if( mmEntStat.curCmd NEQ AT_CMD_BAND
+    AND simEntStat.curCmd NEQ AT_CMD_BAND )
+  {
+  T_ACI_CLOG      cmdLog;     /* holds logging info */
+
+  cmdLog.atCmd                = AT_CMD_CFUN;
+  cmdLog.cmdType              = CLOG_TYPE_Set;
+  cmdLog.retCode              = retCd;
+  cmdLog.cId                  = ACI_NumParmNotPresent;
+  cmdLog.sId                  = ACI_NumParmNotPresent;
+  cmdLog.cmdPrm.sCFUN.srcId   = srcId;
+  cmdLog.cmdPrm.sCFUN.fun     = fun;
+  cmdLog.cmdPrm.sCFUN.rst     = rst;
+
+  rAT_PercentCLOG( &cmdLog );
+  }
+#endif
+
+  return( retCd );
+
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PercentSECP             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the %SEC AT command
+            which is responsible to enter a PIN.
+
+            <pin>:    string of PIN chars.
+            <newpin>: string of PIN chars required if requested PIN is
+                      SIM PUK
+*/
+
+GLOBAL T_ACI_RETURN sAT_PercentSECP ( T_ACI_CMD_SRC srcId,
+                                      CHAR * pin,
+                                      CHAR * newpin )
+{
+  T_SIMLOCK_STATUS  result;  
+  
+  TRACE_FUNCTION ("sAT_PercentSECP()");
+
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+  
+  /* Check validity of pin str*/
+  if( pin EQ NULL)
+  {
+     ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+     return( AT_FAIL );
+  }
+
+  /* Try to set new pin */
+  result = aci_ext_personalisation_CS_change_password( pin, newpin );     
+
+  switch (result)
+  {
+      case SIMLOCK_ENABLED:
+      case SIMLOCK_DISABLED:
+        /* success */
+        return AT_CMPL;
+      case SIMLOCK_BLOCKED:         /* password tried too many times, phone blocked */
+        ACI_ERR_DESC(ACI_ERR_CLASS_Cme, CME_ERR_PhoneFail);
+        return AT_FAIL;
+      case SIMLOCK_LOCKED: /* password wrong */
+        ACI_ERR_DESC(ACI_ERR_CLASS_Cme, CME_ERR_WrongPasswd);
+        return AT_FAIL;
+      default: /* other error */
+        ACI_ERR_DESC(ACI_ERR_CLASS_Cme, CME_ERR_Unknown);
+        return AT_FAIL;
+    }
+
+  
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PercentSECS             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the %SECS? AT command
+            which is responsible to set the status of the Security Code.
+
+            <securityStatus>:   Status of the security code.
+            <code>: Security code required to change the status.
+*/
+
+
+GLOBAL T_ACI_RETURN sAT_PercentSECS ( T_ACI_CMD_SRC srcId,
+                                   T_ACI_SECS_STA securityState,
+                                   CHAR * code )
+{
+
+  T_SIMLOCK_STATUS  result;
+
+  TRACE_FUNCTION ("sAT_PercentSECS()");
+
+
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check status value
+ *-------------------------------------------------------------------
+ */
+  switch (securityState)
+  {
+      case( SECS_STA_Enable ):
+        result = aci_ext_personalisation_CS_set_status(SIMLOCK_ENABLED, code);
+        break;      
+      case( SECS_STA_Disable ):
+        result = aci_ext_personalisation_CS_set_status(SIMLOCK_DISABLED, code);
+        break;      
+      default:
+      return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * analyze answer
+ *-------------------------------------------------------------------
+ */
+  switch (result)
+    {
+      case SIMLOCK_ENABLED:
+      case SIMLOCK_DISABLED:
+        /* success */
+        return AT_CMPL;
+     case SIMLOCK_BLOCKED:         /* password tried too many times, phone blocked */
+        ACI_ERR_DESC(ACI_ERR_CLASS_Cme, CME_ERR_PhoneFail);
+        return AT_FAIL;
+      case SIMLOCK_LOCKED: /* password wrong */
+        ACI_ERR_DESC(ACI_ERR_CLASS_Cme, CME_ERR_WrongPasswd);
+        return AT_FAIL;
+      default: /* other error */
+        ACI_ERR_DESC(ACI_ERR_CLASS_Cme, CME_ERR_Unknown);
+        return AT_FAIL;
+    }
+}
+
+
+
+
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCPIN             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CPIN AT command
+            which is responsible to enter a PIN.
+
+            <pin>:    string of PIN chars.
+            <newpin>: string of PIN chars required if requested PIN is
+                      SIM PUK
+*/
+
+GLOBAL T_ACI_RETURN sAT_PlusCPIN ( T_ACI_CMD_SRC srcId,
+                                   CHAR * pin,
+                                   CHAR * newpin )
+{
+  T_SIM_SET_PRM * pSIMSetPrm;  /* points to SIM parameter set */
+  T_ACI_RETURN    retCd;              /* holds return code */
+  T_SIMLOCK_STATUS retSlStatus; /* holds return code */
+
+  TRACE_FUNCTION ("sAT_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 entity status
+ *-------------------------------------------------------------------
+ */
+  if( simEntStat.curCmd NEQ AT_CMD_NONE )
+
+    return( AT_BUSY );
+
+/*
+ *-------------------------------------------------------------------
+ * check for PIN status
+ *-------------------------------------------------------------------
+ */
+  switch( simShrdPrm.PINStat )
+  {
+    case( PS_RDY ):
+      /*
+       *---------------------------------------------------------------
+        * Not a SIM PIN State, but a ME personalisation PIN
+       *---------------------------------------------------------------
+        */
+  #ifdef SIM_PERS
+      if (AciSLockShrd.blocked)
+      {
+        retSlStatus = aci_slock_authenticate(AciSLockShrd.current_lock, pin);
+        if ( retSlStatus NEQ SIMLOCK_DISABLED)
+        {
+          TRACE_EVENT( "Wrong PIN given for SIM lock." );
+          if (retSlStatus EQ SIMLOCK_BLOCKED)
+          {
+            switch (AciSLockShrd.current_lock)
+            {
+              case SIMLOCK_NETWORK:          ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NetworkPersPukReq);       break;
+              case SIMLOCK_NETWORK_SUBSET:   ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NetworkSubsetPersPukReq); break;
+              case SIMLOCK_SERVICE_PROVIDER: ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_ProviderPersPukReq);      break;
+              case SIMLOCK_CORPORATE:        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_CorporatePersPukReq);     break;
+              case SIMLOCK_SIM:              ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_PhoneFail);               break;
+                /* for SIMLOCK_SIM there is no PUK available. Instead the phone is blocked and can only be unblocked
+                   by the manufacturer as an anti-theft protection. (See manual of several competitor phones ...) */
+              case SIMLOCK_FIRST_SIM:        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_PhFSimPukReq);            break;
+              default:                       ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_WrongPasswd );            break;
+            }
+          }
+          else
+            ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_WrongPasswd );
+          return( AT_FAIL );
+        }
+        else			
+        {
+             simEntStat.curCmd     = AT_CMD_CPIN;
+	      aci_slock_set_CFG();
+             if(cfg_data EQ NULL)
+             	{
+             	  ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_Unknown ); 
+                 return( AT_FAIL );
+             	}
+             aci_slock_init();
+	      
+             retSlStatus = SIMLOCK_ENABLED;
+	      if(AciSLockShrd.current_lock < SIMLOCK_SIM)
+             {
+                AciSLockShrd.current_lock= AciSLockShrd.current_lock +1;
+                 AciSLockShrd.check_lock = SIMLOCK_CHECK_PERS;
+	          retSlStatus = aci_slock_checkpersonalisation(AciSLockShrd.current_lock);
+		}
+		switch(retSlStatus)
+             {
+               case  SIMLOCK_ENABLED  :
+			     return( AT_CMPL);
+               case  SIMLOCK_BLOCKED :
+			   	return( AT_FAIL);
+               case  SIMLOCK_WAIT :
+                         return (AT_EXCT);
+                         
+             }           
+          }
+
+	 }
+
+     #endif  
+    /*
+     *---------------------------------------------------------------
+     * no PIN input is required
+     *---------------------------------------------------------------
+     */
+      retCd = AT_FAIL;
+      break;
+
+    case( NO_VLD_PS ):
+    /*
+     *---------------------------------------------------------------
+     * PIN Status is unknown
+     *---------------------------------------------------------------
+     */
+
+    /* invoke SIM activate and enter PIN if needed ???? */
+      ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+      return( AT_FAIL );
+
+    case( PS_PIN1 ):
+    /*
+     *---------------------------------------------------------------
+     * PIN 1 input is required
+     *---------------------------------------------------------------
+     */
+      if( pin EQ NULL                 OR
+          strlen( pin ) < MIN_PIN_LEN OR
+          strlen( pin ) > PIN_LEN        )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+
+      cmhSIM_FillInPIN ( pin, pSIMSetPrm -> curPIN, PIN_LEN );
+      pSIMSetPrm -> PINType = PHASE_2_PIN_1;
+      simEntStat.curCmd     = AT_CMD_CPIN;
+      simEntStat.entOwn     = simShrdPrm.owner = srcId;
+
+      if( psaSIM_VerifyPIN() < 0 )  /* verify PIN */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in +CPIN" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+      break;
+
+    case( PS_PIN2 ):
+    /*
+     *---------------------------------------------------------------
+     * PIN 2 input is required
+     *---------------------------------------------------------------
+     */
+      if( pin EQ NULL                 OR
+          strlen( pin ) < MIN_PIN_LEN OR
+          strlen( pin ) > PIN_LEN        )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+
+      cmhSIM_FillInPIN ( pin, pSIMSetPrm -> curPIN, PIN_LEN );
+      pSIMSetPrm -> PINType = PHASE_2_PIN_2;
+      simEntStat.curCmd     = AT_CMD_CPIN;
+      simEntStat.entOwn     = simShrdPrm.owner = srcId;
+
+      if( psaSIM_VerifyPIN() < 0 )  /* verify PIN */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in +CPIN" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+      break;
+
+    case( PS_PUK1 ):
+    /*
+     *---------------------------------------------------------------
+     * PUK 1 input is required
+     *---------------------------------------------------------------
+     */
+      if( newpin EQ NULL                 OR
+          strlen( newpin ) EQ 0)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPukReq ); /* inform about needed PUK */
+        return( AT_FAIL );
+      }
+      if( pin EQ NULL                    OR
+          newpin EQ NULL                 OR
+          strlen( pin ) NEQ PUK_LEN      OR
+          strlen( newpin ) < MIN_PIN_LEN OR
+          strlen( newpin ) > PIN_LEN        )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+
+      cmhSIM_FillInPIN ( pin,    pSIMSetPrm -> unblkKey, PUK_LEN );
+      cmhSIM_FillInPIN ( newpin, pSIMSetPrm -> curPIN,   PIN_LEN );
+      pSIMSetPrm -> PINType = PHASE_2_PUK_1;
+      simEntStat.curCmd     = AT_CMD_CPIN;
+      simEntStat.entOwn     = simShrdPrm.owner = srcId;
+
+      if( psaSIM_UnblockCard( ) < 0 )  /* verify PIN */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in +CPIN" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+      break;
+
+    case( PS_PUK2 ):
+    /*
+     *---------------------------------------------------------------
+     * PUK 2 input is required
+     *---------------------------------------------------------------
+     */
+      if( newpin EQ NULL                 OR
+          strlen( newpin ) EQ 0)
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_SimPuk2Req ); /* inform about needed PUK2 */
+        return( AT_FAIL );
+      }
+      if( pin EQ NULL                    OR
+          newpin EQ NULL                 OR
+          strlen( pin ) NEQ PUK_LEN      OR
+          strlen( newpin ) < MIN_PIN_LEN OR
+          strlen( newpin ) > PIN_LEN        )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+
+      cmhSIM_FillInPIN ( pin,    pSIMSetPrm -> unblkKey, PUK_LEN );
+      cmhSIM_FillInPIN ( newpin, pSIMSetPrm -> curPIN,   PIN_LEN );
+      pSIMSetPrm -> PINType = PHASE_2_PUK_2;
+      simEntStat.curCmd     = AT_CMD_CPIN;
+      simEntStat.entOwn     = simShrdPrm.owner = srcId;
+
+      if( psaSIM_UnblockCard( ) < 0 )  /* verify PIN */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in +CPIN" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+      break;
+
+  default:
+      /*
+       *---------------------------------------------------------------
+       * unexpected PIN state
+       *---------------------------------------------------------------
+       */
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
+      return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * log command execution
+ *-------------------------------------------------------------------
+ */
+#if defined SMI OR defined MFW OR defined FF_MMI_RIV
+  {
+  T_ACI_CLOG      cmdLog;      /* holds logging info */
+
+  cmdLog.atCmd                = AT_CMD_CPIN;
+  cmdLog.cmdType              = CLOG_TYPE_Set;
+  cmdLog.retCode              = retCd;
+  cmdLog.cId                  = ACI_NumParmNotPresent;
+  cmdLog.sId                  = ACI_NumParmNotPresent;
+  cmdLog.cmdPrm.sCPIN.srcId   = srcId;
+  cmdLog.cmdPrm.sCPIN.pin     = pin;
+  cmdLog.cmdPrm.sCPIN.newpin  = newpin;
+
+  rAT_PercentCLOG( &cmdLog );
+  }
+#endif
+
+  return( retCd );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCAMM             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CAMM AT command
+            which is responsible to set the ACMMax.
+*/
+
+GLOBAL T_ACI_RETURN sAT_PlusCAMM ( T_ACI_CMD_SRC    srcId,
+                                   LONG             acmmax,
+                                   CHAR *           pwd)
+{
+  T_ACI_RETURN  ret = AT_FAIL;
+
+  TRACE_FUNCTION ("sAT_PlusCAMM()");
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * send parameters to advice of charge module.
+ *-------------------------------------------------------------------
+ */
+  simEntStat.curCmd     = AT_CMD_CAMM;
+  simEntStat.entOwn     = simShrdPrm.owner = srcId;
+  ret = aoc_set_values (srcId,
+                        AOC_ACMMAX,
+                        (void *) acmmax,
+                        (UBYTE *) pwd);
+
+/*
+ *-------------------------------------------------------------------
+ * Check return value of aoc_set_values() equal to AT_FAIL,
+ * resets simEntStat.curcmd and simEntStat.entown.
+ *-------------------------------------------------------------------
+ */
+
+  if( ret EQ AT_FAIL )
+  {
+    simEntStat.curCmd     = AT_CMD_NONE;
+    simEntStat.entOwn     = simShrdPrm.owner = OWN_NONE;
+  }
+
+  return( ret );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCPUC             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CPUC AT command
+            which is responsible to set the PUCT values.
+*/
+
+GLOBAL T_ACI_RETURN sAT_PlusCPUC ( T_ACI_CMD_SRC    srcId,
+                                   CHAR *           currency,
+                                   CHAR *           ppu,
+                                   CHAR *           pwd)
+{
+  T_puct          puct;
+  T_ACI_RETURN    ret = AT_FAIL;
+
+  TRACE_FUNCTION ("sAT_PlusCPUC()");
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * send parameters to advice of charge module.
+ *-------------------------------------------------------------------
+ */
+  strcpy ((char *) puct.currency, currency);
+  strcpy ((char *) puct.value, ppu);
+  simEntStat.curCmd     = AT_CMD_CPUC;
+  simEntStat.entOwn     = simShrdPrm.owner = srcId;
+  ret = aoc_set_values (srcId,
+                        AOC_PUCT,
+                        (void *)&puct,
+                        (UBYTE *) pwd);
+
+/*
+ *-------------------------------------------------------------------
+ * Check return value of aoc_set_values() equal to AT_FAIL,
+ * resets simEntStat.curcmd and simEntStat.entown.
+ *-------------------------------------------------------------------
+ */
+
+  if( ret EQ AT_FAIL )
+  {
+    simEntStat.curCmd     = AT_CMD_NONE;
+    simEntStat.entOwn     = simShrdPrm.owner = OWN_NONE;
+  }
+
+  return( ret );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCACM             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CACM AT command
+            which is responsible to reset the ACM value.
+*/
+
+GLOBAL T_ACI_RETURN sAT_PlusCACM ( T_ACI_CMD_SRC    srcId,
+                                   CHAR *           pwd)
+{
+  T_ACI_RETURN  ret = AT_FAIL;
+  
+  TRACE_FUNCTION ("sAT_PlusCACM()");
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * send parameters to advice of charge module.
+ *-------------------------------------------------------------------
+ */
+  simEntStat.curCmd     = AT_CMD_CACM;
+  simEntStat.entOwn     = simShrdPrm.owner = srcId;
+  ret = aoc_set_values (srcId,
+                        AOC_ACM,
+                        (void *) NULL,
+                        (UBYTE *) pwd);
+
+/*
+ *-------------------------------------------------------------------
+ * Check return value of aoc_set_values() equal to AT_FAIL,
+ * resets simEntStat.curcmd and simEntStat.entown.
+ *-------------------------------------------------------------------
+ */
+
+  if( ret EQ AT_FAIL )
+  {
+    simEntStat.curCmd     = AT_CMD_NONE;
+    simEntStat.entOwn     = simShrdPrm.owner = OWN_NONE;
+  }
+
+  return( ret );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCPOL             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CPOL AT command
+            which is responsible to access the preferred PLMN list.
+
+            <index>:  PLMN list index
+            <format>: PLMN format
+            <oper>:   PLMN name
+            <index2>: second PLMN list index for exchange operation
+            <mode>:   supplemental mode information
+*/
+
+GLOBAL T_ACI_RETURN sAT_PlusCPOL  ( T_ACI_CMD_SRC srcId,
+                                    SHORT index,
+                                    T_ACI_CPOL_FRMT format,
+                                    CHAR * oper,
+                                    SHORT index2,
+                                    T_ACI_CPOL_MOD mode )
+{
+  T_SIM_CMD_PRM * pSIMCmdPrm;       /* points to SIM command parameters */
+  T_SIM_SET_PRM * pSIMSetPrm;       /* points to SIM parameter set */
+  UBYTE plmn[ACI_LEN_PLMN_SEL_NTRY];/* holds coded plmn id */
+
+  TRACE_FUNCTION ("sAT_PlusCPOL()");
+
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+  pSIMSetPrm = &simShrdPrm.setPrm[srcId];
+  pSIMCmdPrm = &cmhPrm[srcId].simCmdPrm;
+
+/*
+ *-------------------------------------------------------------------
+ * check mode parameter
+ *-------------------------------------------------------------------
+ */
+  switch( mode )
+  {
+    case( CPOL_MOD_CompactList ):
+    case( CPOL_MOD_Insert ):
+    case( CPOL_MOD_NotPresent ):
+      break;
+
+    default:
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check format parameter
+ *-------------------------------------------------------------------
+ */
+  switch( format )
+  {
+    case( CPOL_FRMT_Long ):
+    case( CPOL_FRMT_Short ):
+    case( CPOL_FRMT_Numeric ):
+
+      if( index EQ ACI_NumParmNotPresent AND !oper )
+      {
+        pSIMCmdPrm->CPOLfrmt = format;
+        return( AT_CMPL );
+      }
+      break;
+
+    case( CPOL_FRMT_NotPresent ):
+
+      format = pSIMCmdPrm->CPOLfrmt;
+      break;
+
+    default:
+    {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return( AT_FAIL );
+    }
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check for write entry
+ *-------------------------------------------------------------------
+ */
+  if( oper )
+  {
+    /* code plmn id */
+    if( ! cmhSIM_GetCodedPLMN( oper, format, plmn ))
+    {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return( AT_FAIL );
+    }
+
+    /* if EF is already read */
+    if( EfPLMNselStat EQ EF_STAT_READ )
+    {
+      if( mode EQ CPOL_MOD_CompactList )
+      {
+        cmhSIM_CmpctPlmnSel( CPOLSimEfDataLen, CPOLSimEfData );
+      }
+
+      if( index NEQ ACI_NumParmNotPresent )
+      {
+        if( index > (CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY))
+        {
+          ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx );
+          return( AT_FAIL );
+        }
+
+        return cmhSIM_UpdPlmnSel( srcId, index, plmn, mode );
+      }
+      else
+
+        return cmhSIM_FndEmptyPlmnSel( srcId, plmn );
+    }
+    else
+    {
+      if( simEntStat.curCmd NEQ AT_CMD_NONE )
+
+        return( AT_BUSY );
+
+      pSIMCmdPrm->CPOLidx  = (UBYTE)(index EQ ACI_NumParmNotPresent)?
+                                    NOT_PRESENT_8BIT:index;
+      pSIMCmdPrm->CPOLmode = mode;
+      pSIMCmdPrm->CPOLact  = CPOL_ACT_Write;
+      memcpy( pSIMCmdPrm->CPOLplmn, plmn, ACI_LEN_PLMN_SEL_NTRY );
+
+      simEntStat.curCmd = AT_CMD_CPOL;
+      simEntStat.entOwn = srcId;
+
+      return cmhSIM_ReqPlmnSel ( srcId );
+    }
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check for delete entry
+ *-------------------------------------------------------------------
+ */
+  else
+  {
+    /* check presence of index */
+    if( index EQ ACI_NumParmNotPresent )
+    {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx );
+      return( AT_FAIL );
+    }
+
+    /* if EF is already read */
+    if( EfPLMNselStat EQ EF_STAT_READ )
+    {
+      if( mode EQ CPOL_MOD_CompactList )
+      {
+        cmhSIM_CmpctPlmnSel( CPOLSimEfDataLen, CPOLSimEfData );
+      }
+
+      if( index  > (CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY) OR
+         (index2 > (CPOLSimEfDataLen / ACI_LEN_PLMN_SEL_NTRY) AND
+          index2 NEQ ACI_NumParmNotPresent))
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx );
+        return( AT_FAIL );
+      }
+
+      if( index2 EQ ACI_NumParmNotPresent )
+
+        return cmhSIM_DelPlmnSel( srcId, index, mode );
+
+      else
+
+        return cmhSIM_ChgPlmnSel( srcId, index, index2 );
+    }
+    else
+    {
+      if( simEntStat.curCmd NEQ AT_CMD_NONE )
+
+        return( AT_BUSY );
+
+      pSIMCmdPrm->CPOLidx  = (UBYTE)index;
+      pSIMCmdPrm->CPOLidx2 = (index2 NEQ ACI_NumParmNotPresent)?
+                             (UBYTE)index2:NOT_PRESENT_8BIT;
+      pSIMCmdPrm->CPOLmode = mode;
+      pSIMCmdPrm->CPOLact  = CPOL_ACT_Delete;
+
+      simEntStat.curCmd = AT_CMD_CPOL;
+      simEntStat.entOwn = srcId;
+
+      return cmhSIM_ReqPlmnSel ( srcId );
+    }
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCRSM             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CRSM AT command
+            which is responsible for restricted SIM access.
+
+            <cmd>:     access command.
+            <fileId>:  file identifier
+            <p1>:      parameter 1
+            <p2>:      parameter 2
+            <p3>:      parameter 3
+            <dataLen>: length of data
+            <data>:    pointer to data
+*/
+
+T_ACI_RETURN sAT_PlusCRSM  ( T_ACI_CMD_SRC  srcId,
+                             T_ACI_CRSM_CMD cmd,
+                             SHORT          fileId,
+                             SHORT          p1,
+                             SHORT          p2,
+                             SHORT          p3,
+                             SHORT          dataLen,
+                             UBYTE         *data   )
+{
+  T_SIM_TRNS_ACC_PRM prm;   /* holds access parameter */
+
+  TRACE_FUNCTION ("sAT_PlusCRSM()");
+
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check entity status
+ *-------------------------------------------------------------------
+ */
+  if( simEntStat.curCmd NEQ AT_CMD_NONE )
+
+    return( AT_BUSY );
+
+/*
+ *-------------------------------------------------------------------
+ * check command, data, p1, p2 and p3 parameters
+ *-------------------------------------------------------------------
+ */
+  switch( cmd )
+  {
+    case( CRSM_CMD_UpdBin ):
+    case( CRSM_CMD_UpdRec ):
+
+      if( !data OR !dataLen )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+      /*lint -fallthrough*/
+
+    case( CRSM_CMD_ReadBin ):
+    case( CRSM_CMD_ReadRec ):
+
+      if( p1 EQ ACI_NumParmNotPresent OR
+          p2 EQ ACI_NumParmNotPresent OR
+          p3 EQ ACI_NumParmNotPresent )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+      break;
+
+    case( CRSM_CMD_GetResp ):
+    case( CRSM_CMD_Status ):
+
+      if( p3 EQ ACI_NumParmNotPresent )
+        p3 = 0;
+      break;
+
+    case( CRSM_CMD_NotPresent ):
+    default:
+    {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return( AT_FAIL );
+    }
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check fileId parameter
+ *-------------------------------------------------------------------
+ */
+  if( fileId EQ ACI_NumParmNotPresent AND cmd NEQ CRSM_CMD_Status )
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * convert command
+ *-------------------------------------------------------------------
+ */
+  switch( cmd )
+  {
+    case( CRSM_CMD_UpdBin  ): prm.cmd = SIM_UPDATE_BINARY;break;
+    case( CRSM_CMD_UpdRec  ): prm.cmd = SIM_UPDATE_RECORD;break;
+    case( CRSM_CMD_ReadBin ): prm.cmd = SIM_READ_BINARY;break;
+    case( CRSM_CMD_ReadRec ): prm.cmd = SIM_READ_RECORD;break;
+    case( CRSM_CMD_GetResp ): prm.cmd = SIM_GET_RESPONSE;break;
+    case( CRSM_CMD_Status  ): prm.cmd = SIM_STATUS;break;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * access SIM
+ *-------------------------------------------------------------------
+ */
+  simEntStat.curCmd = AT_CMD_CRSM;
+  simEntStat.entOwn = srcId;
+
+  prm.reqDataFld = (USHORT)fileId;
+  prm.p1         = (UBYTE)p1;
+  prm.p2         = (UBYTE)p2;
+  prm.p3         = (UBYTE)p3;
+  prm.dataLen    = (UBYTE)dataLen;
+  prm.transData  = data;
+
+  psaSIM_TrnsSIMAccess( &prm );
+
+  return( AT_EXCT );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PlusCSIM             |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the +CSIM AT command
+            which is responsible for generic SIM access.
+
+*/
+
+T_ACI_RETURN sAT_PlusCSIM  ( T_ACI_CMD_SRC  srcId,
+                             USHORT         dataLen,
+                             UBYTE         *data    )
+{
+  T_SIM_TRNS_ACC_PRM prm;   /* holds access parameter */
+
+  TRACE_FUNCTION ("sAT_PlusCSIM()");
+
+/*
+ *-------------------------------------------------------------------
+ * check command source
+ *-------------------------------------------------------------------
+ */
+  if(!cmh_IsVldCmdSrc (srcId))
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check entity status
+ *-------------------------------------------------------------------
+ */
+  if( simEntStat.curCmd NEQ AT_CMD_NONE )
+  {
+    return( AT_BUSY );
+  }
+
+#if 0 // Dmitriy: for EAP-SIM we need to run the GSM algorithm
+  if (data[0] EQ GSM_CLASS)
+  {
+    /* GSM instruction class is not allowed */
+    TRACE_EVENT("GSM instruction class is not allowed");
+    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+    return( AT_FAIL );
+  }
+#endif
+#if 0 /* do we really need the check for the ATP source ? */
+#ifdef _TARGET_
+  if (ati_is_src_type((UBYTE)srcId, ATI_SRC_TYPE_RIV) EQ FALSE)
+  {
+    /* don't allow other source type than RIV */
+    TRACE_EVENT("other src type than RIV is not allowed");
+    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+    return( AT_FAIL );
+  }
+#endif /*_TARGET_*/
+#endif /* */
+  if (dataLen > MAX_SIM_TRANSP)
+  {
+    /* wrong length value */
+    TRACE_EVENT("wrong length value");
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * access SIM
+ *-------------------------------------------------------------------
+ */
+  simEntStat.curCmd = AT_CMD_CSIM;
+  simEntStat.entOwn = srcId;
+
+  prm.cmd        = SIM_TRANSP_CMD;
+  prm.dataLen    = dataLen;
+  prm.transData  = data;
+
+  psaSIM_TrnsSIMAccess( &prm );
+
+  return( AT_EXCT );
+
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                 |
+| STATE   : code                  ROUTINE : sAT_PercentPVRF          |
++--------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart to the %PVRF AT command
+            which is responsible to verify a specific PIN.
+
+            <pin>:    string of PIN chars.
+            <newpin>: string of PIN chars required if requested PIN is
+                      SIM PUK
+*/
+
+GLOBAL T_ACI_RETURN sAT_PercentPVRF( T_ACI_CMD_SRC   srcId,
+                                     T_ACI_PVRF_TYPE type,
+                                     CHAR * pin,
+                                     CHAR * newpin )
+{
+  T_SIM_SET_PRM * pSIMSetPrm;  /* points to SIM parameter set */
+  T_ACI_RETURN    retCd;       /* holds return code */
+
+  TRACE_FUNCTION ("sAT_PercentPVRF()");
+
+/*
+ *-------------------------------------------------------------------
+ * 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
+ *-------------------------------------------------------------------
+ */
+  if( simEntStat.curCmd NEQ AT_CMD_NONE )
+
+    return( AT_BUSY );
+
+/*
+ *-------------------------------------------------------------------
+ * check for PIN type
+ *-------------------------------------------------------------------
+ */
+  switch( type )
+  {
+    case( PVRF_TYPE_Pin1 ):
+    case( PVRF_TYPE_Pin2 ):
+    /*
+     *---------------------------------------------------------------
+     * PIN 1/2 verify is required
+     *---------------------------------------------------------------
+     */
+      if( pin EQ NULL                 OR
+          strlen( pin ) < MIN_PIN_LEN OR
+          strlen( pin ) > PIN_LEN        )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+
+      cmhSIM_FillInPIN ( pin, pSIMSetPrm -> curPIN, PIN_LEN );
+      pSIMSetPrm -> PINType = (type EQ PVRF_TYPE_Pin1)?
+                                  PHASE_2_PIN_1:PHASE_2_PIN_2;
+      simEntStat.curCmd     = AT_CMD_PVRF;
+      simEntStat.entOwn     = simShrdPrm.owner = srcId;
+
+      if( psaSIM_VerifyPIN() < 0 )  /* verify PIN */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in %%PVRF" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+      break;
+
+    case( PVRF_TYPE_Puk1 ):
+    case( PVRF_TYPE_Puk2 ):
+    /*
+     *---------------------------------------------------------------
+     * PUK 1/2 verify is required
+     *---------------------------------------------------------------
+     */
+      if( pin EQ NULL                    OR
+          newpin EQ NULL                 OR
+          strlen( pin ) NEQ PUK_LEN      OR
+          strlen( newpin ) < MIN_PIN_LEN OR
+          strlen( newpin ) > PIN_LEN        )
+      {
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );
+      }
+
+      cmhSIM_FillInPIN ( pin,    pSIMSetPrm -> unblkKey, PUK_LEN );
+      cmhSIM_FillInPIN ( newpin, pSIMSetPrm -> curPIN,   PIN_LEN );
+      pSIMSetPrm -> PINType = (type EQ PVRF_TYPE_Puk1)?
+                                  PHASE_2_PUK_1:PHASE_2_PUK_2;
+      simEntStat.curCmd     = AT_CMD_PVRF;
+      simEntStat.entOwn     = simShrdPrm.owner = srcId;
+
+      if( psaSIM_UnblockCard( ) < 0 )  /* verify PIN */
+      {
+        TRACE_EVENT( "FATAL RETURN psaSIM in %%PVRF" );
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+        return( AT_FAIL );
+      }
+
+      retCd = AT_EXCT;
+      break;
+
+  default:
+    /*
+     *---------------------------------------------------------------
+     * unexpected PIN state
+     *---------------------------------------------------------------
+     */
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
+      return( AT_FAIL );
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * log command execution
+ *-------------------------------------------------------------------
+ */
+#if defined SMI OR defined MFW OR defined FF_MMI_RIV
+  {
+  T_ACI_CLOG      cmdLog;      /* holds logging info */
+
+  cmdLog.atCmd                = AT_CMD_PVRF;
+  cmdLog.cmdType              = CLOG_TYPE_Set;
+  cmdLog.retCode              = retCd;
+  cmdLog.cId                  = ACI_NumParmNotPresent;
+  cmdLog.sId                  = ACI_NumParmNotPresent;
+  cmdLog.cmdPrm.sPVRF.srcId   = srcId;
+  cmdLog.cmdPrm.sPVRF.type    = type;
+  cmdLog.cmdPrm.sPVRF.pin     = pin;
+  cmdLog.cmdPrm.sPVRF.newpin  = newpin;
+
+  rAT_PercentCLOG( &cmdLog );
+  }
+#endif
+
+  return( retCd );
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                |
+|                                 ROUTINE : sAT_PercentCPRI         |
++-------------------------------------------------------------------+
+
+  PURPOSE : set the CPRI mode for displaying/not displaying
+            ciphering indications
+*/
+
+GLOBAL T_ACI_RETURN sAT_PercentCPRI( T_ACI_CMD_SRC srcId,
+                                     UBYTE mode   )
+{
+  TRACE_FUNCTION ("sAT_PercentCPRI()");
+
+  if( !cmh_IsVldCmdSrc( srcId ) )
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+  if (simShrdPrm.ciSIMEnabled NEQ FALSE)   /* Since this function is used by MMI,it just returns AT_CMPL */
+  {
+    return( AT_CMPL );               /* If CPRI is enabled in the SIM,it just returns AT_CMPL */
+  }
+
+  else
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+    return( AT_FAIL );
+  }
+}
+
+#ifdef FF_DUAL_SIM
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_SIMS                |
+|                                 ROUTINE : sAT_PercentSIM         |
++-------------------------------------------------------------------+
+
+  PURPOSE : Select the SIM to be powered on
+*/
+
+GLOBAL T_ACI_RETURN sAT_PercentSIM( T_ACI_CMD_SRC srcId,
+                                     UBYTE sim_num   )
+{
+  T_SIM_SET_PRM * pSIMSetPrm; /* points to SIM parameter set */
+ 
+  TRACE_FUNCTION ("sAT_PercentSIM()");
+
+  if( !cmh_IsVldCmdSrc( srcId ) )
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );
+  }
+
+  pSIMSetPrm = &simShrdPrm.setPrm[srcId];
+
+  if( simEntStat.curCmd NEQ AT_CMD_NONE )
+  {
+    TRACE_EVENT("Entity SIM is busy: cannot proceed command...");
+    return( AT_BUSY );
+  }
+
+  if(CFUNfun EQ CFUN_FUN_Full)
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+    return( AT_FAIL );
+  }
+
+  if(sim_num < SIM_NUM_0 OR sim_num > SIM_NUM_2)
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
+    return( AT_FAIL );
+  }
+
+  pSIMSetPrm->SIM_Selected = sim_num;
+
+  simEntStat.curCmd = AT_CMD_SIM;
+  simEntStat.entOwn = simShrdPrm.owner = srcId;
+
+  if( psaSIM_SelectSIM() < 0 )   /* select SIM card */
+  {
+    TRACE_EVENT( "FATAL RETURN psaSIM in %SIM" );
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal );
+    return( AT_FAIL );
+  }
+  return(AT_EXCT);
+}
+#endif /*FF_DUAL_SIM*/
+/*==== EOF ========================================================*/