view src/aci2/aci/ati_gprs.c @ 600:8f50b202e81f

board preprocessor conditionals: prep for more FC hw in the future This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and all preprocessor conditionals throughout the code base that tested for it, replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These new symbols are specified as follows: CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by Mother Mychaela under the FreeCalypso trademark. This family will include modem products (repackagings of the FCDEV3B, possibly with RFFE or even RF transceiver changes), and also my desired FreeCalypso handset product. CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products (which will be firmware-compatible with the FCDEV3B if they use TI Rita transceiver, or will require a different fw build if we switch to one of Silabs Aero transceivers), but not the handset product. Right now this CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize everything dealing with MCSI. At the present moment the future of FC hardware evolution is still unknown: it is not known whether we will ever have any beyond-FCDEV3B hardware at all (contingent on uncertain funding), and if we do produce further FC hardware designs, it is not known whether they will retain the same FIC modem core (triband), if we are going to have a quadband design that still retains the classic Rita transceiver, or if we are going to switch to Silabs Aero II or some other transceiver. If we produce a quadband modem that still uses Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination, and the current fcdev3b build target will be renamed to fcmodem. OTOH, if that putative quadband modem will be Aero-based, then it will require a different fw build target, the fcdev3b target will stay as it is, and the two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM, but will have different RF_FAM numbers. But no matter which way we are going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B in places like ACI, and the present change clears the way for future evolution.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 01 Apr 2019 01:05:24 +0000
parents 93999a60b835
children
line wrap: on
line source

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