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

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

/* 
+----------------------------------------------------------------------------- 
|  Project :  GSM-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 commands related to phonebook.
+----------------------------------------------------------------------------- 
*/ 

#ifndef ATI_PHB_C
#define ATI_PHB_C

#undef DUMMY_ATI_STRINGS

#include "aci_all.h"

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

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

#include "aci_mem.h"
#include "psa.h"
#include "cmh.h"
#include "pcm.h"
#include "aci_prs.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 */

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

  PURPOSE : +CPBS (Select Phonebook memory storage)
*/

GLOBAL T_ATI_RSLT setatPlusCPBS(char *cl, UBYTE srcId)
{
  char *me="+CPBS: ";
  T_ACI_RETURN    ret = AT_FAIL;
  T_ACI_PB_STOR   stor = PB_STOR_NotPresent; 
  CHAR            pin2[MAX_PWD_LENGTH] = {0};
  CHAR            sto_str[3]={0};
  SHORT           i;

  TRACE_FUNCTION("setatPlusCPBS()");

  cl = parse(cl,"sn",(LONG)3,sto_str,(LONG)MAX_PWD_LENGTH,pin2);
  if(!cl OR *sto_str EQ '\0')
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  strupper(sto_str);
  for(i=0;phb_mem_names[i].name NEQ 0;i++)
  {
    if (!strcmp(phb_mem_names[i].name,sto_str) )
    {
      stor=phb_mem_names[i].stor;
      break;
    }
  }
  if(phb_mem_names[i].name EQ 0)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cpbs my_bat_set_plus_cpbs = {0};
    T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
    
    TRACE_FUNCTION("setatPlusCPBS() calls bat_send() <=== as APPLICATION");

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CPBS;
    cmd.params.ptr_set_plus_cpbs = &my_bat_set_plus_cpbs;

    my_bat_set_plus_cpbs.storage = (T_BAT_storage)stor;

    src_params->curAtCmd = AT_CMD_CPBS;
    srcId_cb = srcId;
    bat_send(ati_bat_get_client(srcId), &cmd);
    srcId_cb = srcId;
    return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* no FF_ATI_BAT */
  ret = sAT_PlusCPBS(srcId,stor,pin2);
  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 queatPlusCPBS(char *cl, UBYTE srcId)
{
#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    TRACE_FUNCTION("queatPlusCPBS() calls bat_send() <=== as APPLICATION");
    
    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CPBS;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cpbs = &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 *me="+CPBS: ";
  T_ACI_RETURN    ret = AT_FAIL;
  CHAR            sto_str[3]={0};
  T_ACI_PB_STOR   stor;
  SHORT           used;
  SHORT           total;
  SHORT           i;

  TRACE_FUNCTION("queatPlusCPBS()");

  ret = qAT_PlusCPBS(srcId,&stor,&used,&total);
  if (ret EQ AT_CMPL)
  {
    for(i=0;phb_mem_names[i].name NEQ NULL;i++)
    {
      if (phb_mem_names[i].stor EQ stor)
      {
        sprintf(g_sa,"+CPBS: \"%s\",%d,%d",phb_mem_names[i].name,used,total);
        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
        break;
      }
    }
  }
  else 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 : queatPercentCPBS   |
+--------------------------------------------------------------------+

  PURPOSE : %CPBS (Phonebook memory storage)
*/
GLOBAL T_ATI_RSLT queatPercentCPBS(char *cl, UBYTE srcId)
{
#ifdef  FF_ATI_BAT

  T_BAT_cmd_send cmd;
  T_BAT_no_parameter dummy;

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

  cmd.ctrl_params=BAT_CMD_QUE_PERCENT_CPBS;
  dummy.bat_dummy=0xFF;
  cmd.params.ptr_que_percent_cpbs=&dummy;
 
  bat_send(ati_bat_get_client(srcId),&cmd);

  /*
  *   Return value indicates executing, the response will come via
  *   the callback function.
  */
  return(ATI_EXCT);

#else /* FF_ATI_BAT */

  char *me="%CPBS: ";
  T_ACI_RETURN    ret;
  T_ACI_PB_STOR   stor;
  SHORT used,total,first,i;

  TRACE_FUNCTION("queatPercentCPBS()");

  /*
  *   Call the corresponding ACI function.
  */
  ret=qAT_PercentCPBS(srcId,&stor,&used,&total,&first);

  /*
  *   If the query completes successfully, build and send the
  *   answer.
  */
  if (ret EQ AT_CMPL)
  {
    /*
    *   Run through the list of names to get the name of the
    *   currently selected phonebook.
    */
    for(i=0;phb_mem_names[i].name NEQ NULL;i++)
    {
      if (phb_mem_names[i].stor EQ stor)
      {
        sprintf(g_sa,"%s\"%s\",%d,%d,%d",me,phb_mem_names[i].name,used,total,first);
        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
        break;
      }
    }
  }

  return (map_aci_2_ati_rslt(ret));

#endif /* FF_ATI_BAT */
}

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

  PURPOSE : +CPBW (Write Phonebook entry)
*/
GLOBAL T_ATI_RSLT setatPlusCPBW(char *cl, UBYTE srcId)
{
#ifndef TI_PS_FFS_PHB
  UBYTE          pb_status;
#endif
  char           *me                      = "+CPBW: ";
  T_ACI_RETURN    ret = AT_FAIL;
  CHAR           *p_number                = NULL;
  CHAR            text    [MAX_ALPHA_LEN * 4] = {0x00};
  USHORT          lenText                 = 0;
  T_ACI_TOA      *p_toa                   = NULL,
                  type;

  SHORT           toa_val                 = 0,
                  index                   = -1;
#ifndef  FF_ATI_BAT
  T_ACI_PB_TEXT  *p_text                  = NULL;
  T_ACI_PB_TEXT   cvtdText;
  USHORT          lenCvtd                 = 0;
  T_ACI_VP_ABS    dmyDateTime;
#endif /* !FF_ATI_BAT */

  T_ACI_PB_STOR   stor;
  SHORT           used;
  SHORT           total;
  CHAR            numBuf[MAX_PHB_NUM_LEN];
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  memset( numBuf, 0, sizeof(numBuf));

  TRACE_FUNCTION("setatPlusCPBW()");


  ret = qAT_PlusCPBS(srcId,&stor,&used,&total);
  TRACE_EVENT_P1("Current phonebook storage: %d", stor);

#ifdef TI_PS_FFS_PHB
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }
#endif
  
  if (ret EQ AT_CMPL    AND 
      stor EQ PB_STOR_Ed)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }

  if ( ati_user_output_cfg[srcId].cscsChset EQ CSCS_CHSET_Gsm)
  {
    cl=parse(cl,"rsrz",
              &index,
              (LONG)MAX_PHB_NUM_LEN,
              numBuf,
              &toa_val,
              (LONG)MAX_ALPHA_LEN,
              strlen(cl),
              cl,
              &lenText,
              text);
  }
  else
  {
    cl=parse(cl,"rsrz",
              &index,
              (LONG)MAX_PHB_NUM_LEN,
              numBuf,
              &toa_val,
              (LONG)MAX_ALPHA_LEN * 4,
              strlen(cl),
              cl,
              &lenText,
              text);
  }

  if(!cl)
  {
    TRACE_ERROR("ERROR: parsing failed !!!");
    index = get_parse_index();       /* get the problematic component */
    switch (index)
    {
      case 2:   /* component 2 is the number */
        cmdCmeError(CME_ERR_DialToLong);
        break;
      case 4:   /* component 4 is the alpha tag */
        cmdCmeError(CME_ERR_TxtToLong);
        break;
      default:
        cmdCmeError(CME_ERR_OpNotAllow);
        break;
    }
    return ATI_FAIL;
  }
  
#ifndef TI_PS_FFS_PHB
   /* If the phonebook status is not PHB_READY then SIM BUSY error is indicated to the user.*/
  pb_status_req(&pb_status); /* get phone book status */

  TRACE_EVENT_P1("Current phonebook status: %d", pb_status);
  if (pb_status NEQ PHB_READY)
  {
    if(pb_status EQ PHB_BUSY)
    {
      TRACE_EVENT("Error: Phonebook is busy accessing the SIM");
      cmdCmeError(CME_ERR_SimBusy);
    }
    else if(pb_status EQ PHB_UNKNOWN)
    {
      TRACE_EVENT("Error: Phonebook status unknown");
      cmdCmeError(CME_ERR_Unknown);
    }
    return ATI_FAIL;
  }
#endif /* TI_PS_FFS_PHB */

  if( index > total) /* phonebook index is greater than max. */
  {                  /* possible index of SIM                */
    TRACE_EVENT("Error: phonebook index is greater than max possible index of SIM");
    cmdCmeError(CME_ERR_InvIdx);
    return ATI_FAIL;
  }

  if (toa_val > 0)
  {
    type=toa_demerge(toa_val);
    p_toa=&type;
  }
  else
    p_toa=NULL;

  if (numBuf[0] EQ '\0')
    p_number=NULL;
  else
    p_number=numBuf;

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cpbw my_bat_set_plus_cpbw = {0};
    T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

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

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CPBW;
    cmd.params.ptr_set_plus_cpbw = &my_bat_set_plus_cpbw;

    my_bat_set_plus_cpbw.index = (S16)index;

    /* Load the phone number in BAT struct - if there is one */
    if (p_number)
    {
      if (strlen(p_number)>BAT_MAX_CPBW_NUMBER_LEN)
      {
        /*
        *   If the number is too big for the BAT structure we can't do
        *   anything meaningful, so get out now.
        */
        cmdCmeError(CME_ERR_Unknown);
        return ATI_FAIL;
      }

      my_bat_set_plus_cpbw.c_number = strlen(p_number);
      my_bat_set_plus_cpbw.v_number = TRUE;
      memcpy(my_bat_set_plus_cpbw.number, p_number,BAT_MAX_CPBW_NUMBER_LEN);
    }
    else
    {
      my_bat_set_plus_cpbw.v_number = FALSE;
    }
    
    /*
    *   Load the associated text in BAT struct - if there is any
    */
    if ((lenText EQ 0) AND (p_number EQ NULL))
    {
      my_bat_set_plus_cpbw.v_text = FALSE;
    }
    else
    {
      /*
      *   If the associated text is too big for the BAT structure it
      *   will be truncated.
      */
      if (lenText>BAT_MAX_CPBW_TEXT_LEN)
        my_bat_set_plus_cpbw.c_text = BAT_MAX_CPBW_TEXT_LEN;
      else
        my_bat_set_plus_cpbw.c_text = (U8)lenText;

      my_bat_set_plus_cpbw.v_text = TRUE;
      memcpy(my_bat_set_plus_cpbw.text, text, BAT_MAX_CPBW_TEXT_LEN);
    }

    /* Load type as string input */
    if (p_toa)
      my_bat_set_plus_cpbw.type = (S16)toa_val;
    else
      my_bat_set_plus_cpbw.type = (S16)-1;

    src_params->curAtCmd = AT_CMD_CPBW;
    srcId_cb = srcId;
    bat_send(ati_bat_get_client(srcId), &cmd);
 
    return ATI_EXCT; /* executing, because response is passed by callback function */
  }

#else /* no FF_ATI_BAT */

  if( lenText NEQ 0 )
  {
    srcId_cb = srcId;
    utl_chsetToSim ((UBYTE*)text, lenText, (UBYTE*)cvtdText.data,
                    &lenCvtd, GSM_ALPHA_Def);
  }
  cvtdText.cs = CS_Sim;

  /* when the text and the number are both empty, set p_text to NULL */
  if (lenCvtd EQ 0 AND p_number EQ NULL)
  {
    p_text = NULL;
  }
  else
  {
    p_text = &cvtdText;
    cvtdText.len = (UBYTE)lenCvtd;
  }

  ret = sAT_PlusCPBW(srcId, index, p_number, p_toa, p_text, &dmyDateTime);
  switch (ret)
  {
    case AT_FAIL:
      switch (ACI_ERR_DESC_CLASS( aciErrDesc ))
      {
        case ACI_ERR_CLASS_Cme:
          cmdCmeError( ACI_ERR_DESC_NR( aciErrDesc ) );
          break;
        case ACI_ERR_CLASS_Cms:
        case ACI_ERR_CLASS_Ceer:
        case ACI_ERR_CLASS_Ext:
        default:
          cmdCmeError(CME_ERR_Unknown);
          break;
      }
      break;
    case AT_EXCT:
      src_params->curAtCmd = AT_CMD_CPBW;
      break;

    case AT_BUSY:
      cmdCmeError(CME_ERR_SimBusy);
      break;
  }
  return (map_aci_2_ati_rslt(ret));
#endif /* no FF_ATI_BAT */
}

GLOBAL T_ATI_RSLT tesatPlusCPBW(char *cl, UBYTE srcId)
{
#ifdef FF_ATI_BAT

  T_BAT_cmd_send cmd;
  T_BAT_no_parameter dummy;

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

  cmd.ctrl_params = BAT_CMD_TST_PLUS_CPBW;
  dummy.bat_dummy = 0xFF;
  cmd.params.ptr_tst_plus_cpbw = &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           *me                      = "+CPBW: ";
  T_ACI_RETURN    ret = AT_FAIL;
  CHAR           *p_number                = NULL;
  CHAR            text    [MAX_ALPHA_LEN] = {0x00};
  USHORT          lenText                 = 0;
  USHORT          lenCvtd                 = 0;
  T_ACI_PB_TEXT  *p_text                  = NULL;
  T_ACI_TOA      *p_toa                   = NULL;

  SHORT           toa_val                 = 0,
                  index                   = -1,
                  first_idx,
                  last_idx;
  UBYTE           nlength,
                  tlength;
  CHAR            numBuf[MAX_PHB_NUM_LEN];

  memset( numBuf, 0, sizeof(numBuf));

  TRACE_FUNCTION("tesatPlusCPBW()");

  ret = tAT_PlusCPBW(srcId,&first_idx,&last_idx,&nlength,&tlength);
  if(ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s(%d-%d),%d,%s,%d",me,first_idx,last_idx,nlength,"(128-201)",tlength);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  else
  {
    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 : atPlusCPBR         |
+--------------------------------------------------------------------+

  PURPOSE : +CPBR (Read Phonebook Entry)
*/

GLOBAL T_ATI_RSLT setatPlusCPBR(char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  CHAR         cvtdText[4*MAX_ALPHA_LEN]  = {0x00};  /* need enough space for UCS2 strings */
  USHORT       lenCvtdText                = 0;
  USHORT       pos                        = 0;
  SHORT        toa_val                    = 0,
               index1                     = ACI_NumParmNotPresent,
               index2                     = ACI_NumParmNotPresent,
               last_idx                   = ACI_NumParmNotPresent;
#ifndef  FF_ATI_BAT
  SHORT        i;
  T_ACI_PB_LST pblst;
  UBYTE        type;
#endif /* !FF_ATI_BAT */

  TRACE_FUNCTION("setatPlusCPBR()");

  cl = parse(cl,"rr",&index1,&index2);
  if(!cl OR index1 > MAX_PB_INDEX OR index1 < 0 OR index2 > MAX_PB_INDEX)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  if(index2 EQ ACI_NumParmNotPresent)
  {
    index2=index1;
  }

#ifdef FF_ATI_BAT

  if (last_idx EQ ACI_NumParmNotPresent OR last_idx < index2)
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cpbr my_bat_set_plus_cpbr = {0};
    T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
    
    TRACE_FUNCTION("setatPlusCPBR() calls bat_send() <=== as APPLICATION");

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CPBR;
    cmd.params.ptr_set_plus_cpbr = &my_bat_set_plus_cpbr;

    my_bat_set_plus_cpbr.index1 = (U8)index1;
    my_bat_set_plus_cpbr.index2 = (S16)index2;

    src_params->curAtCmd = AT_CMD_CPBR;
    srcId_cb = srcId;
    bat_send(ati_bat_get_client(srcId), &cmd);

    return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* no FF_ATI_BAT */

  while (last_idx EQ ACI_NumParmNotPresent OR last_idx < index2)
  {
    ret = sAT_PlusCPBR(srcId,index1,index2,&last_idx,&pblst[0]);
    if (ret EQ AT_CMPL)
    {
      for ( i = 0;
            i < MAX_PB_ENTR AND pblst[i].index NEQ ACI_NumParmNotPresent;
            i++ )
      {
        type = toa_merge(pblst[i].type);

        pos=sprintf(g_sa,"+CPBR: %d,\"%s\",%d,",
                                         pblst[i].index,
                                         pblst[i].number,
                                         type);
         
        srcId_cb = srcId;
        utl_chsetFromSim((UBYTE*)pblst[i].text.data,
                         pblst[i].text.len,
                         (UBYTE*)cvtdText,
                         sizeof(cvtdText),
                         &lenCvtdText,
                         GSM_ALPHA_Def);

        pos+=sprints(g_sa+pos,cvtdText,lenCvtdText);
        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
      }
      index1=last_idx+1;
    }
    else
    {
      cmdCmeError(CME_ERR_Unknown);
      return ATI_FAIL;
    }
  }
#endif /* no FF_ATI_BAT */

  return (map_aci_2_ati_rslt(ret));
}

GLOBAL T_ATI_RSLT tesatPlusCPBR(char *cl, UBYTE srcId)
{
#ifdef FF_ATI_BAT

  T_BAT_cmd_send cmd;
  T_BAT_no_parameter dummy;

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

  cmd.ctrl_params = BAT_CMD_TST_PLUS_CPBR;
  dummy.bat_dummy = 0xFF;
  cmd.params.ptr_tst_plus_cpbr = &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 */

  T_ACI_RETURN ret = AT_FAIL;
  SHORT        first_idx,
               last_idx                   = ACI_NumParmNotPresent;
  UBYTE        nlength,
               tlength;

  TRACE_FUNCTION("tesatPlusCPBR()");

  ret = tAT_PlusCPBR(srcId,&first_idx,&last_idx,&nlength,&tlength);
  if(ret EQ AT_CMPL)
  {
    sprintf(g_sa,"+CPBR: (%d-%d),%d,%d",first_idx,last_idx,nlength,tlength);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  else
  {
    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 : atPlusCPBF         |
+--------------------------------------------------------------------+

  PURPOSE : +CPBF (Find Text in Phonebook)
*/

GLOBAL T_ATI_RSLT setatPlusCPBF(char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_ACI_RETURN ret = AT_FAIL;
  CHAR         cvtdFindstr[MAX_ALPHA_LEN]    = {0x00};
  USHORT       lenCvtdFindstr                = 0;
  CHAR         cvtdText   [2*MAX_ALPHA_LEN]  = {0x00};
  USHORT       lenCvtdText                   = 0;
  USHORT       pos                           = 0;

  SHORT        toa_val                       = 0,
               i,
               j,
               index1                        = -1;
  SHORT        found;
  T_ACI_PB_LST pblst;
  UBYTE        type;
  SHORT        Size_Max;
  SHORT        extra_char;

#ifdef NO_ASCIIZ
  T_ACI_PB_TEXT pbText;
#endif /* #ifdef NO_ASCIIZ */
 
#endif /* FF_ATI_BAT */

  CHAR         findstr    [MAX_ALPHA_LEN]    = {0x00};
  USHORT       lenFindstr                    = 0;

  TRACE_FUNCTION("setatPlusCPBF()");

  cl=parse(cl,"z",
              (LONG)MAX_ALPHA_LEN,
              strlen(cl),
              cl,
              &lenFindstr,
              findstr);
  if(!cl OR lenFindstr EQ 0)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  srcId_cb = srcId;
  
#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cpbf cpbf;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CPBF;
    cmd.params.ptr_set_plus_cpbf=&cpbf;

    /*
    *   Check that the string isn't too long for the BAT message.
    */
    if (lenFindstr>BAT_MAX_CPBF_FIND_TEXT_LEN)
    {
      cmdCmeError(CME_ERR_Unknown);
      return ATI_FAIL;
    }

    cpbf.c_findtext=(U8)lenFindstr;
    memcpy(cpbf.findtext,findstr,lenFindstr);

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

#ifdef NO_ASCIIZ
  utl_chsetToSim ( (UBYTE*)findstr,
                   lenFindstr,
                   pbText.data,
                   &lenCvtdFindstr,
                   GSM_ALPHA_Def );

  pbText.cs = CS_Sim;
  pbText.len = (UBYTE)lenCvtdFindstr;

  ret = sAT_PlusCPBF( srcId, &pbText, CPBF_MOD_NewSearch,
                      &found, &pblst[0] );
#else  /* #ifdef NO_ASCIIZ */
  utl_chsetToGsm ( (UBYTE*)findstr,
                   lenFindstr,
                   (UBYTE*)cvtdFindstr,
                   &lenCvtdFindstr,
                   GSM_ALPHA_Int );

  ret = sAT_PlusCPBF( srcId, cvtdFindstr, CPBF_MOD_NewSearch,
                      &found, &pblst[0] );
#endif /* #ifdef NO_ASCIIZ */
  if (ret EQ AT_CMPL)
  {
    extra_char = 8;
    Size_Max = KEY + SHORT_LTH + MAX_PHB_NUM_LEN +
               BYTE_LTH + 2*MAX_ALPHA_LEN + extra_char;

    i=0;
    while(i<MAX_PB_ENTR AND i < found)
    {
      type = toa_merge(pblst[i].type);

      pos=sprintf(g_sa,"+CPBF: %d,\"%s\",%d,",
                                         pblst[i].index,
                                         pblst[i].number,
                                         type);
      utl_chsetFromSim((UBYTE*)pblst[i].text.data,
                       pblst[i].text.len,
                       (UBYTE*)cvtdText,
                       sizeof(cvtdText),
                       &lenCvtdText,
                       GSM_ALPHA_Def);
      pos+=sprints(g_sa+pos,cvtdText,lenCvtdText);
      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
      i++;
    }
    if (found > MAX_PB_ENTR)
    {
      while(i < found)
      {
#ifdef NO_ASCIIZ
        ret = sAT_PlusCPBF( srcId, &pbText,
                            CPBF_MOD_NextSearch, &found, &pblst[0] );
#else  /* #ifdef NO_ASCIIZ */
        ret = sAT_PlusCPBF( srcId, cvtdFindstr,
                            CPBF_MOD_NextSearch, &found, &pblst[0] );
#endif /* #ifdef NO_ASCIIZ */
        if (ret EQ AT_CMPL)
        {
          for(j=0;j < MAX_PB_ENTR AND i < found;j++)
          {
            type = toa_merge(pblst[j].type);

            pos=sprintf(g_sa,"+CPBF: %d,\"%s\",%d,",
                                             pblst[j].index,
                                             pblst[j].number,
                                             type);
            utl_chsetFromGsm((UBYTE*)pblst[j].text.data,
                             pblst[j].text.len,
                             (UBYTE*)cvtdText,
                             sizeof(cvtdText),
                             &lenCvtdText,
                             GSM_ALPHA_Def);
            pos+=sprints(g_sa+pos,cvtdText,lenCvtdText);
            io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
            i++;
          }
        }
        else
        {
          i = found; /* Ensure at least termination of loop */
        }
      }
    }
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  return (map_aci_2_ati_rslt(ret));
  
#endif /* no FF_ATI_BAT */  
}

GLOBAL T_ATI_RSLT tesatPlusCPBF(char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_ACI_RETURN ret = AT_FAIL;
  UBYTE        nlength,
               tlength;
#endif

  TRACE_FUNCTION("tesatPlusCPBF()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

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

  ret = tAT_PlusCPBF(srcId,&nlength,&tlength);
  if(ret EQ AT_CMPL)
  {
    resp_disp(srcId, cl,"bb",&nlength,&tlength);
  }
  else
  {
    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 : atPlusCSVM         |
+--------------------------------------------------------------------+

  PURPOSE : +CSVM command (Set Voice Mail Number )
*/

GLOBAL T_ATI_RSLT setatPlusCSVM (char *cl, UBYTE srcId)
{

  T_ACI_CSVM_MOD mode = CSVM_MOD_NotPresent;
  T_ACI_RETURN   ret = AT_FAIL;
  T_ACI_TOA      type;
  SHORT          toa_val=0;
  CHAR           numBuf[MAX_CC_ORIG_NUM_LEN];

  TRACE_FUNCTION("setatPlusCSVM()");

  memset( numBuf, 0, sizeof(numBuf));

  cl=parse(cl,"dsr",&mode,(LONG)MAX_CC_ORIG_NUM_LEN,
           numBuf,&toa_val);

  if(!cl)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  if ( mode EQ CSVM_MOD_Enable AND
       numBuf[0] EQ '\0' OR
       toa_val < 0)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  if(toa_val NEQ 0)
  {
    type=toa_demerge(toa_val);
  }
  else
  {
    cmh_setToaDef(numBuf,&type);
  }
  

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_csvm csvm;
    UBYTE len;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CSVM;
    cmd.params.ptr_set_plus_csvm=&csvm;

    len=strlen(numBuf);

    csvm.mode=(T_BAT_plus_csvm_mode)mode;
    
    if ((len) && (len<=BAT_MAX_CSVM_NUMBER_LEN))
    {
      csvm.v_number=TRUE;      
      csvm.c_number=(U8)len;
      memcpy(csvm.number,numBuf,len);
    }
    else
    {
      csvm.v_number=FALSE;      
    }
    csvm.type=(S16)toa_val;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

  ret = sAT_PlusCSVM(srcId, mode, numBuf, (UBYTE)strlen(numBuf), &type);

  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 queatPlusCSVM (char *cl, UBYTE srcId)
{
  T_ACI_CSVM_MOD mode=CSVM_MOD_NotPresent;
  T_ACI_RETURN   ret = AT_FAIL;
  SHORT          toa_val=0;
  CHAR           numBuf[MAX_CC_ORIG_NUM_LEN];

  TRACE_FUNCTION("queatPlusCSVM()");

  memset( numBuf, 0, sizeof(numBuf));

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

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

  ret = qAT_PlusCSVM(srcId, &mode, numBuf, sizeof(numBuf), &toa_val);
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
  }
  else
  {
    sprintf(g_sa,"+CSVM: %d,\"%s\",%d",mode,numBuf,toa_val);
    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 : atPlusCLAN         |
+--------------------------------------------------------------------+

  PURPOSE : +CLAN command (Set language)
*/

GLOBAL T_ATI_RSLT setatPlusCLAN (CHAR *cl, UBYTE srcId)
{
  T_ACI_RETURN    ret = AT_FAIL;
  CHAR            lng_str[CLAN_CODE_LEN+1]={0};
  SHORT           i;
  T_ACI_LAN_SUP   lngCde;
  CHAR            *auptr="au";
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCLAN()");

  cl = parse(cl,"s",(LONG)3,lng_str);
  if(!cl OR *lng_str EQ '\0')
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  if (strcmp(lng_str, auptr))
  {
    for(i=0;lngs[i].str NEQ 0;i++)
    {
      if (!strcmp(lngs[i].str,lng_str))
      {
        lngCde.str=lngs[i].str;
        lngCde.lng=lngs[i].lng;
       break;
      }
    }
    if(lngs[i].str EQ 0)
    {
      cmdCmeError(CME_ERR_OpNotSupp);
      return ATI_FAIL;
    }
  }
  else
  {
    lngCde.str = lng_str;
    lngCde.lng = CLAN_LNG_AUT;
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_clan clan;
    UBYTE len;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CLAN;
    cmd.params.ptr_set_plus_clan=&clan;

    len=strlen(lng_str);

    if (len>BAT_MAX_CLAN_CODE_LEN)
    {
      cmdCmeError(CME_ERR_Unknown);
      return ATI_FAIL;
    }

    memcpy(clan.code,lng_str,len);
    clan.c_code=(U8)len;
    bat_send(ati_bat_get_client(srcId), &cmd);
    src_params->curAtCmd=AT_CMD_CLAN;
    return(ATI_EXCT);
  }

#else /* no FF_ATI_BAT */

  ret = sAT_PlusCLAN(srcId,&lngCde);
  if (ret EQ AT_EXCT)
  {
    src_params->curAtCmd    = AT_CMD_CLAN;
  }
  else 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 queatPlusCLAN(char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  CHAR            *me="+CLAN: ";
  T_ACI_RETURN    ret = AT_FAIL;
  T_ACI_LAN_SUP   lngCde;
  CHAR            lang_buffer[3]; /* 2 chars for language + 0 terminated string */
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
#endif

  TRACE_FUNCTION("queatPlusCLAN()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

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

  /* to be sure that last cipher is 0 (string)*/
  memset(lang_buffer, 0, sizeof(lang_buffer));
  lngCde.str = lang_buffer;

  ret = qAT_PlusCLAN(srcId, &lngCde);
  switch(ret)
  {
  case(AT_CMPL):
    sprintf(g_sa,"%s%s", me, lngCde.str);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    break;

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

  case(AT_BUSY):
    cmdCmeError(CME_ERR_SimBusy);
    break;

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

#endif /* no FF_ATI_BAT */
}

GLOBAL T_ATI_RSLT tesatPlusCLAN (CHAR *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char          *me="+CLAN: ";
  T_ACI_RETURN  ret = AT_FAIL;
  T_ACI_LAN_SUP lnglst[MAX_LAN];
  SHORT         lastIdx;
  UBYTE         i;
  SHORT         pos;
#endif

  TRACE_FUNCTION("tesatPlusCLAN()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

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

  ret = tAT_PlusCLAN(srcId, &lastIdx, &lnglst[0] );
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }

  pos=sprintf(g_sa,"%s",me);

  for(i=0;i<lastIdx;i++)
  {
    pos += sprintf(g_sa+pos,"%s,",lnglst[i].str);
  }

  g_sa[pos-1] = '\0';
  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 : setatPercentPBCF   |
+--------------------------------------------------------------------+

  PURPOSE : %PBCF command (Set phonebook configuration)
*/

GLOBAL T_ATI_RSLT setatPercentPBCF (CHAR *cl, UBYTE srcId)
{
  T_ACI_PBCF_LDN ldn = PBCF_LDN_NotPresent;
  T_ACI_PBCF_LRN lrn = PBCF_LRN_NotPresent;
  T_ACI_PBCF_LMN lmn = PBCF_LMN_NotPresent;
  T_ACI_RETURN ret = AT_FAIL;

  cl = parse (cl, "ddd", &ldn, &lrn, &lmn);

  /*lint -e685 always evaluates to false*/
  if (!cl OR
      ldn < PBCF_LDN_NotPresent OR ldn > PBCF_LDN_Disable OR
      lrn < PBCF_LRN_NotPresent OR lrn > PBCF_LRN_Disable OR
      lmn < PBCF_LMN_NotPresent OR lmn > PBCF_LMN_Disable)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ATI_FAIL;
  }
  
#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_pbcf pbcf;
    T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

    TRACE_FUNCTION("setatPercentPBCF() calls bat_send() <=== as APPLICATION");
    
    cmd.ctrl_params = BAT_CMD_SET_PERCENT_PBCF;
    cmd.params.ptr_set_percent_pbcf=&pbcf;

    pbcf.ldn = (T_BAT_percent_pbcf_ldn)ldn;
    pbcf.lrn = (T_BAT_percent_pbcf_lrn)lrn;
    pbcf.lmn = (T_BAT_percent_pbcf_lmn)lmn;
    
    bat_send(ati_bat_get_client(srcId), &cmd);
    src_params->curAtCmd=AT_CMD_P_PBCF;
    return(ATI_EXCT);
  }

#else /* FF_ATI_BAT */
  TRACE_FUNCTION("setatPercentPBCF()");

  ret = sAT_PercentPBCF(srcId, ldn, lrn, lmn);
  
  if(ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }
  
  return (map_aci_2_ati_rslt(ret));

#endif /* FF_ATI_BAT */
}


GLOBAL T_ATI_RSLT queatPercentPBCF (CHAR *cl, UBYTE srcId)
{
#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

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

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_PBCF;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_pbcf = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
  
#else /* FF_ATI_BAT */
  CHAR *me = "%PBCF: ";
  T_ACI_PBCF_LDN ldn = PBCF_LDN_NotPresent;
  T_ACI_PBCF_LRN lrn = PBCF_LRN_NotPresent;
  T_ACI_PBCF_LMN lmn = PBCF_LMN_NotPresent;

  TRACE_FUNCTION("queatPercentPBCF()");

  qAT_PercentPBCF (srcId, &ldn, &lrn, &lmn);

  sprintf (g_sa, "%s%d, %d, %d", me, ldn, lrn, lmn);
  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

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

#endif /* ATI_PHB_C */