/*
+-----------------------------------------------------------------------------
|  Project :
|  Modul   :
+-----------------------------------------------------------------------------
|  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 :  GPRS AT Command Handler.
+-----------------------------------------------------------------------------
*/

#if defined (GPRS) && defined (DTI)

#ifndef GACI_CMD_C
#define GACI_CMD_C
#endif

#undef DUMMY_ATI_STRINGS

#include "aci_all.h"

/*includes*/
#include "dti.h"      /* functionality of the dti library */
#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_io.h"
#include "aci_cmd.h"
#include "aci_lst.h"
#include "l4_tim.h"

#include "gdi.h"
#include "audio.h"
#include "p_sim.h"
#include "p_aci.h"
#include "aoc.h"
#include "aci.h"
#include "pcm.h"
#include "rx.h"
#include "pwr.h"

#include "dti_conn_mng.h"
#include "dti_cntrl_mng.h"

#include "gaci.h"
#include "gaci_cmh.h"
#include "psa.h"
#include "psa_sm.h"

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

#include "cmh.h"
#include "cmh_sm.h"

#include "aci_io.h"
#include "aci_mem.h"

#if defined(FF_WAP) OR defined (FF_GPF_TCPIP)  || defined (FF_SAT_E)
#include "gaci_srcc.h"
#include "psa_tcpip.h"
#include "wap_aci.h"
#endif /* defined(WAP) OR defined (FF_GPF_TCPIP)  || defined (FF_SAT_E)*/

#include "gaci_cmd.h"
#include "aci_prs.h"

#include "ati_int.h"

#include "dcm_f.h"

#ifdef FF_ATI_BAT

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

#include "ati_bat.h"

#endif /*FF_ATI_BAT*/

EXTERN char       *cmdErrStr;
EXTERN T_ACI_LIST *ati_src_list;

GLOBAL T_ATI_RSLT setatPlusCGDCONT (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGQREQ  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGQMIN  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGATT   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGACT   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGDATA  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGPADDR (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGAUTO  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGANS   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGCLASS (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGEREP  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGREG   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPlusCGSMS   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT setatPercentCGEREP  (char *cl, UBYTE srcId);

GLOBAL T_ATI_RSLT queatPlusCGDCONT (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGQREQ  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGQMIN  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGATT   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGACT   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGAUTO  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGCLASS (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGEREP  (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGREG   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPlusCGSMS   (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPercentCGEREP  (char *cl, UBYTE srcId);

GLOBAL T_ATI_RSLT tesatPlusCGDCONT (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT tesatPlusCGPADDR (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT tesatPlusCGSMS   (char *cl, UBYTE srcId);

GLOBAL T_ATI_RSLT atGD (char *cl, UBYTE srcId, BOOL *gprs_command);

GLOBAL T_ATI_RSLT setatPercentCGAATT (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPercentCGAATT (char *cl, UBYTE srcId);

GLOBAL T_ATI_RSLT setatPercentCGREG (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPercentCGREG (char *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPercentCGPCO (UBYTE srcId,USHORT cid);
GLOBAL T_ATI_RSLT setatPercentCGCLASS (CHAR *cl, UBYTE srcId);
GLOBAL T_ATI_RSLT queatPercentCGCLASS (CHAR *cl, UBYTE srcId);
/*
+------------------------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD                           |
| STATE   : finnished                   ROUTINE : gaci_ati_cmd_init_each_source      |
+------------------------------------------------------------------------------------+

  PURPOSE : initialize GACI relevant ATI parameters.
*/

GLOBAL void gaci_ati_cmd_init_each_source( UBYTE srcId )
{
  /* init +CGREG param */
  ati_creg_init(srcId, PlusCGREG_CMD);

  /* init %CGREG param */
  ati_creg_init(srcId, PercentCGREG_CMD);

  /* init %CGEREP param */
  ati_user_output_cfg[srcId].Percent_CGEREP_stat = 0;
  ati_user_output_cfg[srcId].CGEREP_mode = 0;
  ati_user_output_cfg[srcId].CGEREP_bfr = 0;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finnished                   ROUTINE : atPlusCGDCONT      |
+--------------------------------------------------------------------+

  PURPOSE : +CGDCONT  command ( PDP context definition )
*/

#define MAGIC_EMPTY_APN "\x0ff"

GLOBAL T_ATI_RSLT setatPlusCGDCONT  (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  T_GPRS_CONT_REC inputCtxt = {MAGIC_EMPTY_APN,
                               "",
                               "",
                               CGDCONT_D_COMP_OMITTED,
                               CGDCONT_H_COMP_OMITTED,
                               {GPRS_QOS_OMITTED, GPRS_QOS_OMITTED, GPRS_QOS_OMITTED, GPRS_QOS_OMITTED, GPRS_QOS_OMITTED},
                               {GPRS_QOS_OMITTED, GPRS_QOS_OMITTED, GPRS_QOS_OMITTED, GPRS_QOS_OMITTED, GPRS_QOS_OMITTED} };
  SHORT cid = GPRS_CID_OMITTED;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGDCONT ()");

  cl=parse(cl,"rsssrr",&cid
                      ,(LONG)MAX_PDP_TYPE_LEN,  inputCtxt.pdp_type
                      ,(LONG)MAX_APN_LEN,       inputCtxt.apn
                      ,(LONG)MAX_PDP_ADDR_LEN,  inputCtxt.pdp_addr
                      ,&inputCtxt.d_comp
                      ,&inputCtxt.h_comp);

  if (!strcmp(inputCtxt.apn, MAGIC_EMPTY_APN))
  {
    /* if APN was ommitted then parse leaves the string untouched */
    inputCtxt.apn[0]='\0';    /* so clear the apn */
  }
  else if (inputCtxt.apn[0] EQ '\0')
  {
    /* if entered APN was "", parse clears the buffer */
    strcpy(inputCtxt.apn, MAGIC_EMPTY_APN);  /* fill magic empty apn */
  }

  if ( !cl )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgdcont cgdcont;
    UBYTE len;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGDCONT;
    cmd.params.ptr_set_plus_cgdcont=&cgdcont;

    cgdcont.cid=(T_BAT_pdp_cid)cid;

    if (utl_strcasecmp((const char *)inputCtxt.pdp_type, (const char *)"ip"))
      cgdcont.pdp_type=BAT_PDP_TYPE_NOT_PRESENT;
    else
      cgdcont.pdp_type=BAT_PDP_TYPE_IPV4;

    len=strlen(inputCtxt.apn);

    if (len<=BAT_MAX_APN_LEN)
    {
      cgdcont.v_apn=TRUE;
      cgdcont.c_apn=(U8)len;
      memcpy(cgdcont.apn,inputCtxt.apn,len);
    }
    else
    {
      cgdcont.v_apn=FALSE;
    }

    len=strlen(inputCtxt.pdp_addr);

    if (len<=BAT_MAX_PDP_ADD)
    {
      cgdcont.v_pdp_addr=TRUE;
      cgdcont.c_pdp_addr=(U8)len;
      memcpy(cgdcont.pdp_addr,inputCtxt.pdp_addr,len);
    }
    else
    {
      cgdcont.v_pdp_addr=FALSE;
    }

    cgdcont.d_comp=(T_BAT_plus_cgdcont_d_comp)inputCtxt.d_comp;
    cgdcont.h_comp=(T_BAT_plus_cgdcont_h_comp)inputCtxt.h_comp;

    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  ret = sAT_PlusCGDCONT (srcId, cid ,&inputCtxt);
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGDCONT;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif
}

GLOBAL T_ATI_RSLT queatPlusCGDCONT  (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGDCONT: ";
  T_ACI_RETURN ret = AT_FAIL;
  T_GPRS_CONT_REC defCtxts[MAX_CID_PLUS_EINS];
  SHORT cid_array[MAX_CID_PLUS_EINS];
  int i = 0, pos = 0, pos2 = 0;
#endif

  TRACE_FUNCTION("queatPlusCGDCONT ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGDCONT;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgdcont = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret = qAT_PlusCGDCONT (srcId, &defCtxts, cid_array);
  if (ret EQ AT_CMPL)
  {
    for ( i = 0; i < MAX_CID && cid_array[i] NEQ INVALID_CID; i++ )
    {
      if (!strcmp(defCtxts[i].apn, MAGIC_EMPTY_APN))      /* special empty APN detected, printout "" */
      {
        sprintf(g_sa,"%s%hd,\"%s\",\"\",\"%s\",%hd,%hd",
          me,
          cid_array[i],
          defCtxts[i].pdp_type,
/*        defCtxts[i].apn,      */
          defCtxts[i].pdp_addr,
          defCtxts[i].d_comp,
          defCtxts[i].h_comp    );
      }

      else if (defCtxts[i].apn[0] == '\0')
      {                                                   /* no APN defined, printout nothing */
        sprintf(g_sa,"%s%hd,\"%s\",,\"%s\",%hd,%hd",
          me,
          cid_array[i],
          defCtxts[i].pdp_type,
/*        defCtxts[i].apn,      */
          defCtxts[i].pdp_addr,
          defCtxts[i].d_comp,
          defCtxts[i].h_comp    );
      }
      else
      {                                                   /* normal, printout the "apn" */
        sprintf(g_sa,"%s%hd,\"%s\",\"%s\",\"%s\",%hd,%hd",
          me,
          cid_array[i],
          defCtxts[i].pdp_type,
          defCtxts[i].apn,
          defCtxts[i].pdp_addr,
          defCtxts[i].d_comp,
          defCtxts[i].h_comp    );
      }
      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    }
    return (ATI_CMPL);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}


GLOBAL T_ATI_RSLT tesatPlusCGDCONT  (char *cl, UBYTE srcId)
{
  char *me="+CGDCONT: ";

  sprintf(g_sa,"%s(1-%d),\"IP\",,,(0),(0,1)",
                              me, MAX_CID );

  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  return (ATI_CMPL);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finnished                   ROUTINE : atPlusCGQREQ       |
+--------------------------------------------------------------------+

  PURPOSE : +CGQREQ  command (context QOS request)
*/

GLOBAL T_ATI_RSLT setatPlusCGQREQ (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  T_QOS input_qos = { ( UBYTE ) GPRS_QOS_OMITTED };
  SHORT cid = GPRS_CID_OMITTED;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGQREQ ()");

  cl=parse(cl,"raaaar",&cid
                      ,1L ,&input_qos.preced
                      ,1L ,&input_qos.delay
                      ,1L ,&input_qos.relclass
                      ,1L ,&input_qos.peak
                          ,&input_qos.mean);

  if (cl EQ NULL)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

  if ( input_qos.preced NEQ GPRS_QOS_OMITTED )
    input_qos.preced    -= '0';
  if ( input_qos.delay NEQ GPRS_QOS_OMITTED )
    input_qos.delay     -= '0';
  if ( input_qos.relclass NEQ GPRS_QOS_OMITTED )
    input_qos.relclass  -= '0';
  if ( input_qos.peak NEQ GPRS_QOS_OMITTED )
    input_qos.peak      -= '0';
  if ( input_qos.mean EQ 0xff )
    input_qos.mean       = 0;

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgqreq cgqreq;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGQREQ;
    cmd.params.ptr_set_plus_cgqreq=&cgqreq;

    cgqreq.cid=(T_BAT_pdp_cid)cid;
/*
    if (input_qos.preced!=GPRS_QOS_OMITTED)
      cgqreq.precedence=(T_BAT_precedence)input_qos.preced;
    else
      cgqreq.precedence=BAT_PRECEDENCE_NOT_PRESENT;

    if (input_qos.delay!=GPRS_QOS_OMITTED)
      cgqreq.delay=(T_BAT_delay)input_qos.delay;
    else
      cgqreq.delay=BAT_DELAY_NOT_PRESENT;

    if (input_qos.relclass!=GPRS_QOS_OMITTED)
      cgqreq.reliability=(T_BAT_reliability)input_qos.relclass;
    else
      cgqreq.reliability=BAT_RELIABILITY_NOT_PRESENT;

    if (input_qos.peak!=GPRS_QOS_OMITTED)
      cgqreq.peak=(T_BAT_peak)input_qos.peak;
    else
      cgqreq.peak=BAT_PEAK_NOT_PRESENT;

    if (input_qos.mean)
      cgqreq.mean=(T_BAT_mean)input_qos.mean;
    else
      cgqreq.mean=BAT_MEAN_NOT_PRESENT;
*/

    cgqreq.precedence  = (T_BAT_precedence)input_qos.preced;
    cgqreq.delay       = (T_BAT_delay)input_qos.delay;
    cgqreq.reliability = (T_BAT_reliability)input_qos.relclass;
    cgqreq.peak        = (T_BAT_peak)input_qos.peak;
    cgqreq.mean        = (T_BAT_mean)input_qos.mean;

    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  ret = sAT_PlusCGQREQ (srcId, cid ,&input_qos);
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGQREQ;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif
}

GLOBAL T_ATI_RSLT queatPlusCGQREQ (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGQREQ: ";
  T_ACI_RETURN ret = AT_FAIL;
  T_QOS *pdef_qos[MAX_CID_PLUS_EINS];
  SHORT cid_array[MAX_CID_PLUS_EINS];
  int i = 0;
#endif

  TRACE_FUNCTION("queatPlusCGQREQ ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGQREQ;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgqreq = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret=qAT_PlusCGQREQ (srcId, pdef_qos, cid_array);
  if (ret EQ AT_CMPL)
  {
    for ( i = 0; i < MAX_CID && pdef_qos[i]; i++ )
    {
      sprintf(g_sa,"%s%hd,%d,%d,%d,%d,%d", me, cid_array[i],
        pdef_qos[i]->preced,
        pdef_qos[i]->delay,
        pdef_qos[i]->relclass,
        pdef_qos[i]->peak,
        pdef_qos[i]->mean       );

      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    }
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : atPlusCGQMIN       |
+--------------------------------------------------------------------+

  PURPOSE : +CGQMIN command (context min QOS requirement)
*/

GLOBAL T_ATI_RSLT setatPlusCGQMIN (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  T_QOS input_qos = { ( UBYTE ) GPRS_QOS_OMITTED };
  SHORT cid = GPRS_CID_OMITTED;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGQMIN ()");

  cl=parse(cl,"raaaar",&cid
                      ,1L ,&input_qos.preced
                      ,1L ,&input_qos.delay
                      ,1L ,&input_qos.relclass
                      ,1L ,&input_qos.peak
                          ,&input_qos.mean);

  if ( input_qos.preced NEQ GPRS_QOS_OMITTED )
    input_qos.preced    -= '0';
  if ( input_qos.delay NEQ GPRS_QOS_OMITTED )
    input_qos.delay     -= '0';
  if ( input_qos.relclass NEQ GPRS_QOS_OMITTED )
    input_qos.relclass  -= '0';
  if ( input_qos.peak NEQ GPRS_QOS_OMITTED )
    input_qos.peak      -= '0';

  if ( input_qos.mean EQ 0xff )
    input_qos.mean       = 0;

  if ( !cl )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgqmin cgqmin;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGQMIN;
    cmd.params.ptr_set_plus_cgqmin=&cgqmin;

    cgqmin.cid=(T_BAT_pdp_cid)cid;
/*
    if (input_qos.preced!=GPRS_QOS_OMITTED)
      cgqmin.precedence=(T_BAT_precedence)input_qos.preced;
    else
      cgqmin.precedence=BAT_PRECEDENCE_NOT_PRESENT;

    if (input_qos.delay!=GPRS_QOS_OMITTED)
      cgqmin.delay=(T_BAT_delay)input_qos.delay;
    else
      cgqmin.delay=BAT_DELAY_NOT_PRESENT;

    if (input_qos.relclass!=GPRS_QOS_OMITTED)
      cgqmin.reliability=(T_BAT_reliability)input_qos.relclass;
    else
      cgqmin.reliability=BAT_RELIABILITY_NOT_PRESENT;

    if (input_qos.peak!=GPRS_QOS_OMITTED)
      cgqmin.peak=(T_BAT_peak)input_qos.peak;
    else
      cgqmin.peak=BAT_PEAK_NOT_PRESENT;

    if (input_qos.mean)
      cgqmin.mean=(T_BAT_mean)input_qos.mean;
    else
      cgqmin.mean=BAT_MEAN_NOT_PRESENT;
*/

   cgqmin.precedence  = (T_BAT_precedence)input_qos.preced;
   cgqmin.delay       = (T_BAT_delay)input_qos.delay;
   cgqmin.reliability = (T_BAT_reliability)input_qos.relclass;
   cgqmin.peak        = (T_BAT_peak)input_qos.peak;
   cgqmin.mean        = (T_BAT_mean)input_qos.mean;

    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  ret = sAT_PlusCGQMIN (srcId, cid ,&input_qos);
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGQMIN;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }
#endif
}

GLOBAL T_ATI_RSLT queatPlusCGQMIN (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGQMIN: ";
  T_ACI_RETURN ret = AT_FAIL;
  T_QOS *pdef_qos[MAX_CID_PLUS_EINS];
  SHORT cid_array[MAX_CID_PLUS_EINS];
  int i = 0;
#endif

  TRACE_FUNCTION("queatPlusCGQMIN ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGQMIN;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgqmin = &dummy;

    bat_send(ati_bat_get_client(srcId), &cmd);

    return(ATI_EXCT);
  }
#else

  ret=qAT_PlusCGQMIN (srcId, pdef_qos, cid_array);
  if (ret EQ AT_CMPL)
  {
    for ( i = 0; i < MAX_CID && pdef_qos[i]; i++ )
    {
      sprintf(g_sa,"%s%hd,%d,%d,%d,%d,%d", me, cid_array[i],
        pdef_qos[i]->preced,
        pdef_qos[i]->delay,
        pdef_qos[i]->relclass,
        pdef_qos[i]->peak,
        pdef_qos[i]->mean       );

      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    }
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : atPlusCGATT        |
+--------------------------------------------------------------------+

  PURPOSE : +CGATT command ( GPRS attach/detach )
*/

GLOBAL T_ATI_RSLT setatPlusCGATT (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  T_CGATT_STATE state = CGATT_STATE_OMITTED;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGATT ()");

  cl=parse(cl,"d",&state);

  if ( !cl )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgatt cgatt;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGATT;
    cmd.params.ptr_set_plus_cgatt=&cgatt;

    /*
    *   This relies on T_CGATT_STATE being identical to
    *   T_BAT_plus_cgatt_state.
    */
    cgatt.state=(T_BAT_plus_cgatt_state)state;

    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  ret = sAT_PlusCGATT ( srcId, state );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGATT;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

GLOBAL T_ATI_RSLT queatPlusCGATT (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGATT: ";
  T_ACI_RETURN ret = AT_FAIL;
  T_CGATT_STATE state = CGATT_STATE_OMITTED;
#endif

  TRACE_FUNCTION("queatPlusCGATT ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGATT;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgatt = &dummy;

    bat_send(ati_bat_get_client(srcId), &cmd);

    return(ATI_EXCT);
  } 
#else

  ret = qAT_PlusCGATT(srcId, &state);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s%d", me, state);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}


/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : atPlusCGCLASS      |
+--------------------------------------------------------------------+

  PURPOSE : +CGCLASS command  (GPRS class change)
*/

GLOBAL T_ATI_RSLT setatPlusCGCLASS (char *cl, UBYTE srcId)
{
  char *me="+CGCLASS: ";
  T_ACI_RETURN ret = AT_FAIL;
  T_CGCLASS_CLASS m_class = CGCLASS_CLASS_OMITTED;
  char test_class[3]="";
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("atPlusCGCLASS ()");

  cl = parse (cl,"s", (LONG)3, &test_class );

  switch (*test_class)
  {
    case 'A':
      break;
    case 'B':
      m_class = CGCLASS_CLASS_B;
      break;
    case 'C':
      switch(*(test_class + 1))
      {
        case 'G':
          m_class = CGCLASS_CLASS_CG;
          break;
        case 'C':
          m_class = CGCLASS_CLASS_CC;
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if ( !cl || m_class == CGCLASS_CLASS_OMITTED )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgclass cgclass;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGCLASS;
    cmd.params.ptr_set_plus_cgclass=&cgclass;

    /*
    *   This relies on T_BAT_mobile_class and T_CGCLASS_CLASS
    *   being identical.
    */
    cgclass.mobile_class=(T_BAT_mobile_class)m_class;

    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  ret = sAT_PlusCGCLASS ( srcId, m_class );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGCLASS;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

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

#ifndef FF_ATI_BAT
  char *me="+CGCLASS: ";
  char *classes[] = {"A","B","CG","CC"};
  T_ACI_RETURN ret = AT_FAIL;
  T_CGCLASS_CLASS m_class = CGCLASS_CLASS_OMITTED;
  char test_class[3]="";
#endif

  TRACE_FUNCTION("queatPlusCGCLASS ()");

#ifdef FF_ATI_BAT
  {
  T_BAT_cmd_send cmd;
  T_BAT_no_parameter dummy;

  cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGCLASS;
  dummy.bat_dummy = 0xFF;
  cmd.params.ptr_que_plus_cgclass = &dummy;
  bat_send(ati_bat_get_client(srcId), &cmd);
  return(ATI_EXCT);
  }
#else

  ret = qAT_PlusCGCLASS(srcId, &m_class);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s\"%s\"", me, classes[m_class]);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}


/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finnished                   ROUTINE : atPlusCGACT        |
+--------------------------------------------------------------------+

  PURPOSE : +CGACT command (context activation/deactivation)
*/

GLOBAL T_ATI_RSLT setatPlusCGACT (char *cl, UBYTE srcId)
{
  char *end;
  T_ACI_RETURN ret = AT_FAIL;
  T_CGACT_STATE state = CGACT_STATE_OMITTED;
  SHORT count = 0;
  SHORT cid, cid_array[MAX_CID_PLUS_EINS];
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGACT ()");

  end = cl;

  if ( *cl != ',' )
    state = (T_CGACT_STATE) strtol(cl, &end, 10);

  while ( *end EQ ',' )
  {
    cl = end;           /* advace to the next delimiter */
    cl ++;              /* skip the delimiter */
    cid = INVALID_CID;

    cid = ( SHORT ) strtol (cl, &end, 10);

    if (cid < 1 || cid > MAX_CID || count >= MAX_CID)
    {
      cmdCmeError(CME_ERR_OpNotAllow);
      return (ATI_FAIL);
    }
    cid_array[count] = cid;
    count ++;
  }

  cid_array[count] = INVALID_CID;
  cl = end;

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgact cgact;
    UBYTE n;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGACT;
    cmd.params.ptr_set_plus_cgact=&cgact;

    /*
    *   This relies on T_BAT_plus_cgact_state and T_CGACT_STATE
    *   being identical.
    */
    cgact.state=(T_BAT_plus_cgact_state)state;

    for (n=0;((n<count) && (n<BAT_MAX_PDP_CID));n++)
      cgact.cid[n]=(T_BAT_pdp_cid)cid_array[n];

    cgact.c_cid=(U8)n;
 
    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  /* (De) Activate necessary contexts */
  ret = sAT_PlusCGACT ( srcId, state, cid_array );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGACT;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

GLOBAL T_ATI_RSLT queatPlusCGACT (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGACT: ";
  T_ACI_RETURN ret = AT_FAIL;
  SHORT count = 0;
  SHORT cid_array[MAX_CID_PLUS_EINS];
  BOOL  states[MAX_CID_PLUS_EINS];
#endif

  TRACE_FUNCTION("queatPlusCGACT ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGACT;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgact = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret=qAT_PlusCGACT(srcId, states, cid_array);
  if (ret EQ AT_CMPL)
  {
    for ( count = 0; count < MAX_CID && cid_array[count] NEQ INVALID_CID; count++ )
    {
      sprintf(g_sa,"%s%hd,%d", me, cid_array[count], states[count] EQ TRUE? 1 : 0);
      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    }
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}


/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finnished                   ROUTINE : atPlusCGDATA       |
+--------------------------------------------------------------------+

  PURPOSE : +CGDATA command (data connect)
*/

GLOBAL T_ATI_RSLT setatPlusCGDATA (char *cl, UBYTE srcId)
{
  char L2P[MAX_L2P_LENGTH] = "", *end;
  T_ACI_RETURN ret = AT_FAIL;
  SHORT count = 0, stop = 1;
  SHORT cid_array[MAX_CID_PLUS_EINS] = { GPRS_CID_OMITTED };
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGDATA ()");

  switch ( *cl )
  {
    case ',':
      /* the L2P is unspecified */
      *L2P = 0;
      break;
    case '\"':
      cl++;
      while (*cl && stop)
      {
        if ( *cl NEQ '\"' && count < MAX_L2P_LENGTH - 1 )
        {
          L2P[count] = *cl;
          count ++;
          cl    ++;
        }
        else
        {
          L2P[count] = 0;
          stop = 0;
        }
      }

      if ( *cl NEQ '\"' )
      { /* Bad user input, abort */
        cmdCmeError(CME_ERR_OpNotAllow);
        return (ATI_FAIL);
      }

      cl++;
      break;
    case 0:
      break;
    default:
      /* Bad user input, abort */
      cmdCmeError(CME_ERR_OpNotAllow);
      return (ATI_FAIL);
  }

  end   = cl;
  count = 0;
  while ( *end EQ ',' )
  {
    cl = end;
    cl ++;

    cid_array[count] = ( SHORT ) strtol (cl, &end, 10);

    if ( count >= MAX_CID )
    {
      cmdCmeError(CME_ERR_OpNotAllow);
      return (ATI_FAIL);
    }
    count ++;
  }

  if ( count )
    cid_array[count] = INVALID_CID;

  cl = end;

/*
 *  if no cid is given or if there is no matching context definition
 *  the function sAT_PlusCGDATA will process this
 */

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgdata cgdata;
    UBYTE n;
    UBYTE len;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGDATA;
    cmd.params.ptr_set_plus_cgdata=&cgdata;

    cgdata.v_cid=FALSE;

    if (count)
    {
      for (n=0;((n<count) && (n<BAT_MAX_PDP_CID));n++)
        cgdata.cid[n]=(T_BAT_pdp_cid)cid_array[n];

      cgdata.c_cid=(U8)n;
      cgdata.v_cid=TRUE;
    }

    cgdata.v_l2p=FALSE;

    if (L2P[0]) 
    {
      if ((len=strlen(L2P))<=BAT_MAX_CGDATA_L2P_LEN)
      {
        cgdata.v_l2p=TRUE;
        memcpy(cgdata.l2p,L2P,len);
        cgdata.c_l2p=len;
      }
    }
    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  /* establish communication between the TE and the network */
  ret = sAT_PlusCGDATA ( srcId, L2P, cid_array );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      cmdErrStr   = NULL;
      src_params->curAtCmd    = AT_CMD_CGDATA;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

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

  PURPOSE : +CGPADDR command (show PDP addresses)
  active command returns a list of last used  PDP addresses
  for specified cids. If unspecified, returns list for all
  defined cids.
*/

GLOBAL T_ATI_RSLT setatPlusCGPADDR (char *cl, UBYTE srcId)
{
  char          *me="+CGPADDR: ", *end;
#ifndef FF_ATI_BAT
  T_ACI_RETURN  ret;
  T_PDP_ADDRESS pdp_addresses[MAX_CID];
#endif

  SHORT         count = 0;
  SHORT         cid_array[MAX_CID_PLUS_EINS];

  TRACE_FUNCTION("setatPlusCGPADDR ()");

  do
  {
    cid_array[count] = ( SHORT ) strtol (cl, &end, 10);
    count ++;
    cl = end;
    if ( *cl EQ ',' )
      cl++;
  }
  while ( *end EQ ',' );

  cid_array[count] = INVALID_CID;
  cl = end;

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgpaddr cgpaddr;
    UBYTE n;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGPADDR;
    cmd.params.ptr_set_plus_cgpaddr=&cgpaddr;

    cgpaddr.c_cid=0;

    if (count)
    {
      for (n=0;((n<count) && (n<BAT_MAX_PDP_CID));n++)
        cgpaddr.cid[n]=(T_BAT_pdp_cid)cid_array[n];

      cgpaddr.c_cid=(U8)n;
    }
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }

#else

  /* return a list of PDP addresses for the specified context identifier */
  ret = sAT_PlusCGPADDR ( srcId, cid_array, pdp_addresses );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      count = 0;
      if (cid_array[0] NEQ INVALID_CID)
      {
        while ( cid_array[count] NEQ INVALID_CID )
        {
          if (*pdp_addresses[count])
            sprintf(g_sa,"%s%hd,\"%s\"", me, cid_array[count], pdp_addresses[count]);
          else
            sprintf(g_sa,"%s%hd", me, cid_array[count]);

          io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
          count ++;
        }
      }
      return (ATI_CMPL);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/

}

GLOBAL T_ATI_RSLT tesatPlusCGPADDR (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char          *me="+CGPADDR: ";
  T_ACI_RETURN  ret;
  SHORT         count = 0;
  SHORT         cid_array[MAX_CID_PLUS_EINS];
  int           pos = 0;
#endif

  TRACE_FUNCTION("tesatPlusCGPADDR ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_TST_PLUS_CGPADDR;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_tst_plus_cgpaddr = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  /* return a list of defined context identifier */
  ret = tAT_PlusCGPADDR ( srcId, cid_array );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      pos = sprintf(g_sa,"%s(", me);
      while ( cid_array[count] NEQ INVALID_CID )
      {
        if ( count NEQ 0 )
        {
          g_sa[pos] = ','; pos++;
        }
        pos += sprintf(g_sa + pos,"%hd", cid_array[count]);
        count ++;
      }
      g_sa[pos] = ')'; pos++;
      g_sa[pos] = 0;
      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
      return (ATI_CMPL);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finnished                   ROUTINE : atPlusCGAUTO       |
+--------------------------------------------------------------------+

  PURPOSE : +CGAUTO command (auto answer/modem compatibility control)
*/

GLOBAL T_ATI_RSLT setatPlusCGAUTO (char *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_FAIL;
  T_CGAUTO_N n = CGAUTO_N_OMITTED;       /* Invalid range value to detect an empty parameter */
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGAUTO ()");

  cl  =  parse (cl,"d", &n );
  ret = sAT_PlusCGAUTO ( srcId, n );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      at.rngPrms.srcID_CGAUTO = srcId;
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGATT;
      at.rngPrms.srcID_CGAUTO = srcId;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }
}

GLOBAL T_ATI_RSLT queatPlusCGAUTO (char *cl, UBYTE srcId)
{
  char *me="+CGAUTO: ";
  T_ACI_RETURN ret = AT_FAIL;
  T_CGAUTO_N n = CGAUTO_N_OMITTED;       /* Invalid range value to detect an empty parameter */

  TRACE_FUNCTION("queatPlusCGAUTO ()");

  ret = qAT_PlusCGAUTO(srcId, &n);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s%hd", me, n);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));
}

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

  PURPOSE : +CGANS command (answer NW context req)
*/

GLOBAL T_ATI_RSLT setatPlusCGANS   (char *cl, UBYTE srcId)
{
  char L2P[MAX_L2P_LENGTH] = "", *end;
  T_ACI_RETURN ret = AT_FAIL;
  SHORT cid = GPRS_CID_OMITTED, response = -1, count = 0, stop = 1;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGANS ()");

  response = ( SHORT ) strtol (cl, &end, 10);
  cl = end;

  if ( *cl EQ ',' )
  {
    cl++;
    switch ( *cl )
    {
      case ',':
        /* the L2P is unspecified */
        *L2P = 0;
        break;
      case '\"':
        cl++;
        while (*cl && stop)
        {
          if ( *cl NEQ '\"' && count < MAX_L2P_LENGTH - 1 )
          {
            L2P[count] = *cl;
            count ++;
            cl    ++;
          }
          else
          {
            L2P[count] = 0;
            stop = 0;
          }
        }

        if ( *cl NEQ '\"' )
        { /* Bad user input, abort */
          cmdCmeError(CME_ERR_OpNotAllow);
          return (ATI_FAIL);
        }

        cl++;
        break;
      default:
        /* Bad user input, abort */
        cmdCmeError(CME_ERR_OpNotAllow);
        return (ATI_FAIL);
    }
    if ( *cl EQ ',' )
    {
      cl++;
      cid = ( SHORT ) strtol (cl, &end, 10);
      cl = end;
    }
  }

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgans cgans;
    UBYTE len;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGANS;
    cmd.params.ptr_set_plus_cgans=&cgans;

    cgans.cid=(T_BAT_pdp_cid)cid;

    /*
    *   This relies on T_BAT_plus_cgans_response and T_CGANS_RESPONSE
    *   being identical.
    */
    cgans.response=(T_BAT_plus_cgans_response)response;

    len=strlen(L2P);

    cgans.v_l2p=FALSE;

    if ((len) && (len<=BAT_MAX_CGANS_L2P_LEN))
    {
      memcpy(cgans.l2p,L2P,len);
      cgans.c_l2p=(U8)len;
      cgans.v_l2p=TRUE;
    }
    bat_send(ati_bat_get_client(srcId), &cmd);

    src_params->curAtCmd=AT_CMD_CGANS;

    if ((at.rngPrms.isRng==TRUE) && (at.rngPrms.mode==CRING_MOD_Gprs))
      ati_stop_ring();

    return(ATI_EXCT);
  }

#else

  /* return a list of PDP addresses for the specified context identifier */
  ret = sAT_PlusCGANS ( srcId, response, L2P, cid );

  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);

    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGANS;
      if ( at.rngPrms.isRng EQ TRUE       AND
           at.rngPrms.mode  EQ CRING_MOD_Gprs )
      {
        ati_stop_ring();
      }
      return (ATI_EXCT);

    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

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

  PURPOSE : +CGEREP command
*/

GLOBAL T_ATI_RSLT setatPlusCGEREP (char *cl, UBYTE srcId)
{
  T_ACI_RETURN  ret;
  T_CGEREP_MODE mode  = CGEREP_MODE_OMITTED;
  T_CGEREP_BFR  bfr   = CGEREP_BFR_OMITTED;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGEREP ()");

  cl=parse(cl,"dd",&mode, &bfr);

  ret = sAT_PlusCGEREP ( srcId, mode, bfr );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGEREP;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }
}

GLOBAL T_ATI_RSLT queatPlusCGEREP (char *cl, UBYTE srcId)
{
  char *me="+CGEREP: ";
  T_ACI_RETURN  ret;
  T_CGEREP_MODE mode  = CGEREP_MODE_OMITTED;
  T_CGEREP_BFR  bfr   = CGEREP_BFR_OMITTED;

  TRACE_FUNCTION("queatPlusCGEREP ()");

  ret=qAT_PlusCGEREP(srcId, &mode, &bfr);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s%d,%d", me, mode, bfr);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  return (map_aci_2_ati_rslt(ret));
}

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

  PURPOSE : %CGEREP command
*/

GLOBAL T_ATI_RSLT setatPercentCGEREP (char *cl, UBYTE srcId)
{
  TRACE_FUNCTION("setatPercentCGEREP ()");

  switch( *cl )
  {
    case '0':
        ati_user_output_cfg[srcId].Percent_CGEREP_stat = 0;
        return (ATI_CMPL);

    case '1':
        ati_user_output_cfg[srcId].Percent_CGEREP_stat = 1;
        return (ATI_CMPL);

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

GLOBAL T_ATI_RSLT queatPercentCGEREP (char *cl, UBYTE srcId)
{
  char *me="%CGEREP: ";
  UBYTE mode;

  TRACE_FUNCTION("queatPercentCGEREP ()");

  mode = ati_user_output_cfg[srcId].Percent_CGEREP_stat;

  sprintf(g_sa,"%s%d", me, mode);
  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

  return (ATI_CMPL);
}


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

  PURPOSE : +CGREG command
*/

GLOBAL T_ATI_RSLT setatPlusCGREG (char *cl, UBYTE srcId)
{
  T_ATI_CREG_MOD mode=CREG_MOD_OFF;

  TRACE_FUNCTION("setatPlusCGREG()");

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

  switch(mode)
  {
    case CREG_MOD_OFF:
    case CREG_MOD_ON:
    case CREG_MOD_LOC_INF_ON:
      /* user wants to set mode: reset CREG related ATI parameters */
      ati_creg_init(srcId, PlusCGREG_CMD);
      ati_gprs_user_output_cfg[srcId].plus_cgreg.mod_lac_cid.pres_mode = mode;
      return ATI_CMPL;

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

GLOBAL T_ATI_RSLT queatPlusCGREG (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_CGREG_STAT   stat;
  USHORT         lac, cid;
  T_ATI_CREG_MOD mode;
  short          pos;
#endif

  TRACE_FUNCTION("queatPlusCGREG()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGREG;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgreg = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  mode = ati_gprs_user_output_cfg[srcId].plus_cgreg.mod_lac_cid.pres_mode;

  if (qAT_PlusCGREG(srcId, &stat, &lac, &cid) NEQ AT_CMPL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }

  pos = sprintf(g_sa, "+CGREG: %d,%d", mode, stat);

  if(mode EQ CREG_MOD_LOC_INF_ON)
  {
    if(stat EQ CGREG_STAT_REG_HOME  OR  stat EQ CGREG_STAT_REG_ROAM)
      sprintf(g_sa+pos, ",\"%04X\",\"%04X\"", lac, cid);
  }

  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  return ATI_CMPL;

#endif /*FF_ATI_BAT*/
}


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

  PURPOSE : %CGREG command
*/

GLOBAL T_ATI_RSLT setatPercentCGREG (char *cl, UBYTE srcId)
{
  T_ATI_CREG_MOD mode=CREG_MOD_OFF;

  TRACE_FUNCTION("setatPercentCGREG()");

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

  switch(mode)
  {
    case CREG_MOD_OFF:
    case CREG_MOD_ON:
    case CREG_MOD_LOC_INF_ON:
    case CREG_MOD_LOC_INF_ON_CTXACT:
      /* user wants to set mode: reset CREG related ATI parameters */
      ati_creg_init(srcId, PercentCGREG_CMD);
      ati_gprs_user_output_cfg[srcId].percent_cgreg.mod_lac_cid.pres_mode = mode;
      return ATI_CMPL;

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

GLOBAL T_ATI_RSLT queatPercentCGREG (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_P_CGREG_STAT  stat;
  USHORT          lac, cid;
  T_ATI_CREG_MOD  mode;
  SHORT           pos;
#endif

  TRACE_FUNCTION("queatPercentCGREG()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_CGREG;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgreg = &dummy;

    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  } 
#else

  mode = ati_gprs_user_output_cfg[srcId].percent_cgreg.mod_lac_cid.pres_mode;

  if (qAT_PercentCGREG(srcId, &stat, &lac, &cid) NEQ AT_CMPL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return ATI_FAIL;
  }

  pos = sprintf(g_sa,"%s: %d,%d", "%CGREG", mode, stat);

  if (mode EQ CREG_MOD_LOC_INF_ON  OR  mode EQ CREG_MOD_LOC_INF_ON_CTXACT)
  {
    if (stat EQ P_CGREG_STAT_REG_HOME  OR  stat EQ P_CGREG_STAT_REG_ROAM)
      pos += sprintf(g_sa+pos, ",\"%04X\",\"%04X\"", lac, cid);
    else if (mode EQ CREG_MOD_LOC_INF_ON_CTXACT)
      pos += sprintf(g_sa+pos, ",,");   /* if CTXACT follows so lac and cid are ommitted */
  }

  if (mode EQ CREG_MOD_LOC_INF_ON_CTXACT)
    sprintf(g_sa+pos, (cmhSM_isContextActive() ? ",1" : ",0"));

  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  return ATI_CMPL;

#endif /*FF_ATI_BAT*/
}


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

  PURPOSE : +CGSMS command (define MO SMS behaviour)
*/

GLOBAL T_ATI_RSLT setatPlusCGSMS (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_ACI_RETURN    ret;
#endif
  T_CGSMS_SERVICE service = CGSMS_SERVICE_OMITTED;  /* Invalid range value to detect an empty parameter */
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);

  TRACE_FUNCTION("setatPlusCGSMS ()");

  cl=parse(cl,"d",&service);

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_plus_cgsms cgsms;

    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGSMS;
    cmd.params.ptr_set_plus_cgsms=&cgsms;

    /*
    *   This relies on T_BAT_plus_cgsms_service and T_CGSMS_SERVICE
    *   being identical.
    */
    cgsms.service=(T_BAT_plus_cgsms_service)service;

    bat_send(ati_bat_get_client(srcId), &cmd);

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

#else

  ret = sAT_PlusCGSMS ( srcId, service );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
      src_params->curAtCmd    = AT_CMD_CGSMS;
      return (ATI_EXCT);
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

GLOBAL T_ATI_RSLT queatPlusCGSMS (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGSMS: ";
  T_ACI_RETURN    ret;
  T_CGSMS_SERVICE service = CGSMS_SERVICE_OMITTED;  /* Invalid range value to detect an empty parameter */
#endif

  TRACE_FUNCTION("queatPlusCGSMS ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PLUS_CGSMS;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgsms = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret = qAT_PlusCGSMS(srcId, &service);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s%hd", me, service);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    return (ATI_CMPL);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

GLOBAL T_ATI_RSLT tesatPlusCGSMS (char *cl, UBYTE srcId)
{
  char *me="+CGSMS: ", list[10] = "(0-3)";
  T_ACI_RETURN    ret;
  T_CGSMS_SERVICE service = CGSMS_SERVICE_OMITTED;  /* Invalid range value to detect an empty parameter */
  SHORT           service_list;

  TRACE_FUNCTION("tesatPlusCGSMS ()");

  ret = tAT_PlusCGSMS ( srcId, &service_list );
  switch (ret)
  {
  case (AT_CMPL):                         /*operation completed*/
    if ( service_list NEQ 15 )
    {
      list[1] = service EQ 1 ? '0':'1';
      list[2] = ')';
      list[3] = 0;
    }
    cl++;
    sprintf(g_sa,"%s%s", me, list);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
    return (ATI_CMPL);
  default:
    cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
    return (ATI_FAIL);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finnished                   ROUTINE : atGD               |
+--------------------------------------------------------------------+

  PURPOSE : +ATD command
*/

GLOBAL T_ATI_RSLT atGD (char *cl, UBYTE srcId, BOOL *gprs_command)
{

  SHORT count = 0, cid_array[2] = { GPRS_CID_OMITTED, INVALID_CID }, i = 0;
  T_ACI_RETURN ret = AT_FAIL;
  char  L2P[MAX_L2P_LENGTH] = "PPP", save_char, *p_save_char, *end;
  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
  int l2pID = -1;

  TRACE_FUNCTION ("atGD()");

  if (cl EQ NULL)
  {
    *gprs_command = FALSE;
    return (ATI_FAIL);
  }

  /* ignore modifier */
  switch ( *cl )
  {
    case 'T':
    case 't':
    case 'P':
    case 'p':
      if ( *(cl + 1) EQ '*' )
      {
        cl ++;
      }
      else
      {
        *gprs_command = FALSE;
        return (ATI_FAIL);
      }
      break;
    case '*':
      break;
    default:
      *gprs_command = FALSE;
      return (ATI_FAIL);
  }

  /* check the service code */

#if defined(FF_WAP) OR defined(FF_GPF_TCPIP) || defined (FF_SAT_E)
  if ( (*(cl + 1) NEQ '9') ||
       ( ( *(cl + 2) NEQ '9' ) && ( *(cl + 2) NEQ '8' ) ) )
  {
    *gprs_command = FALSE;
    return (ATI_FAIL);
  }

  else if ( *(cl + 2) EQ '8' ) /* atd*98# -> WAP over GPRS */
  {
    /* if call not yet marked as WAP call, mark it now */
    if (!Wap_Call)
    {
      TRACE_EVENT ("ati_gprs, atGD, cmd is atd*98#");
      sAT_PercentWAP(srcId, 1);
    }
    l2pID = GPRS_CID_OMITTED;
}

#else  /* defined(WAP) OR defined(FF_GPF_TCPIP)  || defined (FF_SAT_E)*/
  if (  *(cl + 1) NEQ '9' || *(cl + 2) NEQ '9' )
  {
    *gprs_command = FALSE;
    return (ATI_FAIL);
  }
#endif /*defined(WAP) OR defined(FF_GPF_TCPIP)  || defined (FF_SAT_E)*/

  cl += 3;
  /* now *98 or *99 detected */
  /* the next character must be # or * for GPRS, otherwise this is USSD and not GPRS related! */

  if (*cl NEQ '#' AND *cl NEQ '*')
  {
    *gprs_command = FALSE;
    return (ATI_FAIL);
  }

  *gprs_command = TRUE;

  /* parse the parameter list */
  while ( *cl EQ '*' )
  {
    count ++; /* count the parameter of the command */
    cl ++;
    p_save_char = strpbrk (cl, "*#" );
    if ( !p_save_char )
    { /* Bad user input*/
      cmdCmeError(CME_ERR_OpNotAllow);
      return (ATI_FAIL);
    }

#if defined(FF_WAP) OR defined(FF_GPF_TCPIP) || defined (FF_SAT_E) 
    if( Wap_Call )
    {
      l2pID = *cl - '0';
      cl++;
      break;
    }
    else
#endif /* defined(WAP) OR defined(FF_GPF_TCPIP)  || defined (FF_SAT_E)*/
    {
      /* parse one parameter */
      switch ( count )
      {
        case 1: /* called_address */
          cl = p_save_char;
          break;
        case 2: /* L2P */
          if ( *cl NEQ '*' )
          {
            l2pID = (SHORT) strtol(cl, &end, 10);
          
            if(cl + 1 EQ end)
            { /* L2P obmitted */
              l2pID = -1;
            }
            else if(-1 EQ l2pID)
            {
              cmdCmeError(CME_ERR_OpNotAllow);
              return (ATI_FAIL);
            }
            cl = end;
          }
          break;
        case 3: /* cid */
          save_char     = *p_save_char;
          *p_save_char  = 0;

          cid_array[0] = (SHORT) strtol(cl, &end, 10);

          *p_save_char = save_char;

          cl = end;
          break;
        default:
          /* Bad user input*/
          cmdCmeError(CME_ERR_OpNotAllow);
          return (ATI_FAIL);
      }
    }

  } /* while */

  /* check end of line charakter */
  if ( *cl NEQ '#')
  { /* Bad user input*/
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#if defined(FF_WAP) OR defined(FF_GPF_TCPIP) || defined (FF_SAT_E)
  if ( Wap_Call )
  {
    BYTE  options;
    SHORT j = 0;
    SRCC_LINK_NO link_no = SRCC_INVALID_LINK;
    /* process WAP over GPRS */

  /*
   *-------------------------------------------------------------------
   * check entity status
   *-------------------------------------------------------------------
   */
    if( smEntStat.curCmd NEQ AT_CMD_NONE )
      return( ATI_BUSY );

    cid_array[0] = l2pID;

    if(is_gpf_tcpip_call()) {
      GPF_TCPIP_STATEMENT(link_no = SRCC_TCPIP_SNDCP_LINK);
    }
    else {
      link_no = SRCC_IP_SNDCP_LINK;
    }
    /* check number of context */
    if ( TRUE NEQ srcc_reserve_sources( link_no, 1 ) )
    {
      TRACE_EVENT ("srcc_reserve_sources failed!");
      cmdCmeError(CME_ERR_Unknown);
      return ( ATI_FAIL );
    }

    if ( cmhSM_define_cid_list( srcId, cid_array ) EQ 0)       /* process cid list */
    {
      TRACE_EVENT ("*** cmhSM_define_cid_list failed! ***");
      cmdCmeError(CME_ERR_Unknown);
      return( ATI_FAIL );
    }

    /* get dti id */
    srcc_new_count(link_no);
    
    wap_dti_id = dti_cntrl_new_dti(DTI_DTI_ID_NOTPRESENT);
    pdp_context[work_cids[cid_pointer] - 1].link_id_new =
      dti_conn_compose_link_id (0,0, wap_dti_id, DTI_TUPLE_NO_NOTPRESENT );
    pdp_context[work_cids[cid_pointer] - 1].owner = srcId;

    TRACE_EVENT_P1 ("ati_gprs, atGD, link_id_new = %0X", pdp_context[work_cids[0] - 1].link_id_new);

    /* set IP options */
    if(is_gpf_tcpip_call()) {
      options = TCPIP_ACT_OPTION_V4 | TCPIP_ACT_OPTION_TCPIP; 
    }
    else {
      options = TCPIP_ACT_OPTION_V4 | TCPIP_ACT_OPTION_UDP;
    }

    /* send request to ACI WAP to activate WAP */
    smShrdPrm.owner  = srcId;
    smEntStat.entOwn = smShrdPrm.owner;
    smEntStat.curCmd = AT_CMD_CGDATA;

    if(src_params)
    {
      src_params->curAtCmd = AT_CMD_CGDATA;
    }

    psaTCPIP_Activate( srcId, wap_dti_id,
                       wapId, options, TCPIP_CONNECTION_TYPE_GPRS_WAP,
                       cmhSM_IP_activate_cb);
    return (ATI_EXCT);

  }
#endif /* defined(WAP) OR defined(FF_GPF_TCPIP) || defined (FF_SAT_E) */
  /*
   *    patch for testing of network requested context activation 
   *    and answer by dial-up-network (ATD -> ATA)
   */
  if ( cmhSM_sAT_A( srcId, &ret ) EQ TRUE )
  {
    switch (ret)
    {
      case (AT_CMPL):                         /*operation completed*/
        return (ATI_CMPL);
      case (AT_EXCT):
         if(src_params)
         {
           src_params->curAtCmd = AT_CMD_CGANS;
         }
        return (ATI_EXCT);
      default:
        cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
        return (ATI_FAIL);
    }
  }
  else
  {
    /* process function */
    switch(l2pID) 
    {
      case -1:  /* L2P obmitted */
      case 1:   /* PPP */
        break;

#if defined(FF_PKTIO) OR defined(FF_TCP_IP) || defined(FF_GPF_TCPIP) OR defined (FF_PSI)
      case 901: /* M-PKT */
        strcpy(L2P, "M-PKT");
        break;
#endif /* FF_PKTIO || FF_TCP_IP || FF_GPF_TCPIP OR FF_PSI */
      case 0:   /* NULL - not supported at this moment -> use CGACT */
      default:
        cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
        return (ATI_FAIL);
    }

    ret = sAT_PlusCGDATA ( srcId, L2P, cid_array );
    switch (ret)
    {
      case (AT_CMPL):                         /*operation completed*/
        return (ATI_CMPL);
      case (AT_EXCT):
        if(src_params)
        {        
          src_params->curAtCmd = AT_CMD_CGDATA;
        }
        return (ATI_EXCT);
      case (AT_BUSY):
        cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
        return (ATI_FAIL);
      default:
        cmdCmeError(CME_ERR_NotPresent);         /*Command failed*/
        return (ATI_FAIL);
    }
  }
}


/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : setatPercentCGAATT |
+--------------------------------------------------------------------+

  PURPOSE : %CGAATT command ( GPRS automatic attach mode )
*/

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

  T_ACI_RETURN ret = AT_FAIL;
  T_CGAATT_ATTACH_MODE att_m = CGAATT_ATTACH_MODE_OMITTED;
  T_CGAATT_DETACH_MODE det_m = CGAATT_DETACH_MODE_OMITTED;

  TRACE_FUNCTION("setatPercentCGAATT ()");

  cl=parse(cl,"dd",&att_m, &det_m);

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_cgaatt cgaatt;

    cmd.ctrl_params = BAT_CMD_SET_PERCENT_CGAATT;
    cmd.params.ptr_set_percent_cgaatt=&cgaatt;

    /*
    *   This relies on T_CGAATT_ATTACH_MODE and T_GGAATT_DETACH_MODE being
    *   identical to T_BAT_percent_cgaatt_att_m and T_BAT_percent_cgaatt_det_m.
    */
    cgaatt.att_m=(T_BAT_percent_cgaatt_att_m)att_m;
    cgaatt.det_m=(T_BAT_percent_cgaatt_det_m)det_m;

    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }

#else

  ret = sAT_PercentCGAATT ( srcId, att_m, det_m );
  switch (ret)
  {
    case (AT_CMPL):                         /*operation completed*/
      return (ATI_CMPL);
    case (AT_EXCT):
    default:
      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
      return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

GLOBAL T_ATI_RSLT queatPercentCGAATT (char *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_ACI_RETURN    ret;
  T_CGAATT_ATTACH_MODE att_m = CGAATT_ATTACH_MODE_OMITTED;
  T_CGAATT_DETACH_MODE det_m = CGAATT_DETACH_MODE_OMITTED;
#endif

  TRACE_FUNCTION("atPercentCGAATT ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_CGAATT;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_cgaatt = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret = qAT_PercentCGAATT(srcId, &att_m, &det_m);
  if (ret EQ AT_CMPL)
  {
    sprintf(g_sa,"%s: %d,%d", "%CGAATT", att_m, det_m);
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
	return (ATI_CMPL);
  }
  else
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

#endif /*FF_ATI_BAT*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : setatPercentSNCNT  |
+--------------------------------------------------------------------+

  PURPOSE : %SNCNT command ( SNDCP Counter )
            = 0: reset SNCNT counter.
            ?: ask for current count.
*/

GLOBAL T_ATI_RSLT setatPercentSNCNT (CHAR *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_CMPL;

  TRACE_FUNCTION("setatPercentSNCNT ()");

  if( *cl NEQ '0' )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

  cl++;

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_sncnt sncnt;

    cmd.ctrl_params = BAT_CMD_SET_PERCENT_SNCNT;
    cmd.params.ptr_set_percent_sncnt=&sncnt;

    sncnt.rst=BAT_P_SNCNT_RESET_RESET;

    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }

#else

  /* AT%SNCNT = 0 resets counter */
  ret = sAT_PercentSNCNT( srcId, TRUE );

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}

GLOBAL T_ATI_RSLT queatPercentSNCNT (CHAR *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_CMPL;

  TRACE_FUNCTION("queatPercentSNCNT ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_SNCNT;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_sncnt = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }

#else

  /* AT%SNCNT? returns current counter without resetting */
  ret = sAT_PercentSNCNT( srcId, FALSE );

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : setatPercentCGMM   |
+--------------------------------------------------------------------+

  PURPOSE : %CGMM command ( Configure GMM )
            %CGMM = cipher_on, tlli_handling
*/

GLOBAL T_ATI_RSLT setatPercentCGMM(CHAR *cl, UBYTE srcId)
{
  T_ACI_RETURN ret = AT_CMPL;
  USHORT cipher_on, tlli_handling;

  cl=parse(cl, "rr", &cipher_on, &tlli_handling);

  if(!cl)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT
  {
  T_BAT_cmd_send cmd;
  T_BAT_cmd_set_percent_cgmm my_bat_set_percent_cgmm;

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

  memset(&my_bat_set_percent_cgmm, 0, sizeof(my_bat_set_percent_cgmm));
  cmd.ctrl_params = BAT_CMD_SET_PERCENT_CGMM;
  cmd.params.ptr_set_percent_cgmm = &my_bat_set_percent_cgmm;

  my_bat_set_percent_cgmm.cipher_on = cipher_on;
  my_bat_set_percent_cgmm.tlli_handling = tlli_handling;

  bat_send(ati_bat_get_client(srcId), &cmd);

  return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* OLD FUNCTION BODY */

  TRACE_FUNCTION("setatPercentCGMM()");

  ret = sAT_PercentCGMM( srcId, (UBYTE)cipher_on, (UBYTE)tlli_handling );

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

#endif /* no FF_ATI_BAT*/
}


GLOBAL T_ATI_RSLT setatPercentCGPCO_HEX (USHORT cid,
                                    UBYTE *pco_hex_string, USHORT len)
{
  USHORT  pco_len;
  UBYTE   *pco_array;
  int     i;

  ACI_MALLOC (pco_array, ACI_PCO_MAX_LEN + 1);

  pco_len = utl_HexStrToBin (pco_hex_string, len,
                             pco_array, ACI_PCO_MAX_LEN + 1);
  if (pco_len EQ 0)
  {
    cmdCmeError (CME_ERR_InvalidTxtChar);
    ACI_MFREE (pco_array);
    return (ATI_FAIL);
  }

  if (cid EQ 0)
  {
    for (i = 0; i < MAX_CID; i++)
    {
      pdp_context[i].user_pco.len = (UBYTE)pco_len;
      memcpy (pdp_context[i].user_pco.pco, pco_array, pco_len);
    }
  }
  else
  {
    pdp_context[cid - 1].user_pco.len = (UBYTE)pco_len;
    memcpy (pdp_context[cid - 1].user_pco.pco, pco_array, pco_len);
  }

  ACI_MFREE (pco_array);

  return (ATI_CMPL);
}

GLOBAL T_ATI_RSLT setatPercentCGPCO_ASCII (UBYTE srcId, USHORT cid,
                                      UBYTE *pco_ascii_string, USHORT len)
{
  CHAR          aut_prot[5];
  CHAR          user[MAX_USER_LEN+1];   /* + '\0' */
  CHAR          pwd[MAX_PWD_LEN+1];     /* + '\0' */
  CHAR          dns1[MAX_DNS_LEN];
  CHAR          dns2[MAX_DNS_LEN];
  CHAR          *cl;

  TRACE_FUNCTION("setatPercentCGPCO_ASCII():");

  /* Initialize arrays */
  user[0] = '\0';
  pwd[0] = '\0';
  dns1[0] = '\0'; 
  dns2[0] = '\0'; 

  cl = parse ((CHAR*)pco_ascii_string, "qqqqq",
              sizeof (aut_prot), aut_prot,
              sizeof (user), user, sizeof (pwd), pwd, sizeof(dns1), dns1, sizeof(dns2), dns2);

  if(cl EQ NULL)
  {
    cmdCmeError (CME_ERR_InvalidTxtChar);
    return (ATI_FAIL);
  }
  if (strcmp (aut_prot, "PAP"))
  {
    cmdCmeError (CME_ERR_OpNotSupp);
    return (ATI_FAIL);
  }

  if (sAT_PercentCGPCO (srcId, cid,
                        ACI_PCO_AUTH_PROT_PAP, user, pwd, dns1, dns2) EQ AT_FAIL)
  {
    cmdCmeError (CME_ERR_Unknown);
    return (ATI_FAIL);
  }
  
  return (ATI_CMPL);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS                         MODULE  : ATI_GPRS          |
| STATE   : finished                     ROUTINE : ipaddr_to_string  |
+--------------------------------------------------------------------+

  PURPOSE : print the IP address (little endian!) to the supplied string.

*/
GLOBAL void ipaddr_to_string(ULONG ipaddr, char *ipaddr_string)
{
  UBYTE *addrbyte_p ;        /* Pointer to single address bytes. */
  
  if (ipaddr_string)
  {
    addrbyte_p = (UBYTE *) &ipaddr ;
    if (ipaddr NEQ 0)
    {
      /* This is for little endian *only*! */
      sprintf(ipaddr_string,"%u.%u.%u.%u",
              addrbyte_p[3], addrbyte_p[2], addrbyte_p[1], addrbyte_p[0]);
    }
    else
    {
      *ipaddr_string = '\0' ;
    }
  }
}


/*
+--------------------------------------------------------------------+
| PROJECT : GPRS                        MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : queatPercentCGPCO  |
+--------------------------------------------------------------------+

  PURPOSE : %CGPCO command
              * query network pco for cid
*/

GLOBAL T_ATI_RSLT queatPercentCGPCO (UBYTE srcId, USHORT cid)
{
  char *me="%CGPCO: ";
  ULONG gateway,dns1,dns2;
  char dns1_str[sizeof("255.255.255.255")];
  char dns2_str[sizeof("255.255.255.255")];
  char gatew_str[sizeof("255.255.255.255")];
  USHORT i;                     /* Counter for loop over context IDs. */

  TRACE_FUNCTION("queatPercentCGPCO( )");

  if(!cid)  /* for all available cid's: recurse */
  {
    for (i=1; i<MAX_CID; i++)
    {
      queatPercentCGPCO(srcId, i) ;
    }
  }
  else /* for a specific cid */
  {
    gateway = dns1 = dns2 = 0 ; /* Just in case... */
    qAT_PercentCGPCO(srcId,&gateway,&dns1,&dns2,cid);
    if(dns1 OR dns2 OR gateway)
    {
      ipaddr_to_string(dns1, dns1_str);
      ipaddr_to_string(dns2, dns2_str);
      ipaddr_to_string(gateway, gatew_str);
      sprintf(g_sa, "%s\"%s,%s,%s\",%d",
              me, dns1_str, dns2_str, gatew_str, cid) ;
    
      io_sendMessage (srcId, g_sa, ATI_NORMAL_OUTPUT);
    }
   }
   return (ATI_CMPL);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS                        MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : setatPercentCGPCO  |
+--------------------------------------------------------------------+

  PURPOSE : %CGPCO command
              * set the PCO for context activation
*/

GLOBAL T_ATI_RSLT setatPercentCGPCO(CHAR *cl, UBYTE srcId)
{
  USHORT              cid = 0;
  T_ACI_CGPCO_FORMAT  format;
  T_ATI_RSLT          ret = ATI_FAIL;
  CHAR               *pco_string;
  T_ACI_CGPCO_MODE    mode;

  TRACE_FUNCTION("setatPercentCGPCO()");

  ACI_MALLOC (pco_string, ACI_PCO_MAX_LEN * 2 + 1);

  cl = parse(cl, "ddsr",&mode, &format, ACI_PCO_MAX_LEN * 2 + 1, pco_string, &cid);

  if(cl EQ NULL)
  {
    cmdCmeError (CME_ERR_OpNotAllow);
  }
  else if (cid > MAX_CID)
  {
    cmdCmeError (CME_ERR_OpNotSupp);
  }
  else
  {

#ifdef FF_ATI_BAT

    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_cgpco cgpco;
    SHORT len;

    cmd.ctrl_params = BAT_CMD_SET_PERCENT_CGPCO;
    cmd.params.ptr_set_percent_cgpco=&cgpco;

    cgpco.cid=(T_BAT_pdp_cid)cid;
    cgpco.v_pco=FALSE;

    ret=ATI_EXCT;

    switch (mode)
    {
      case CGPCO_MODE_QUERY_PCO:
        cgpco.mode=BAT_P_CGPCO_MODE_QUERY_PCO;
        cgpco.format=(T_BAT_percent_cgpco_format)format;
        break;

      case CGPCO_MODE_SET_PCO:
        cgpco.mode=BAT_P_CGPCO_MODE_SET_PCO;
        cgpco.format=(T_BAT_percent_cgpco_format)format;

        len=strlen(pco_string);

        if (len>BAT_MAX_CGPCO_PCO_LEN)
        {
          ret=ATI_FAIL;
        }
        else
        {
          memcpy(cgpco.pco,pco_string,len);
          cgpco.c_pco=(U8)len;
          cgpco.v_pco=TRUE;
        }
        break;

      default:
        cmdCmeError(CME_ERR_OpNotSupp);
        ret=ATI_FAIL;
        break;
    }

    if (ret==ATI_EXCT)
    {
      bat_send(ati_bat_get_client(srcId), &cmd);
    }

#else

    switch (mode)
    {
      case CGPCO_MODE_QUERY_PCO:
        ret = queatPercentCGPCO (srcId,cid);
        break;
      case CGPCO_MODE_SET_PCO:
        switch (format)
        {
          case CGPCO_FORMAT_HEX:
            ret = setatPercentCGPCO_HEX (cid, (UBYTE*)pco_string, (USHORT)strlen (pco_string));
            break;
          case CGPCO_FORMAT_ASCII:
            ret = setatPercentCGPCO_ASCII (srcId, cid, (UBYTE*)pco_string, (USHORT)strlen (pco_string));
            break;
         default:
            cmdCmeError (CME_ERR_OpNotSupp);
            break;
         }
        break;
      default:
        cmdCmeError (CME_ERR_OpNotSupp);
        break;
    }
#endif

  }

  ACI_MFREE (pco_string);

  return (ret);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS                        MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : setatPercentCGPPP  |
+--------------------------------------------------------------------+

  PURPOSE : %CGPPP command
              * set PPP values in GPRS case

PPP_AP_NO                      0x0         no authentication
PPP_AP_PAP                     0x1         password authentication protocol
PPP_AP_CHAP                    0x2         challenge handshake authentication protocol
PPP_AP_AUTO                    0x3         automatic authentication

*/

GLOBAL T_ATI_RSLT setatPercentCGPPP (CHAR *cl, UBYTE srcId)
{
  T_ACI_PPP_PROT  protocol;
  T_ACI_RETURN    ret = ATI_FAIL;

  cl = parse(cl, "d", &protocol);

  if (!cl)
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return ret;
  }

#ifdef FF_ATI_BAT
  {
  T_BAT_cmd_send cmd;
  T_BAT_cmd_set_percent_cgppp my_bat_set_percent_cgppp;

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

  memset(&my_bat_set_percent_cgppp, 0, sizeof(my_bat_set_percent_cgppp));
  cmd.ctrl_params = BAT_CMD_SET_PERCENT_CGPPP;
  cmd.params.ptr_set_percent_cgppp = &my_bat_set_percent_cgppp;

  my_bat_set_percent_cgppp.protocol = protocol;

  bat_send(ati_bat_get_client(srcId), &cmd);

  return ATI_EXCT; /* executing, because response is passed by callback function */
  }
#else /* OLD FUNCTION BODY */

  TRACE_FUNCTION("setatPercentCGPPP( )");

  ret = sAT_PercentCGPPP(srcId, protocol);
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }
  return (map_aci_2_ati_rslt(ret));

#endif /* no FF_ATI_BAT*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GPRS                        MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : queatPercentCGPPP  |
+--------------------------------------------------------------------+

  PURPOSE : %CGPPP command
              * query PPP values in GPRS case

PPP_AP_NO                      0x0         no authentication
PPP_AP_PAP                     0x1         password authentication protocol
PPP_AP_CHAP                    0x2         challenge handshake authentication protocol
PPP_AP_AUTO                    0x3         automatic authentication

*/

GLOBAL T_ATI_RSLT queatPercentCGPPP (CHAR *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  T_ACI_PPP_PROT  protocol;
  T_ACI_RETURN    ret;
#endif

  TRACE_FUNCTION("queatPercentCGPPP( )");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_CGPPP;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_percent_cgppp = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret = qAT_PercentCGPPP(srcId, &protocol);
  if (ret EQ AT_FAIL)
  {
    cmdCmeError(CME_ERR_Unknown);
    return (ATI_FAIL);
  }

  sprintf (g_sa, "%s: %d", "%CGPPP", protocol);
  io_sendMessage (srcId, g_sa, ATI_NORMAL_OUTPUT);

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}
/*
+--------------------------------------------------------------------+
| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
| STATE   : finished                    ROUTINE : atPercentCGCLASS   |
+--------------------------------------------------------------------+

  PURPOSE : %CGCLASS command  (GPRS class change)
*/

GLOBAL T_ATI_RSLT setatPercentCGCLASS (CHAR *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *me="+CGCLASS: ";
  T_ACI_RETURN ret;
#endif

  T_PERCENT_CGCLASS m_class = PERCENT_CGCLASS_OMITTED;
  char test_class[3]="";

  TRACE_FUNCTION("setatPercentCGCLASS ()");

  cl = parse (cl,"s", (LONG)3, &test_class );

  switch (*test_class)
  {
    case 'A':
      break;
    case 'B':
      switch(*(test_class + 1))
      {
        case 'G':
          m_class = PERCENT_CGCLASS_BG;
          break;
        case 'C':
          m_class = PERCENT_CGCLASS_BC;
          break;
        case 'X':
          m_class = PERCENT_CGCLASS_BX;
          break;
        case '\0':
          m_class = PERCENT_CGCLASS_B;
          break;
        default:
          break;
      }
      break;
    case 'C':
      switch(*(test_class + 1))
      {
        case 'G':
          m_class = PERCENT_CGCLASS_CG;
          break;
        case 'C':
          m_class = PERCENT_CGCLASS_CC;
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

  if ( !cl OR m_class == PERCENT_CGCLASS_OMITTED )
  {
    cmdCmeError(CME_ERR_OpNotAllow);
    return (ATI_FAIL);
  }

#ifdef FF_ATI_BAT

  {
    T_BAT_cmd_send cmd;
    T_BAT_cmd_set_percent_cgclass cgclass;

    cmd.ctrl_params = BAT_CMD_SET_PERCENT_CGCLASS;
    cmd.params.ptr_set_percent_cgclass=&cgclass;

    /*
    *   BAT and ACI versions of mobile class are different enough
    *   to require this conversion.
    */

    /*
    *   This relies on T_BAT_p_mobile_class and T_PERCENT_CGCLASS
    *   being identical.
    */
    cgclass.p_mobile_class=(T_BAT_p_mobile_class)m_class;

    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }

#else

  ret = sAT_PercentCGCLASS ( srcId, m_class );
  if (ret EQ AT_FAIL)
  {
     cmdCmeError (CME_ERR_OpNotAllow);
     return (ATI_FAIL);
  }
  return (map_aci_2_ati_rslt(ret));

#endif
}

GLOBAL T_ATI_RSLT queatPercentCGCLASS (CHAR *cl, UBYTE srcId)
{
#ifndef FF_ATI_BAT
  char *classes[] = {"A","B","BG","BC","BX","CG","CC"};
  T_ACI_RETURN ret;
  T_PERCENT_CGCLASS m_class, currentClass;
  char test_class[3]="";
#endif

  TRACE_FUNCTION("queatPercentCGCLASS ()");

#ifdef FF_ATI_BAT
  {
    T_BAT_cmd_send cmd;
    T_BAT_no_parameter dummy;

    cmd.ctrl_params = BAT_CMD_QUE_PERCENT_CGCLASS;
    dummy.bat_dummy = 0xFF;
    cmd.params.ptr_que_plus_cgclass = &dummy;
    bat_send(ati_bat_get_client(srcId), &cmd);
    return(ATI_EXCT);
  }
#else

  ret = qAT_PercentCGCLASS(srcId, &m_class, &currentClass);
  if (ret EQ AT_CMPL)
  {
    if(m_class NEQ currentClass)
    {
      sprintf(g_sa,"%s: \"%s\",\"%s\"", "%CGCLASS", classes[m_class], classes[currentClass]);
    }
    else
    {
      sprintf(g_sa,"%s: \"%s\"", "%CGCLASS", classes[m_class]);
    }
    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
  }

  return (map_aci_2_ati_rslt(ret));

#endif /*FF_ATI_BAT*/
}
#endif /* GPRS */

