/* 
+----------------------------------------------------------------------------- 
|  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 */
