view src/aci2/aci/ati_sim.c @ 294:cd37d228dae0

src/gpf2/{misc,tst}: import from TCS211 semi-src with CRLF line endings and directory name capitalization cleaned up
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 21 Oct 2017 01:12:15 +0000
parents 93999a60b835
children
line wrap: on
line source

/*   
+-----------------------------------------------------------------------------
|  Project :  GSM-F&D (8411)
|  Modul   :  ATI
+-----------------------------------------------------------------------------
|  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 :  AT Command Interpreter: SIM related functions.
+-----------------------------------------------------------------------------
*/

#ifndef ATI_SIM_C
#define ATI_SIM_C

#undef DUMMY_ATI_STRINGS

#include "aci_all.h"

#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_io.h"
#include "aci_cmd.h"
#include "l4_tim.h"

#include "gdi.h"
#include "audio.h"

#include "aci_mem.h"
#include "aci_ext_pers.h"
#include "aci_slock.h"
#include "aci_prs.h"
#include "aci_lst.h"
#include "ati_int.h"

#ifdef  FF_ATI_BAT

#include "typedefs.h"
#include "gdd.h"
#include "bat.h"

#include "ati_bat.h"

#endif /* FF_ATI_BAT */

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

EXTERN CHAR *cmdExtError (T_ACI_EXT_ERR e);

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

  PURPOSE : %SECP command (PIN functionality for MMI Security)
*/

GLOBAL T_ATI_RSLT setatPercentSECP(CHAR * cl, UBYTE srcId)
{
  char pinOld [MAX_PWD_LENGTH]={0};                 
  char pinNew [MAX_PWD_LENGTH]={0};
  T_ACI_RETURN ret = AT_FAIL;

  TRACE_FUNCTION ("setatPercentSECP()");

  cl = parse(cl, "nn", (LONG)MAX_PWD_LENGTH, pinOld,(LONG)MAX_PWD_LENGTH, pinNew);
  if ( !cl OR (*pinOld EQ '\0' AND *pinNew EQ '\0') )  
  {   
    cmdCmeError(CME_ERR_OpNotAllow);    
    return ATI_FAIL;  
  }
  
  ret = sAT_PercentSECP(srcId, pinOld, pinNew);

  return (map_aci_2_ati_rslt(ret));
}


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

  PURPOSE : %SECS command (This function changes the state of the MMI Security code
                  It requires the existing security code as one of the parameters)
*/


GLOBAL  T_ATI_RSLT setatPercentSECS (CHAR *cl, UBYTE srcId)
{
  char code [MAX_PWD_LENGTH]={0};
  T_ACI_SECS_STA securityState = SECS_STA_NotPresent;
  T_ACI_RETURN ret = AT_FAIL;
  

  TRACE_FUNCTION ("setatPercentSECS()");

  /* Get the required state and the Security code from the command parameters*/
  cl = parse(cl, "dn", &securityState, (LONG)MAX_PWD_LENGTH, code);

  if ( !cl OR *code EQ '\0' )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

  ret = sAT_PercentSECS(srcId,securityState,code);
  return (map_aci_2_ati_rslt(ret));


}


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

  PURPOSE : %SECS? command (It queries the state of the MMI Security code)
*/


GLOBAL  T_ATI_RSLT quetatPercentSECS (CHAR *cl, UBYTE srcId)
{
  T_ACI_SECS_STA securityState = SECS_STA_NotPresent;
  T_ACI_RETURN ret = AT_FAIL;
  

  TRACE_FUNCTION ("qetatPercentSECS()");

  /* Get the State value from the Command Handler */
  ret = qAT_PercentSECS(srcId, &securityState);

    if (ret EQ AT_CMPL)
  {
    resp_disp(srcId, cl,"e",&securityState);
    return ATI_CMPL;
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }


}



GLOBAL CHAR *CPIN_RESULT(T_ACI_CPIN_RSLT code)
{
  switch (code)
  {
    default:
    case(CPIN_RSLT_NotPresent): return"not present";
    case(CPIN_RSLT_SimReady):   return"READY";
    case(CPIN_RSLT_SimPinReq):  return"SIM PIN";
    case(CPIN_RSLT_SimPukReq):  return"SIM PUK";
    case(CPIN_RSLT_PhSimPinReq):return"PH-SIM PIN";
    case(CPIN_RSLT_SimPin2Req): return"SIM PIN2";
    case(CPIN_RSLT_SimPuk2Req): return"SIM PUK2";
        /* OVK: Extended list of all possible result according to 07.07 */
    case(CPIN_RSLT_PhFSimPinReq): return"PH-FSIM PIN";
    case(CPIN_RSLT_PhFSimPukReq): return"PH-FSIM PUK";
    case(CPIN_RSLT_PhNetPinReq): return"PH-NET PIN";
    case(CPIN_RSLT_PhNetPukReq): return"PH_NET PUK";
    case(CPIN_RSLT_PhNetSubPinReq): return"PH-NETSUB PIN";
    case(CPIN_RSLT_PhNetSubPukReq): return"PH-NETSUB PUK";
    case(CPIN_RSLT_PhSPPinReq): return"PH-SP PIN";
    case(CPIN_RSLT_PhSPPukReq): return"PH-SP PUK";
    case(CPIN_RSLT_PhCorpPinReq): return"PH-CORP PIN";
    case(CPIN_RSLT_PhCorpPukReq): return"PH-CORP PUK";


  }
}

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

  PURPOSE : +CPIN command (PIN functionality of ME)
*/

GLOBAL T_ATI_RSLT setatPlusCPIN (char *cl, UBYTE srcId)
{
  char pinOld [MAX_PWD_LENGTH]={0};                 /* ES!! enough for bad guys?*/
  char pinNew [MAX_PWD_LENGTH]={0};
  T_ACI_RETURN ret = AT_FAIL;
  UBYTE slockBlocked = 0;              /* @GBR: AT_CMPL is interpreted as error per default. This is wrong, if the ME is SIMLOCKed */

  TRACE_FUNCTION ("setatPlusCPIN()");

  cl = parse(cl,"nn",(LONG)MAX_PWD_LENGTH,&pinOld,(LONG)MAX_PWD_LENGTH,&pinNew);
  if ( !cl OR *pinOld EQ '\0' )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  #ifdef SIM_PERS
  slockBlocked = AciSLockShrd.blocked;
  #endif
#ifdef  FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cpin my_bat_set_plus_cpin = {0};
    T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
    
    TRACE_FUNCTION("setatPlusCPIN() calls bat_send() <=== as APPLICATION");

    /* memset(&my_bat_set_plus_cpin,  FALSE, sizeof(my_bat_set_plus_cpin)); Already initilaised */
    cmd.ctrl_params = BAT_CMD_SET_PLUS_CPIN;
    cmd.params.ptr_set_plus_cpin = &my_bat_set_plus_cpin;

    /* Set old pin BAT attribs */
    my_bat_set_plus_cpin.c_pin = strlen(pinOld);
    memcpy(my_bat_set_plus_cpin.pin, pinOld, BAT_MAX_CPIN_PIN_LEN);

    /* Set new pin BAT attribs */
    if(my_bat_set_plus_cpin.c_newpin = strlen(pinNew))
    {
      my_bat_set_plus_cpin.v_newpin = TRUE;
      memcpy(my_bat_set_plus_cpin.pin, pinNew, BAT_MAX_CPIN_PIN_LEN);
    }

    src_params->curAtCmd = AT_CMD_CPIN;

    bat_send(ati_bat_get_client(srcId), &cmd);
    return ATI_EXCT; /* executing, because response is passed by callback function */
  }
  
#else /* no FF_ATI_BAT */

  TRACE_FUNCTION("setatPlusCPIN()");
  ret = sAT_PlusCPIN (srcId,pinOld,pinNew);

  switch(ret)
  {
    case(AT_EXCT):
    {
      break;
    }
    case(AT_BUSY):
    {
      cmdCmeError(CME_ERR_SimBusy);
      break;
    }
    case(AT_FAIL):
    {
      cmdCmeError(CME_ERR_Unknown);
      break;
    }
    case(AT_CMPL):
    {
      if (!slockBlocked)
      {
        cmdCmeError(CME_ERR_Unknown);
      }
      break;
    }
  }
  return (map_aci_2_ati_rslt(ret));
#endif  /* FF_ATI_BAT */
}

GLOBAL T_ATI_RSLT queatPlusCPIN (char *cl, UBYTE srcId)
{
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
  src_params->curAtCmd = AT_CMD_CPIN;

#ifdef  FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    TRACE_FUNCTION("queatPlusCPIN() calls bat_send() <=== as APPLICATION");

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CPIN;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cpin = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* no FF_ATI_BAT */
  {
  char pinOld [MAX_PWD_LENGTH]={0};                   /* ES!! enough for bad guys?*/
  char pinNew [MAX_PWD_LENGTH]={0};
  T_ACI_RETURN ret = AT_FAIL;
  T_ACI_CPIN_RSLT code;

  TRACE_FUNCTION ("queatPlusCPIN()");

  ret= qAT_PlusCPIN (srcId,&code);    /*PIN status is requested*/
  switch (ret)
  {
    case(AT_CMPL):
    {
      sprintf (g_sa,"+CPIN: %s",CPIN_RESULT(code));
      io_sendMessage (srcId, g_sa, ATI_NORMAL_OUTPUT);
      break;
    }
    case(AT_EXCT):
    {
      src_params->curAtCmd    = AT_CMD_CPIN;
      break;
    }
    default:
    {
      cmdCmeError (CME_ERR_Unknown);
      break;
    }
  }
  return (map_aci_2_ati_rslt(ret));
  }
#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : +CPOL command (preferred operator list)
*/

GLOBAL T_ATI_RSLT setatPlusCPOL (char *cl, UBYTE srcId)
{
  T_ACI_CPOL_FRMT format = CPOL_FRMT_NotPresent;
  SHORT           index = ACI_NumParmNotPresent;
  SHORT           startIdx=0,lastIdx=0,usdNtry=0;
  char            op[20] = {0};
  T_ACI_RETURN    ret = AT_FAIL;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCPOL()");

  cl = parse(cl,"dds",&index,&format,(LONG)20,op);
  if(!cl)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cpol cpol;
    UBYTE len;

    len=strlen(op);

    /*
    *   If the operator name is too big for the BAT structure, there's
    *   nothing we can do. A truncated version would be meaningless, and
    *   to omit it would result in an operator being deleted from the
    *   list.
    */
    if (len>BAT_MAX_CPOL_OPER_LEN)
      return(ATI_FAIL);

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CPOL;
    cmd.params.ptr_set_plus_cpol=&cpol;

    cpol.index=(S16)index;

    /*
    *   This relies on T_ACI_CPOL_FRMT being identical to
    *   T_BAT_plus_cpol_format.
    */
    cpol.format=(T_BAT_plus_cpol_format)format;

    if (len>0)
    {
      memcpy(cpol.oper,op,len);
      cpol.v_oper=TRUE;
      cpol.c_oper=(U8)len;
    }
    else
    {
      cpol.v_oper=FALSE;
    }

    bat_send(ati_bat_get_client(srcId), &cmd);
    src_params->curAtCmd=AT_CMD_CPOL;
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

#ifdef WIN32
  ret=sAT_PlusCPOL(srcId,index,format,
                   ((op[0] NEQ 0x0)?op:NULL),
                   cpolIdx2,
                   cpolMode);
#else
  ret=sAT_PlusCPOL(srcId,index,format,
                   ((op[0] NEQ 0x0)?op:NULL),
                   ACI_NumParmNotPresent,
                   CPOL_MOD_NotPresent);
#endif


  switch (ret)
  {
  case (AT_CMPL):
    return ATI_CMPL;
  case (AT_EXCT):
    src_params->curAtCmd    = AT_CMD_CPOL;
    return ATI_EXCT;
  default:
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }
#endif /* no FF_ATI_BAT */
}

GLOBAL T_ATI_RSLT tesatPlusCPOL (char *cl, UBYTE srcId)
{
  T_ACI_CPOL_FRMT format = CPOL_FRMT_NotPresent;
  SHORT           index = ACI_NumParmNotPresent;
  SHORT           startIdx=0,lastIdx=0,usdNtry=0;
  char            op[20] = {0};
  T_ACI_RETURN    ret = AT_FAIL;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("tesatPlusCPOL()");

  src_params->curAtCmd=AT_CMD_CPOL;

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_TST_PLUS_CPOL;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_tst_plus_cpol = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  } 
#else /* no FF_ATI_BAT */

  ret = tAT_PlusCPOL(srcId,&lastIdx,&usdNtry);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"+CPOL: (1-%d),(0-2)", lastIdx);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  if (ret EQ AT_EXCT)
  {
    src_params->curAtCmd  = AT_CMD_CPOL;
  }
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT */
}

GLOBAL T_ATI_RSLT queatPlusCPOL (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_ACI_CPOL_LST  plmnSelLst;
  UBYTE           idx;
  BOOL            loop;
#endif

  T_ACI_CPOL_FRMT format = CPOL_FRMT_NotPresent;
  SHORT           index = ACI_NumParmNotPresent;
  SHORT           startIdx=0,lastIdx=0,usdNtry=0;
  char            op[20] = {0};
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  src_params->curAtCmd=AT_CMD_CPOL;

  TRACE_FUNCTION("queatPlusCPOL()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CPOL;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cpol = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  } 
#else /* no FF_ATI_BAT */

#ifdef WIN32
  switch (qAT_PlusCPOL ( srcId,
                         1, &lastIdx,
                         &plmnSelLst[0],
                         cpolMode))
#else
  switch (qAT_PlusCPOL ( srcId,
                         1, &lastIdx,
                         &plmnSelLst[0],
                         CPOL_MOD_NotPresent))
#endif
  {
    case AT_CMPL:
      loop = TRUE;
      do
      {
        if( lastIdx EQ ACI_NumParmNotPresent )
          break;

        startIdx = lastIdx+1;

        for( idx=0; idx < MAX_OPER; idx++ )
        {
          if( plmnSelLst[idx].index EQ ACI_NumParmNotPresent )
          {
            loop = FALSE;
            break;
          }
          sprintf(g_sa,"+CPOL: %d,%d,\"%s\"", plmnSelLst[idx].index,
                                              plmnSelLst[idx].format,
                                              plmnSelLst[idx].oper );
          io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
        }

        if( qAT_PlusCPOL(srcId, startIdx, &lastIdx, &plmnSelLst[0],
#ifdef WIN32
            cpolMode
#else
            CPOL_MOD_NotPresent
#endif
           ) EQ AT_FAIL OR !loop)
        {
          break;
        }
      }
      while( loop );
      return ATI_CMPL;

    case AT_EXCT:
      src_params->curAtCmd    = AT_CMD_CPOL;
      return ATI_EXCT;

    default:
      cmdCmeError(CME_ERR_Unknown);
      return ATI_FAIL;
  }

#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : +CNUM command (subscriber number)
*/

GLOBAL T_ATI_RSLT setatPlusCNUM (char *cl, UBYTE srcId)
{
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
  TRACE_FUNCTION("setatPlusCNUM()");

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    TRACE_FUNCTION("setatPlusCNUM() calls bat_send() <=== as APPLICATION");

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CNUM;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_set_plus_cnum = &dummy;

    bat_send(ati_bat_get_client(srcId), &cmd);
 
    src_params->curAtCmd=AT_CMD_CNUM;
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

  if ( qAT_PlusCNUM ( srcId, CNUM_MOD_NewRead ) EQ AT_EXCT )
  {
    src_params->curAtCmd    = AT_CMD_CNUM;
    return ATI_EXCT;
  }
  else
  {
    cmdCmeError ( CME_ERR_Unknown );
    return ATI_FAIL;
  }

#endif /* no FF_ATI_BAT */
}


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

  PURPOSE : +CFUN command (Phone functionality)
*/

GLOBAL T_ATI_RSLT setatPlusCFUN (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret   = AT_FAIL;
  T_ACI_CFUN_FUN fun = CFUN_FUN_NotPresent;
  T_ACI_CFUN_RST rst = CFUN_RST_NotPresent;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  src_params->curAtCmd = AT_CMD_CFUN;
  
  cl = parse (cl, "dd", &fun, &rst);
  if ( !cl )
  {
    cmdCmeError (CME_ERR_OpNotAllow);
    return ret;
  }

#ifdef  FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cfun my_bat_set_plus_cfun;
    
    TRACE_FUNCTION("setatPlusCFUN() calls bat_send() <=== as APPLICATION");

    memset(&my_bat_set_plus_cfun,  FALSE, sizeof(my_bat_set_plus_cfun));
    cmd.ctrl_params = BAT_CMD_SET_PLUS_CFUN;
    cmd.params.ptr_set_plus_cfun = &my_bat_set_plus_cfun;

    my_bat_set_plus_cfun.fun = (T_BAT_VAL_plus_cfun_fun)fun;
    my_bat_set_plus_cfun.rst = (T_BAT_VAL_plus_cfun_rst)rst;


    bat_send(ati_bat_get_client(srcId), &cmd);
    return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* no FF_ATI_BAT */
  {
    TRACE_FUNCTION("setatPlusCFUN()");
    ret = sAT_PlusCFUN (srcId,fun,rst);
    switch (ret)
    {
      case AT_EXCT:               /*Command is executing*/
        audio_SetAmplf (AUDIO_MICROPHONE, (UBYTE)75);
        audio_SetAmplf (AUDIO_SPEAKER,    (UBYTE)175);
        src_params->curAtCmd    = AT_CMD_CFUN;
        break;

      case AT_CMPL:
        src_params->curAtCmd    = AT_CMD_NONE;
        break;

      default: /* AT_FAIL or nothing was returned */
        cmdExtError (EXT_ERR_NotPresent);
        break;
    }
    return (map_aci_2_ati_rslt (ret));
  }
#endif /* no FF_ATI_BAT */
}

GLOBAL T_ATI_RSLT queatPlusCFUN (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  T_ACI_CFUN_FUN fun = CFUN_FUN_NotPresent;
  T_ACI_CFUN_RST rst = CFUN_RST_NotPresent;

#ifdef  FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    TRACE_FUNCTION("queatPlusCFUN() calls bat_send() <=== as APPLICATION");

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CFUN;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cfun = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* no FF_ATI_BAT */
  TRACE_FUNCTION("queatPlusCFUN()");

  ret = qAT_PlusCFUN(srcId, &fun);
  if (ret EQ AT_CMPL)
  {
    resp_disp(srcId, cl,"e",&fun);
    return ATI_CMPL;
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }
#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : +CIMI command (request international mobile subscriber
                           identity)
*/
GLOBAL T_ATI_RSLT setatPlusCIMI(char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  CHAR imsi[MAX_IMSI_LEN+1];        /* +1 for '\0' */
#endif

  T_ACI_RETURN   ret = AT_FAIL;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCIMI()");

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    TRACE_FUNCTION("setatPlusCIMI() calls bat_send() <=== as APPLICATION");

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CIMI;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_set_plus_cimi = &dummy;

    bat_send(ati_bat_get_client(srcId), &cmd);
 
    src_params->curAtCmd=AT_CMD_CIMI;
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

  ret = qAT_PlusCIMI(srcId, imsi);
  switch (ret)
  {
    case( AT_CMPL ):

      sprintf(g_sa,"%s",imsi);
      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
      break;

    case( AT_EXCT ):
      src_params->curAtCmd    = AT_CMD_CIMI;
      break;

    default:

      break;
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT */
}


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

  PURPOSE : +CRSM Restricted SIM access
*/
GLOBAL T_ATI_RSLT setatPlusCRSM(char *cl, UBYTE srcId)
{
  T_ACI_RETURN     ret        = AT_FAIL;
  UBYTE           *data;
  USHORT           lenData    = 0;
  T_ACI_CRSM_CMD   cmd        = CRSM_CMD_NotPresent;
  SHORT            fileId     = ACI_NumParmNotPresent,
                   p1         = ACI_NumParmNotPresent,
                   p2         = ACI_NumParmNotPresent,
                   p3         = ACI_NumParmNotPresent;
  USHORT           lenDataStr = 0;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);


  TRACE_FUNCTION("setatPlusCRSM");

  cl = parse(cl,"drrrrl", &cmd,&fileId, &p1, &p2, &p3,&lenDataStr,&data );
  if(!cl)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

  utl_hexToGsm( data, lenDataStr, data, &lenData, GSM_ALPHA_Def,
                CSCS_ALPHA_Reserved );

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send bat_cmd;
    T_BAT_cmd_set_plus_crsm crsm;

    /*
    *   If the data is too big for the BAT structure, there's
    *   nothing we can do. A truncated version would be meaningless.
    */
    if (lenData>BAT_MAX_CRSM_DATA_LEN)
      return(ATI_FAIL);

    bat_cmd.ctrl_params = BAT_CMD_SET_PLUS_CRSM;
    bat_cmd.params.ptr_set_plus_crsm=&crsm;

    /*
    *   This relies on T_ACI_CRSM_COMMAND and T_BAT_plus_crsm_command
    *   being identical. They are, except in that the ACI version has
    *   a 'not present' value. This is not an issue in this direction.
    */
    crsm.command=(T_BAT_plus_crsm_command)cmd;

    crsm.fileid=(S32)fileId;
    crsm.p1=(S16)p1;
    crsm.p2=(S16)p2;
    crsm.p3=(S16)p3;
    crsm.c_data=(U8)lenData;
    memcpy(crsm.data,data,lenData);

    bat_send(ati_bat_get_client(srcId),&bat_cmd);

    src_params->curAtCmd=AT_CMD_CRSM;
    return(ATI_EXCT);
  }
#else /* no FF_ATI_BAT */

  ret = sAT_PlusCRSM( srcId, cmd, fileId, p1, p2, p3,
                      lenData, data );
  if (ret EQ AT_EXCT)
  {
    src_params->curAtCmd = AT_CMD_CRSM;
  }
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : +CSIM Generic SIM access
*/
GLOBAL T_ATI_RSLT setatPlusCSIM(char *cl, UBYTE srcId)
{
  T_ACI_RETURN     ret        = AT_FAIL;
  USHORT           given_length;
  UBYTE           *data;
  USHORT           lenData    = 0;
  USHORT           lenDataStr = 0;


  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);


  TRACE_FUNCTION("setatPlusCSIM");

  cl = parse(cl,"rl", &given_length, &lenDataStr, &data );
  if(!cl)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

  if ((given_length > MAX_SIM_TRANSP*2)
       OR (given_length NEQ lenDataStr)
       OR (lenDataStr EQ 0))
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

  lenData = utl_HexStrToBin(data, lenDataStr, data, MAX_SIM_TRANSP);

  if (lenData EQ 0)
  {
    TRACE_EVENT("invalid character in <command>");
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send bat_cmd;
    T_BAT_cmd_set_plus_csim csim;

    /*
    *   If the data is too big for the BAT structure, there's
    *   nothing we can do. A truncated version would be meaningless.
    */
    if (lenData>BAT_MAX_CSIM_CMD_LEN)
      return(ATI_FAIL);

    bat_cmd.ctrl_params = BAT_CMD_SET_PLUS_CSIM;
    bat_cmd.params.ptr_set_plus_csim=&csim;

    csim.c_command=(U8)lenData;
    memcpy(csim.command,data,lenData);

    bat_send(ati_bat_get_client(srcId),&bat_cmd);

    src_params->curAtCmd=AT_CMD_CRSM;
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

  ret = sAT_PlusCSIM( srcId, lenData, data );
  if (ret EQ AT_EXCT)
  {
    src_params->curAtCmd = AT_CMD_CSIM;
  }
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : %ATR answer to reset (query)
*/
GLOBAL T_ATI_RSLT queatPercentATR ( char *cl, UBYTE srcId )
{
#ifndef FF_ATI_BAT
  T_ACI_RETURN ret;
  UBYTE i;
  UBYTE phase;
  UBYTE atr_len = 0;
  UBYTE atr_info[MAX_SIM_ATR];
#endif

  TRACE_FUNCTION( "queatPercentATR()" );

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_ATR;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_atr = &dummy;

    /*
    *   Without this we will lose track of the source ID by the time the
    *   response arrives.
    */
    srcId_cb=srcId;

    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  } 
#else /* no FF_ATI_BAT */

  ret = qAT_PercentATR( srcId, &phase, &atr_len, atr_info );

  if( ret NEQ AT_CMPL )
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  else
  {
    if(phase NEQ NOT_PRESENT_8BIT)
    {
      i=sprintf(g_sa,"%s%d,", "%ATR: ", phase);/* if phase available.. return phase*/
    }
    else
    {
      i=sprintf(g_sa,"%s", "%ATR: FFFF");/* else return FFFF*/
    }

    if(atr_len)                    /* if ATR data available... return ATR data*/
    {
      sprintf(g_sa+i,","); 
      utl_binToHex( atr_info, atr_len, g_sa+i );
    }
        
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : %CPRI command (select cipher indication mode)
*/

GLOBAL T_ATI_RSLT setatPercentCPRI ( char *cl, UBYTE srcId )
{
  T_ACI_RETURN ACI_return = AT_FAIL;
  UBYTE CPRImode;

  TRACE_FUNCTION( "setatPercentCPRI()" );

  switch( *cl )
  {
  case '0':
  case '1':
    CPRImode = *cl - 0x30; /* make binary value */
    cl++;
    ACI_return = sAT_PercentCPRI( srcId, CPRImode );
    if( ACI_return NEQ AT_CMPL )
    {
      cmdCmeError(CME_ERR_Unknown);
    }
    else                                         /* If ACI_return is AT_CMPL,updates the CPRI_stat with CPRImode */
    {
      ati_user_output_cfg[srcId].CPRI_stat = CPRImode;
    }
    break;
  default:
    cmdCmeError(CME_ERR_OpNotAllow);
    break;
  }
  return (map_aci_2_ati_rslt(ACI_return));
}


GLOBAL T_ATI_RSLT queatPercentCPRI ( char *cl, UBYTE srcId )
{
  T_ACI_RETURN ACI_return = AT_FAIL;
  UBYTE CPRIenabled;

  TRACE_FUNCTION( "queatPercentCPRI()" );

  ACI_return = qAT_PercentCPRI( srcId, &CPRIenabled );
  
  if( ACI_return NEQ AT_CMPL )
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  else
  {
    if (CPRIenabled)
    {
      CPRIenabled = ati_user_output_cfg[srcId].CPRI_stat;
    }
    else
    {
      CPRIenabled = CI_DISABLED;
    }
    resp_disp(srcId, cl,"b",&CPRIenabled);
  }
  return (map_aci_2_ati_rslt(ACI_return));
}

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

  PURPOSE : return information relating to status of PIN.

*/

GLOBAL T_ATI_RSLT setatPercentPVRF( char *cl, UBYTE srcId )
{
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
  T_ACI_PVRF_TYPE type;
  CHAR            pin[10];
  CHAR            newpin[10];
  T_ACI_RETURN    ret          = AT_FAIL;

  TRACE_FUNCTION( "setatPercentPVRF()" );

  /* parse mode */
  cl = parse (cl, "dss", &type, (LONG) sizeof (pin),pin, (LONG) sizeof (newpin), newpin);
  if ((!cl) OR (type > PVRF_TYPE_Puk2) OR (type <= PVRF_TYPE_NotPresent))
  {
    cmdCmeError (CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_pvrf pvrf;
    UBYTE len;

    cmd.ctrl_params = BAT_CMD_SET_PERCENT_PVRF;
    cmd.params.ptr_set_percent_pvrf=&pvrf;

    /*
    *   This relies on T_ACI_PVRF_TYPE and T_BAT_percent_pvrf_type
    *   being identical. They are, except in that the ACI version has
    *   a 'not present' value. In this direction, that doesn't matter.
    */
    pvrf.type=(T_BAT_percent_pvrf_type)type;

    len=strlen(pin);
    if (len>BAT_MAX_PVRF_PIN_LEN)
      return(ATI_FAIL);

    pvrf.c_pin=(U8)len;
    memcpy(pvrf.pin,pin,len);

    len=strlen(newpin);
    if (len>BAT_MAX_PVRF_NEW_PIN_LEN)
      return(ATI_FAIL);

    if (len)
    {
      pvrf.v_newpin=TRUE;
      pvrf.c_newpin=(U8)len;
      memcpy(pvrf.newpin,newpin,len);
    }
    else
    {
      pvrf.v_newpin=FALSE;
    }
    bat_send(ati_bat_get_client(srcId), &cmd);

    src_params->curAtCmd=AT_CMD_PVRF;
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

  ret = sAT_PercentPVRF (srcId, type, pin, newpin);

  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      break;
    case (AT_EXCT):
      src_params->curAtCmd = AT_CMD_PVRF;
      break;
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      break;
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT */
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : code                        ROUTINE : queatPercentPVRF   |
+--------------------------------------------------------------------+

  PURPOSE : %PVRF command
*/
GLOBAL T_ATI_RSLT queatPercentPVRF (char *cl, UBYTE srcId)
{
  TRACE_FUNCTION("queatPercentPVRF()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_PVRF;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_pvrf = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  } 
#else /* no FF_ATI_BAT */
  {
  T_ACI_PVRF_STAT ps1;
  T_ACI_PVRF_STAT ps2;
  CHAR  *me = "%PVRF: ";
  SHORT  pn1cnt = 0;
  SHORT  pn2cnt = 0;
  SHORT  pk1cnt = 0;
  SHORT  pk2cnt = 0;

  T_ACI_RETURN ret = qAT_PercentPVRF(srcId, &pn1cnt, &pn2cnt, &pk1cnt, &pk2cnt, &ps1, &ps2);

  if (ret NEQ AT_CMPL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  sprintf(g_sa,"%s%d, %d, %d, %d, %d, %d", me, pn1cnt, pn2cnt, pk1cnt, pk2cnt, ps1, ps2);
  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

  return (ATI_CMPL);
  }
#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : %CUST command ( Set Customisation Mode Function )
*/

GLOBAL T_ACI_RETURN setatPercentCUST ( char *cl, UBYTE srcId )
{
  TRACE_FUNCTION( "setatPercentCUST()" );

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_cust cust;

    cmd.ctrl_params = BAT_CMD_SET_PERCENT_CUST;
    cmd.params.ptr_set_percent_cust=&cust;

    switch (*cl)
    {
      case '0':
        cust.mode=BAT_P_CUST_MODE_NORMAL;
        break;

      case '1':
        cust.mode=BAT_P_CUST_MODE_BEHAVIOUR_1;
        break;

      default:
        cmdCmeError(CME_ERR_OpNotAllow);
        return(ATI_FAIL);
    }
    bat_send(ati_bat_get_client(srcId), &cmd);

    return(ATI_EXCT);
  }
#else /* no FF_ATI_BAT */

  switch( *cl )
  {
    case '0':
      if (sAT_PercentCUST(srcId, (UBYTE)CUST_NORMAL_BEHAVIOUR) EQ AT_FAIL)
      {
        cmdCmeError(CME_ERR_Unknown);
        return (ATI_FAIL);
      }
      break;

    case '1':
      if (sAT_PercentCUST (srcId, (UBYTE)CUST_MODE_BEHAVIOUR_1) EQ AT_FAIL)
      {
        cmdCmeError(CME_ERR_Unknown);
        return (ATI_FAIL);
      }
      break;

    default:
      cmdCmeError(CME_ERR_OpNotAllow);
      return (ATI_FAIL);
   }

  return (ATI_CMPL);

#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : %CUST command (Customisaton Mode)
*/
GLOBAL T_ATI_RSLT queatPercentCUST (char *cl, UBYTE srcId)
{
  TRACE_FUNCTION("queatPercentCUST()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_CUST;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_cust = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  } 
#else /* no FF_ATI_BAT */
  {
    T_CUST_MOD mode;
    T_ACI_RETURN ret = qAT_PercentCUST(srcId, &mode);

    if (ret NEQ AT_CMPL)
    {
      cmdCmeError(CME_ERR_Unknown);
      return (ATI_FAIL);
    }

    sprintf(g_sa,"%%CUST: %d", mode);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

    return ATI_CMPL;
  }
#endif /* no FF_ATI_BAT */
}

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

  PURPOSE : %SATCC command ( Enable/Disable the Call/Short Message Control By SIM )
*/

GLOBAL T_ACI_RETURN setatPercentSATCC ( char *cl, UBYTE srcId )

{
#ifdef FF_ATI_BAT
  T_BAT_cmd_send              bat_cmd;
  T_BAT_cmd_set_percent_satcc satcc;
#endif
  TRACE_FUNCTION( "setatPercentSATCC()" );

#ifdef FF_ATI_BAT
  switch( *cl )
  {
    case '0':
      satcc.mode = BAT_P_SATCC_MODE_INACTIVE;
      break;
    case '1':
      satcc.mode = BAT_P_SATCC_MODE_ACTIVE;
      break;
    default:
      cmdCmeError(CME_ERR_Unknown);
      return (ATI_FAIL);
  }

  bat_cmd.ctrl_params                  = BAT_CMD_SET_PERCENT_SATCC;
  bat_cmd.params.ptr_set_percent_satcc = &satcc;

  bat_send(ati_bat_get_client(srcId),&bat_cmd);

  return(ATI_EXCT);

#else
  switch( *cl )
  {
    case '0':
      if (sAT_PercentSATCC(srcId, (UBYTE)SATCC_CONTROL_BY_SIM_INACTIVE) EQ AT_FAIL)
      {
        cmdCmeError(CME_ERR_Unknown);
        return (ATI_FAIL);
      }
      break;

    case '1':
      if (sAT_PercentSATCC (srcId, (UBYTE)SATCC_CONTROL_BY_SIM_ACTIVE) EQ AT_FAIL)
      {
        cmdCmeError(CME_ERR_Unknown);
        return (ATI_FAIL);
      }
      break;

    default:
      cmdCmeError(CME_ERR_OpNotAllow);
      return (ATI_FAIL);
   }

  return (ATI_CMPL);

#endif
}

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

  PURPOSE : %SATCC command (Query Call/Short Message control By SIM)
*/
GLOBAL T_ATI_RSLT queatPercentSATCC (char *cl, UBYTE srcId)
{
#ifdef FF_ATI_BAT
  T_BAT_cmd_send     bat_cmd;
  T_BAT_no_parameter satcc;
#else
  T_SAT_CC_MOD    mode;
  T_ACI_RETURN      ret = AT_FAIL;
#endif

  TRACE_FUNCTION("queatPercentSATCC()");

#ifdef FF_ATI_BAT
  bat_cmd.ctrl_params                  = BAT_CMD_QUE_PERCENT_SATCC;
  bat_cmd.params.ptr_que_percent_satcc = &satcc;

  bat_send(ati_bat_get_client(srcId),&bat_cmd);

  return(ATI_EXCT);

#else

  ret = qAT_PercentSATCC(srcId, &mode);

  if (ret NEQ AT_CMPL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  sprintf(g_sa,"%%SATCC: %d", mode);
  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
	
#endif /*FF_ATI_BAT*/ 

  return ATI_CMPL;
} 

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

  PURPOSE : enable %SIMINS / %SIMREM indications
*/

GLOBAL T_ATI_RSLT setatPercentSIMIND(char *cl, UBYTE srcId)
{
  int mode = 1;

  TRACE_FUNCTION("setatPercentSIMIND()");

  /* parse mode */
  cl = parse (cl, "d", &mode);

  if (mode EQ 0 OR mode EQ 1)
  {
    ati_user_output_cfg[srcId].SIMIND_stat = mode;
    return (ATI_CMPL);
  }
  else
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : ACI_CMD            |
| STATE   : code                        ROUTINE : queatPercentSIMIND |
+--------------------------------------------------------------------+

  PURPOSE : query status of %SIMINS / %SIMREM indications
*/
GLOBAL T_ATI_RSLT queatPercentSIMIND(char *cl, UBYTE srcId)
{
  CHAR           *me  =  "%SIMIND";

  TRACE_FUNCTION("queatPercentSIMIND()");

  sprintf(g_sa,"%s: %d", me, ati_user_output_cfg[srcId].SIMIND_stat);
  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

  return (ATI_CMPL);
}

#ifdef FF_DUAL_SIM
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
| STATE   : code                        ROUTINE : atPlusCFUN         |
+--------------------------------------------------------------------+

  PURPOSE : %SIM command (SIM Selection)
*/

GLOBAL T_ATI_RSLT setatPercentSIM (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret   = AT_FAIL;
  UBYTE sim_num;

  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPercentSIM()");

  /*input functionality*/
  cl = parse (cl,"d",&sim_num);
  if ( !cl )
  {
    cmdCmeError (CME_ERR_OpNotAllow);
    return(ATI_FAIL);
  }
  
  ret = sAT_PercentSIM (srcId,sim_num);
  switch (ret)
  {
    case AT_EXCT:               /*Command is executing*/
      src_params->curAtCmd    = AT_CMD_SIM;
      break;

    case AT_FAIL:
      src_params->curAtCmd    = AT_CMD_NONE;
      break;

    default:
      cmdCmeError(CME_ERR_Unknown);
      break;
  }
  return (map_aci_2_ati_rslt (ret));
}

GLOBAL T_ATI_RSLT queatPercentSIM (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  UBYTE sim_num;

  TRACE_FUNCTION("queatPercentSIM()");

  ret = qAT_PercentSIM(srcId, &sim_num);

  if (ret EQ AT_CMPL)
  {
    resp_disp(srcId, cl,"b",&sim_num);
    return ATI_CMPL;
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }
}
#endif /*FF_DUAL_SIM*/
#endif /* ATI_SIM_C */