diff src/g23m-aci/aci/ati_gprs.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-aci/aci/ati_gprs.c	Fri Oct 16 06:25:50 2020 +0000
@@ -0,0 +1,4965 @@
+/*
++-----------------------------------------------------------------------------
+|  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"
+
+#include "cmh.h"
+#include "cmh_sm.h"
+
+#include "aci_io.h"
+#include "aci_mem.h"
+
+#if defined(FF_WAP) OR defined (FF_GPF_TCPIP)  OR defined (FF_SAT_E)
+#include "gaci_srcc.h"
+#include "psa_tcpip.h"
+#include "wap_aci.h"
+#endif /* defined(FF_WAP) OR defined (FF_GPF_TCPIP)  OR defined (FF_SAT_E)*/
+
+#include "gaci_cmd.h"
+#include "cmh_gppp.h"
+#include "psa_gppp.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);
+LOCAL 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);
+#ifdef REL99
+GLOBAL T_ATI_RSLT queatPlusCGEQREQ (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT queatPlusCGEQMIN (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT queatPlusCGTFT   (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT queatPlusCGDSCONT(char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT tesatPlusCGEQNEG (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT tesatPlusCGCMOD  (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT tesatPlusCGTFT   (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT tesatPlusCGDSCONT(char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT setatPlusCGEQMIN (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT setatPlusCGEQREQ (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT setatPlusCGEQNEG (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT setatPlusCGCMOD  (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT setatPlusCGTFT   (char *cl, UBYTE srcId);
+GLOBAL T_ATI_RSLT setatPlusCGDSCONT(char *cl, UBYTE srcId);
+#endif
+
+EXTERN char *parseDSNP_U16      (char blocks, char *p_in, U16 *p_out);
+EXTERN char *parseIPv4Address(char *p_in, U8 * p_ip_addr, U8 * is_ip_valid);
+EXTERN char *parseIPv6Address(char *p_in, U8 * p_ip_addr, U8 * is_ip_valid);
+
+EXTERN T_PDP_CONTEXT_INTERNAL *p_pdp_context_list;
+
+
+/*
++------------------------------------------------------------------------------------+
+| 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;
+  U8            valid_ip;
+  U8            cid          = PDP_CONTEXT_CID_OMITTED;  
+  char         *p_pdp_addr   = NULL;
+  USHORT        pdp_addr_len = 0;
+  
+  T_PDP_CONTEXT pdp_context_input = { "",
+                                      MAGIC_EMPTY_APN,
+                                      NAS_is_ip_not_present, 0,
+                                      PDP_CONTEXT_D_COMP_OMITTED, 
+                                      PDP_CONTEXT_H_COMP_OMITTED,
+                                      PDP_CONTEXT_CID_OMITTED };
+
+  
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+  TRACE_FUNCTION("setatPlusCGDCONT ()");
+
+  cl = parse( cl, "csslcc", &cid,
+                            (LONG)MAX_PDP_CONTEXT_TYPE_LEN, &pdp_context_input.pdp_type,
+                            (LONG)MAX_PDP_CONTEXT_APN_LEN,  &pdp_context_input.pdp_apn,
+                            &pdp_addr_len,                  &p_pdp_addr,
+                            &pdp_context_input.d_comp,
+                            &pdp_context_input.h_comp);
+
+  if (!strcmp(pdp_context_input.pdp_apn, MAGIC_EMPTY_APN))
+  {
+    /* if APN was ommitted then parse leaves the string untouched */
+    pdp_context_input.pdp_apn[0]='\0';    /* so clear the apn */
+  }
+  else if (pdp_context_input.pdp_apn[0] EQ '\0')
+  {
+    /* if entered APN was "", parse clears the buffer */
+    strcpy(pdp_context_input.pdp_apn, MAGIC_EMPTY_APN);  /* fill magic empty apn */
+  }
+
+  if ( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+  strupper( (char*) &pdp_context_input.pdp_type);
+
+  /* Issue 27081 - GPRS context is transformed from lower cases into upper cases */
+  /* strupper( (char*) &pdp_context_input.pdp_apn ); */
+
+  if( p_pdp_addr )
+  {
+    if( pdp_addr_len >= 7 AND pdp_addr_len <= 15 )
+    {
+      p_pdp_addr = parseIPv4Address( p_pdp_addr, (U8*) &(pdp_context_input.pdp_addr.ip_address.ipv4_addr.a4), &valid_ip);
+      if (valid_ip NEQ 0)
+      {
+        pdp_context_input.pdp_addr.ctrl_ip_address = NAS_is_ipv4;
+      }
+      else
+      {
+        /* If the IP address is not valid then we should send ERROR message. */
+        cmdCmeError(CME_ERR_OpNotAllow);
+        return (ATI_FAIL);
+      }
+    }
+    else
+    {
+      if( pdp_addr_len >= 31 AND pdp_addr_len <= 63 )
+      {
+        p_pdp_addr = parseIPv6Address( p_pdp_addr, (U8*) &(pdp_context_input.pdp_addr.ip_address.ipv6_addr.a6), &valid_ip);
+        if (valid_ip NEQ 0)
+        {
+          pdp_context_input.pdp_addr.ctrl_ip_address = NAS_is_ipv6;
+        }
+        else
+        {
+          /* If the IP address is not valid then we should send ERROR message. */
+          cmdCmeError(CME_ERR_OpNotAllow);
+          return (ATI_FAIL);
+        }
+      }
+      else
+      {
+        cmdCmeError(CME_ERR_OpNotAllow);
+        return (ATI_FAIL);
+      }
+    }
+  }
+  else
+  {
+    if( pdp_addr_len NEQ 0 )
+    {
+      cmdCmeError(CME_ERR_OpNotAllow);
+      return (ATI_FAIL);
+    }
+    else
+    {
+      //if pdp_addr is omitted, ctrl must be set to not present...
+      pdp_context_input.pdp_addr.ctrl_ip_address = NAS_is_ip_not_present;
+    }
+  }
+
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_cgdcont cgdcont;
+
+    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGDCONT;
+    cmd.params.ptr_set_plus_cgdcont = &cgdcont;
+
+    cgdcont.cid=(T_BAT_pdp_cid)cid;
+
+    /* currently both IPv4,IPV6 supported */
+    if (!utl_strcasecmp((const char *)pdp_context_input.pdp_type, 
+                        (const char *)"ip"))
+      cgdcont.pdp_type = BAT_PDP_TYPE_IPV4;
+    else if (!utl_strcasecmp((const char *)pdp_context_input.pdp_type,
+                             (const char *)"ipv6"))
+      cgdcont.pdp_type = BAT_PDP_TYPE_IPV6;
+    else
+      cgdcont.pdp_type = BAT_PDP_TYPE_NOT_PRESENT;
+    
+    /* apn value = "" */
+    if (!strcmp(pdp_context_input.pdp_apn, MAGIC_EMPTY_APN))
+    {
+      cgdcont.v_apn = TRUE;
+      cgdcont.c_apn = 0;
+    }
+    /* apn value omitted */
+    else if (pdp_context_input.pdp_apn[0] EQ '\0')
+    {
+      cgdcont.v_apn = FALSE;
+    }
+    /* apn with valid value (longer than 0) */
+    else
+    {
+      cgdcont.v_apn = TRUE;
+      cgdcont.c_apn = (U8)strlen(pdp_context_input.pdp_apn);
+      memcpy(cgdcont.apn,pdp_context_input.pdp_apn, cgdcont.c_apn);
+    }
+    
+        
+    if (pdp_addr_len)
+    {
+      cgdcont.v_pdp_addr = TRUE;
+      cgdcont.c_pdp_addr = (U8)pdp_addr_len;
+      memcpy(cgdcont.pdp_addr,p_pdp_addr,pdp_addr_len);
+    }
+    else
+    {
+      cgdcont.v_pdp_addr = FALSE;
+      cgdcont.c_pdp_addr = 0;
+    }
+    
+    cgdcont.d_comp = (T_BAT_plus_cgdcont_d_comp)pdp_context_input.d_comp;
+    cgdcont.h_comp = (T_BAT_plus_cgdcont_h_comp)pdp_context_input.h_comp;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    src_params->curAtCmd=AT_CMD_CGDCONT;
+    return(ATI_EXCT);
+  }
+#else
+  ret = sAT_PlusCGDCONT((T_ACI_CMD_SRC)srcId, cid, &pdp_context_input );
+  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
+  T_ACI_RETURN ret = AT_FAIL;
+  T_PDP_CONTEXT pdp_context_array[PDP_CONTEXT_CID_MAX];
+  SHORT         pdp_context_cid_array[PDP_CONTEXT_CID_MAX];
+  char          pdp_addr[64];
+  char          message[255];
+  int           i=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
+
+  memset( &pdp_context_array, 0, sizeof(pdp_context_array) );
+  memset( &pdp_context_cid_array, PDP_CONTEXT_CID_OMITTED, sizeof(pdp_context_cid_array) );
+
+  ret = qAT_PlusCGDCONT((T_ACI_CMD_SRC)srcId, pdp_context_array, pdp_context_cid_array);
+
+  if (ret EQ AT_CMPL)
+  {
+    for ( i = 0; i < PDP_CONTEXT_CID_MAX AND pdp_context_cid_array[i] NEQ PDP_CONTEXT_CID_OMITTED; i++ )
+    {
+      if( pdp_context_addr_omitted(&(pdp_context_array[i].pdp_addr) ) )
+      {
+        sprintf( pdp_addr,"\"\"");
+      }
+      else
+      {
+        if( pdp_context_array[i].pdp_addr.ctrl_ip_address EQ NAS_is_ipv4 )
+        {
+          /* IP v4 address */
+          sprintf( pdp_addr, "\"%d.%d.%d.%d\"", 
+                             pdp_context_array[i].pdp_addr.ip_address.ipv4_addr.a4[0],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv4_addr.a4[1],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv4_addr.a4[2],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv4_addr.a4[3] );
+        }
+        else
+        {
+          /* IP v6 address */
+          sprintf( pdp_addr, "\"%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\"", 
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[0],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[1],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[2],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[3],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[4],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[5],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[6],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[7],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[8],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[9],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[10],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[11],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[12],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[13],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[14],
+                             pdp_context_array[i].pdp_addr.ip_address.ipv6_addr.a6[15] );
+        }
+        
+      }
+
+      if( pdp_context_apn_omitted( pdp_context_array[i].pdp_apn ) )
+      {
+        sprintf( message, "+CGDCONT: %d,\"%s\",,%s,%d,%d",
+                          pdp_context_cid_array[i],
+                          pdp_context_array[i].pdp_type,
+                          pdp_addr,
+                          pdp_context_array[i].d_comp,
+                          pdp_context_array[i].h_comp );
+      }
+      else if (!strcmp(pdp_context_array[i].pdp_apn, MAGIC_EMPTY_APN)) 
+      { /* special empty APN detected, printout "" */
+        sprintf( message, "+CGDCONT: %d,\"%s\",\"\",%s,%d,%d",
+                          pdp_context_cid_array[i],
+                          pdp_context_array[i].pdp_type,
+                          pdp_addr,
+                          pdp_context_array[i].d_comp,
+                          pdp_context_array[i].h_comp );
+      }
+      else
+      {
+        sprintf( message, "+CGDCONT: %d,\"%s\",\"%s\",%s,%d,%d",
+                          pdp_context_cid_array[i],
+                          pdp_context_array[i].pdp_type,
+                          pdp_context_array[i].pdp_apn,
+                          pdp_addr,
+                          pdp_context_array[i].d_comp,
+                          pdp_context_array[i].h_comp );
+      }
+                        
+      io_sendMessage(srcId, message, ATI_NORMAL_OUTPUT);
+
+    }
+  }
+  else
+  {
+    cmdCmeError(CME_ERR_Unknown);
+    return (ATI_FAIL);
+  }
+
+  return (ATI_CMPL);
+#endif /*FF_ATI_BAT*/
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT :                             MODULE  : GACI_CMD           |
+| STATE   : finnished                   ROUTINE : testatPlusCGDCONT  |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGQREQ  command (context QOS request)
+*/
+
+GLOBAL T_ATI_RSLT tesatPlusCGDCONT  (char *cl, UBYTE srcId)
+{
+  char *me = "+CGDCONT: ";
+
+  sprintf( g_sa, "%s(1-%d),\"IP\",,,(0),(0-3)", me, PDP_CONTEXT_CID_MAX );
+  io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT );
+
+  sprintf( g_sa, "%s(1-%d),\"IPV6\",,,(0),(0-3)", me, PDP_CONTEXT_CID_MAX );
+  io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT );
+  
+  /* As for EDGE we are not supporting PDP_Type as "PPP" */
+/*  sprintf( g_sa, "%s(1-%d),\"PPP\",,,(0-2),(0-3)", me, PDP_CONTEXT_CID_MAX );
+  io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT );*/
+
+  return (ATI_CMPL);
+}
+
+#ifdef REL99
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   :                             ROUTINE : atPlusCGDSCONT     |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGDSCONT command ( secondary PDP context definition )
+*/
+
+GLOBAL T_ATI_RSLT setatPlusCGDSCONT( char *cl, UBYTE srcId )
+{
+
+  U8 cid = PDP_CONTEXT_CID_OMITTED;
+
+ 
+  T_PDP_CONTEXT pdp_context_input = { "",
+                                      "", 
+                                      NAS_is_ip_not_present,0,
+                                      PDP_CONTEXT_D_COMP_OMITTED, 
+                                      PDP_CONTEXT_H_COMP_OMITTED,
+                                      PDP_CONTEXT_CID_OMITTED }; 
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+  TRACE_FUNCTION("setatPlusCGDSCONT ()");
+
+  cl = parse( cl, "cccc", 
+                  &cid,
+                  &(pdp_context_input.p_cid),
+                  &pdp_context_input.d_comp,
+                  &pdp_context_input.h_comp);
+
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_cgdscont cgdscont;
+    
+    cmd.ctrl_params  = BAT_CMD_SET_PLUS_CGDSCONT;
+    cmd.params.ptr_set_plus_cgdscont = &cgdscont;
+
+    cgdscont.cid=(T_BAT_pdp_cid)cid;
+    cgdscont.p_cid = (U8)pdp_context_input.p_cid;
+
+    cgdscont.d_comp = (T_BAT_plus_cgdcont_d_comp)pdp_context_input.d_comp;
+    cgdscont.h_comp = (T_BAT_plus_cgdcont_d_comp)pdp_context_input.h_comp;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    src_params->curAtCmd=AT_CMD_CGDSCONT;
+    return(ATI_EXCT);
+}
+#else
+  switch( sAT_PlusCGDSCONT(( T_ACI_CMD_SRC)srcId, cid , &pdp_context_input) )
+  {
+    case (AT_CMPL):                   /*operation completed*/
+      return (ATI_CMPL);
+    case (AT_EXCT):     
+//      curAtCmd    = AT_CMD_CGDSCONT;  /*operation in progress*/
+      return (ATI_EXCT);
+    default:
+      cmdCmeError(CME_ERR_Unknown);   /*Command failed*/
+      return (ATI_FAIL);
+  }
+
+
+#endif /* FF_ATI_BAT */
+
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   :                             ROUTINE : queatPlusCGDSCONT  |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGDSCONT=? command
+*/
+
+GLOBAL T_ATI_RSLT queatPlusCGDSCONT( char *cl, UBYTE srcId )
+{
+  T_ACI_RETURN  ret;
+  T_PDP_CONTEXT pdp_context_array[PDP_CONTEXT_CID_MAX];
+  U8            pdp_context_cid_array[PDP_CONTEXT_CID_MAX];
+  int           i;
+
+  TRACE_FUNCTION("queatPlusCGDSCONT ()");
+#ifdef FF_ATI_BAT
+{
+    T_BAT_cmd_send cmd;
+    T_BAT_no_parameter dummy;
+
+    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGDSCONT;
+    dummy.bat_dummy = 0xFF;
+    cmd.params.ptr_set_plus_cgdscont = &dummy;
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    return(ATI_EXCT);
+}
+#else
+
+  memset( &pdp_context_cid_array, PDP_CONTEXT_CID_OMITTED, sizeof(pdp_context_cid_array) );
+
+  ret = qAT_PlusCGDSCONT(( T_ACI_CMD_SRC)srcId, pdp_context_array, pdp_context_cid_array);
+
+  if (ret EQ AT_CMPL)
+  {
+    for ( i = 0; i < PDP_CONTEXT_CID_MAX AND pdp_context_cid_array[i] NEQ PDP_CONTEXT_CID_OMITTED; i++ )
+    {
+      sprintf( g_sa, "+CGDSCONT: %d,%d,%d,%d",
+                     pdp_context_cid_array[i],
+                     pdp_context_array[i].p_cid,
+                     pdp_context_array[i].d_comp,
+                     pdp_context_array[i].h_comp );
+
+      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    }
+  }
+  else
+  {
+    cmdCmeError(CME_ERR_Unknown);
+    return (ATI_FAIL);
+  }
+
+  return (ATI_CMPL);
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   :                             ROUTINE : testatPlusCGDSCONT |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGDSCONT?
+*/
+
+GLOBAL T_ATI_RSLT tesatPlusCGDSCONT( char *cl, UBYTE srcId )
+{
+  char me[50];
+  char cid_list[PDP_CONTEXT_CID_MAX + 1];
+  BOOL active = FALSE;
+  U8   i        = 0;
+  U8   cid;
+
+  cid_list[0] = 0;
+
+  me[0] = 0;
+
+  for( cid = PDP_CONTEXT_CID_MIN; cid <= PDP_CONTEXT_CID_MAX; cid++ )
+  {
+    if( tAT_PlusCGDSCONT(( T_ACI_CMD_SRC) srcId, cid, &active ) EQ AT_CMPL )
+    {
+      if( active EQ TRUE )
+      {
+        cid_list[i] = cid;
+        i++;
+        cid_list[i] = 0;
+      }      
+    }
+    else
+    {
+      cmdCmeError( CME_ERR_Unknown );
+      return (ATI_FAIL);
+    }
+  }
+
+  i = 0;
+  sprintf( me, "+CGDSCONT: (1-%d),", PDP_CONTEXT_CID_MAX);
+
+  if( cid_list[i] NEQ 0 )
+  {
+    sprintf( me, "%s(%d", me, cid_list[i] );
+    i++;
+  
+    while( cid_list[i] NEQ 0 )
+    {
+      sprintf( me, "%s,%d", me, cid_list[i] );
+      i++;
+    }
+  }
+
+  if( cid_list[0] NEQ 0 )
+  {
+    sprintf( me, "%s)", me );
+  }
+  
+
+  /* As for EDGE we are not supporting PDP_Type as "PPP" */
+  /*sprintf( g_sa, "%s,\"PPP\",(0-1),(0-1)", me );
+  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);*/
+
+  sprintf( g_sa, "%s,\"IP\",(0),(0-1)", me );
+  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+  
+  sprintf( g_sa, "%s,\"IPV6\",(0),(0-1)", me );
+  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+
+  return (ATI_CMPL);
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   :                             ROUTINE : atPlusCGTFT        |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGTFT command ( Traffic Flow Template definition )
+*/
+
+GLOBAL T_ATI_RSLT setatPlusCGTFT( char *cl, UBYTE srcId )
+{
+  U8       cid                         = 0;
+  U8       protocol_or_next_header     = 0;
+  U8       is_ip_valid                 = FALSE;
+  U16      tos_value                   = 0;
+  U16      tos_mask                    = 0;
+  U32      ipsec_spi                   = 0;
+  U32      flow_label                  = 0;
+
+  char     *p_addr_n_mask_str          = NULL;
+  char     *p_dest_port_range_str      = NULL;
+  char     *p_src_port_range_str       = NULL;
+  char     *p_tos_mask_or_tc_mask_str  = NULL;
+
+  USHORT   addr_n_mask_str_len         = 0;
+  USHORT   dest_port_range_str_len     = 0;
+  USHORT   src_port_range_str_len      = 0;
+  USHORT   tos_mask_or_tc_mask_str_len = 0;
+  T_NAS_tft_pf  tft_pf_input;
+
+#ifdef FF_ATI_BAT
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+#endif
+    
+  TRACE_FUNCTION("setatPlusCGTFT ()");
+
+  memset( &tft_pf_input, 0x00, sizeof(T_NAS_tft_pf) );
+  
+//                 +------------  1: <cid>
+//                 |+-----------  2: <packet filter identifier>
+//                 ||+----------  3: <evaluation precedence index>
+//                 |||+---------  4: <source address and sub met mask>
+//                 ||||+--------  5: <protocol number (IPv4) / next header (IPv6)>
+//                 |||||+-------  6: <destenation port range>
+//                 ||||||+------  7: <source port range>
+//                 |||||||+-----  8: <ipsec security parameter index (SPI)>
+//                 ||||||||+----  9: <type of service and mask (IPv4) / traffic class and mask (IPv6)>
+//                 |||||||||+--- 10: <flow label (IPv6)>
+//                 ||||||||||    
+  cl = parse( cl, "ccclcllyly",
+                  &cid,                                                     /*  1 */
+                  &tft_pf_input.tft_pf_id,                                  /*  2 */
+                  &tft_pf_input.tft_pf_precedence,                          /*  3 */
+                  &addr_n_mask_str_len,         &p_addr_n_mask_str,         /*  4 */
+                  &protocol_or_next_header,                                 /*  5 */
+                  &dest_port_range_str_len,     &p_dest_port_range_str,     /*  6 */
+                  &src_port_range_str_len,      &p_src_port_range_str,      /*  7 */
+                  &ipsec_spi,                                               /*  8 */
+                  &tos_mask_or_tc_mask_str_len, &p_tos_mask_or_tc_mask_str, /*  9 */
+                  &flow_label                                               /* 10 */
+                  );
+
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+  if( !p_addr_n_mask_str )
+  {
+    /* IP address and mask is omitted */
+      
+    if( flow_label EQ 0 )
+    {
+      /* IP v4 type */
+      tft_pf_input.ctrl_tft_pf_entry = NAS_is_tft_pf_ipv4;
+    }
+    else
+    {
+      /* IP v6 type */
+      tft_pf_input.ctrl_tft_pf_entry  = NAS_is_tft_pf_ipv6;
+      tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_FLOW_LABEL;
+    }
+  }
+  else
+  {
+
+    if( addr_n_mask_str_len >= 15 AND addr_n_mask_str_len <= 31 )
+    {
+      // The length of the string is within the length of an IP v4 string.
+
+      if( flow_label EQ 0 )
+      {
+        tft_pf_input.ctrl_tft_pf_entry = NAS_is_tft_pf_ipv4;
+            
+        // Parse IP v4 address 
+        p_addr_n_mask_str = parseIPv4Address( p_addr_n_mask_str,
+                                              (U8*) &(tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_addr), &is_ip_valid );
+        // Parse IP v4 sub net mask
+        p_addr_n_mask_str = parseIPv4Address( p_addr_n_mask_str,
+                                                (U8*) &(tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_mask), &is_ip_valid);
+      
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_IPv4_SRC_ADDR_MASK;
+      }
+      else
+      {
+        cmdCmeError(CME_ERR_OpNotAllow);
+        return (ATI_FAIL);
+      }
+    }
+    else
+    {
+      if( addr_n_mask_str_len >= 63 AND addr_n_mask_str_len <= 127 )
+      {
+        // The length of the string is within the length of an IP v6 string.
+
+        tft_pf_input.ctrl_tft_pf_entry = NAS_is_tft_pf_ipv6;
+        tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_flow_label = flow_label;
+
+        // Parse IP v6 address 
+        p_addr_n_mask_str = parseIPv6Address( p_addr_n_mask_str,
+                                              (U8*) &(tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr), &is_ip_valid );
+        // Parse IP v4 sub net mask
+        p_addr_n_mask_str = parseIPv6Address( p_addr_n_mask_str,
+                                              (U8*) &(tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask), &is_ip_valid );
+          
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_IPv6_SRC_ADDR_MASK;
+      }
+      else
+      {
+        cmdCmeError(CME_ERR_OpNotAllow);
+        return (ATI_FAIL);
+      }
+    }
+      
+    if( !p_addr_n_mask_str )
+    {
+      cmdCmeError(CME_ERR_OpNotAllow);
+      return (ATI_FAIL);
+    }
+  } /* END: if( !p_addr_n_mask_str ) */
+
+  switch( tft_pf_input.ctrl_tft_pf_entry )
+  {
+    /*** IP v4 parameters */
+    case NAS_is_tft_pf_ipv4:
+    {   
+      if( protocol_or_next_header )
+      {
+        tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_protocol = protocol_or_next_header;
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_PROTOCOL_OR_NEXT_HDR;        
+      }
+    
+      /* Type of service and mask */
+      if( p_tos_mask_or_tc_mask_str )
+      {
+        p_tos_mask_or_tc_mask_str = parseDSNP_U16( 1, p_tos_mask_or_tc_mask_str, 
+                                                   &tos_value );
+
+        tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_tos_and_mask.tos_value = (U8)tos_value;
+
+
+        p_tos_mask_or_tc_mask_str = parseDSNP_U16( 1, p_tos_mask_or_tc_mask_str, 
+                                                   &tos_mask );
+        
+        tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_tos_and_mask.tos_mask = (U8)tos_mask;
+        
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_TOS_AND_MASK;        
+      }
+
+      /* Destenation port */
+      if( p_dest_port_range_str )
+      {
+        p_dest_port_range_str = parseDSNP_U16( 1, p_dest_port_range_str, 
+                                               (U16*) &tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_dest_port_range.low_limit );
+        p_dest_port_range_str = parseDSNP_U16( 1, p_dest_port_range_str, 
+                                               (U16*) &tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_dest_port_range.high_limit );
+
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_DEST_PORT_RANGE;
+      }
+        
+      /* Source port */
+      if( p_src_port_range_str )
+      {
+        p_src_port_range_str = parseDSNP_U16( 1, p_src_port_range_str, 
+                                              (U16*)&tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_src_port_range.low_limit );
+        p_src_port_range_str = parseDSNP_U16( 1, p_src_port_range_str, 
+                                              (U16*)&tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_src_port_range.high_limit );
+
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_SRC_PORT_RANGE;
+      }
+        
+      /* IPSEC security parameter spi */
+      if( ipsec_spi )
+      {
+        tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_ipsec_spi = ipsec_spi;
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_IPSEC_SPI;
+      }
+      break;
+
+    } /* END: case NAS_is_tft_pf_ipv4 */
+
+
+    /*** IP v6 parameters ***/
+    case NAS_is_tft_pf_ipv6:
+    {
+      /* Next header */
+      if ( protocol_or_next_header )
+      {
+        tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_next_hdr = protocol_or_next_header;
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_PROTOCOL_OR_NEXT_HDR;
+      }
+
+      /* Type of service and mask */
+      if ( p_tos_mask_or_tc_mask_str )
+      {
+        p_tos_mask_or_tc_mask_str = parseDSNP_U16( 1, p_tos_mask_or_tc_mask_str, 
+                                                 &tos_value );
+
+        tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_tos_and_mask.tos_value = (U8)tos_value;
+        
+        p_tos_mask_or_tc_mask_str = parseDSNP_U16( 1, p_tos_mask_or_tc_mask_str, 
+                                                 &tos_mask );
+
+        tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_tos_and_mask.tos_mask = (U8)tos_mask;
+        
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_TOS_AND_MASK;
+      }
+
+
+      /* Destenation port */
+      if ( p_dest_port_range_str )
+      {
+        p_dest_port_range_str = parseDSNP_U16( 1, p_dest_port_range_str, 
+                                             (U16*)&tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_dest_port_range.low_limit );
+        p_dest_port_range_str = parseDSNP_U16( 1, p_dest_port_range_str, 
+                                             (U16*)&tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_dest_port_range.high_limit );
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_DEST_PORT_RANGE;
+      }
+      
+      /* Source port */
+      if ( p_src_port_range_str )
+      {
+        p_src_port_range_str = parseDSNP_U16( 1, p_src_port_range_str, 
+                                            (U16*)&tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_src_port_range.low_limit );
+        p_src_port_range_str = parseDSNP_U16( 1, p_src_port_range_str, 
+                                            (U16*)&tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_src_port_range.high_limit );
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_SRC_PORT_RANGE;
+      }
+
+      /* IPSEC security parameter spi */
+      if ( ipsec_spi )
+      {
+        tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_ipsec_spi = ipsec_spi;
+        tft_pf_input.tft_pf_valid_bits |= NAS_TFT_ID_IPSEC_SPI;
+      }
+
+      break;
+    } /* END: case NAS_is_tft_pf_ipv6 */
+      
+    default:
+    {
+      cmdCmeError(CME_ERR_OpNotAllow);
+      return (ATI_FAIL);
+    }
+  } /* END: switch( tft_pf_input.ctrl_tft_pf_entry ) */
+
+#ifdef FF_ATI_BAT
+  {  
+    T_BAT_cmd_send              bat_cmd;
+    T_BAT_cmd_set_plus_cgtft bat_cgtft;
+    bat_cmd.ctrl_params                  = BAT_CMD_SET_PLUS_CGTFT;
+    bat_cmd.params.ptr_set_plus_cgtft = &bat_cgtft;
+    
+    bat_cgtft.cid               =  cid;
+    bat_cgtft.tft_pf_id         = tft_pf_input.tft_pf_id;             
+    bat_cgtft.tft_pf_precedence = tft_pf_input.tft_pf_precedence;     
+    bat_cgtft.prt_num_or_nxt_hd = protocol_or_next_header;     
+    
+    /* addr_n_mask */
+    bat_cgtft.v_addr_n_mask = (addr_n_mask_str_len AND
+                               p_addr_n_mask_str);
+
+    if (tft_pf_input.ctrl_tft_pf_entry EQ NAS_is_tft_pf_ipv4)
+    {
+      bat_cgtft.c_addr_n_mask = 2 * NAS_SIZE_IPv4_ADDR;
+      memcpy(bat_cgtft.addr_n_mask,
+             &tft_pf_input.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask,
+             2 * NAS_SIZE_IPv4_ADDR);
+
+      /* dest_port_range */
+      if (tft_pf_input.tft_pf_valid_bits & 
+          NAS_TFT_ID_DEST_PORT_RANGE)
+      {
+        bat_cgtft.v_dest_port_range  = TRUE;
+        bat_cgtft.c_dest_port_range  = 2;
+        bat_cgtft.dest_port_range[0] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv4.tft_dest_port_range.low_limit;
+        bat_cgtft.dest_port_range[1] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv4.tft_dest_port_range.high_limit;
+      }    
+
+      /* src_port_range */
+      if (tft_pf_input.tft_pf_valid_bits & 
+          NAS_TFT_ID_SRC_PORT_RANGE)
+      {
+        bat_cgtft.v_src_port_range  = TRUE;
+        bat_cgtft.c_src_port_range  = 2;
+        bat_cgtft.src_port_range[0] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv4.tft_src_port_range.low_limit;
+        bat_cgtft.src_port_range[1] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv4.tft_src_port_range.high_limit;
+      }    
+
+      /* tos_mask_or_tc_mask */
+      if (tft_pf_input.tft_pf_valid_bits &
+          NAS_TFT_ID_TOS_AND_MASK)
+      {
+        bat_cgtft.v_tos_mask_or_tc_mask  = TRUE;
+        bat_cgtft.c_tos_mask_or_tc_mask  = 2;
+        bat_cgtft.tos_mask_or_tc_mask[0] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv4.tft_tos_and_mask.tos_value;
+        bat_cgtft.tos_mask_or_tc_mask[1] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv4.tft_tos_and_mask.tos_mask;
+      }
+    }
+    else if (tft_pf_input.ctrl_tft_pf_entry EQ NAS_is_tft_pf_ipv6)
+    {
+      bat_cgtft.c_addr_n_mask = 2 * NAS_SIZE_IPv6_ADDR;
+      memcpy(bat_cgtft.addr_n_mask,
+             &tft_pf_input.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask,
+             2 * NAS_SIZE_IPv6_ADDR);
+
+      /* dest_port_range */
+      if (tft_pf_input.tft_pf_valid_bits & 
+          NAS_TFT_ID_DEST_PORT_RANGE)
+      {
+        bat_cgtft.v_dest_port_range  = TRUE;
+        bat_cgtft.c_dest_port_range  = 2;
+        bat_cgtft.dest_port_range[0] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv6.tft_dest_port_range.low_limit;
+        bat_cgtft.dest_port_range[1] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv6.tft_dest_port_range.high_limit;
+      }    
+
+      /* src_port_range */
+      if (tft_pf_input.tft_pf_valid_bits & 
+          NAS_TFT_ID_SRC_PORT_RANGE)
+      {
+        bat_cgtft.v_src_port_range  = TRUE;
+        bat_cgtft.c_src_port_range  = 2;
+        bat_cgtft.src_port_range[0] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv6.tft_src_port_range.low_limit;
+        bat_cgtft.src_port_range[1] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv6.tft_src_port_range.high_limit;
+      }    
+
+      /* tos_mask_or_tc_mask */
+      if (tft_pf_input.tft_pf_valid_bits &
+          NAS_TFT_ID_TOS_AND_MASK)
+      {
+        bat_cgtft.v_tos_mask_or_tc_mask  = TRUE;
+        bat_cgtft.c_tos_mask_or_tc_mask  = 2;
+        bat_cgtft.tos_mask_or_tc_mask[0] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv6.tft_tos_and_mask.tos_value;
+        bat_cgtft.tos_mask_or_tc_mask[1] = tft_pf_input.tft_pf_entry.
+          tft_pf_ipv6.tft_tos_and_mask.tos_mask;
+      }
+
+    }
+
+    /* ipsec_spi */
+    //bat_cgtft.v_ipsec_spi = tft_pf_input.ipsec_spi_present;
+    bat_cgtft.ipsec_spi   = ipsec_spi;
+    
+                                       
+    /* flow_label */
+    bat_cgtft.flow_label = flow_label;
+
+    bat_send(ati_bat_get_client(srcId), &bat_cmd);
+    src_params->curAtCmd=AT_CMD_CGTFT;
+    return(ATI_EXCT);
+}
+#else
+  switch( sAT_PlusCGTFT( ( T_ACI_CMD_SRC)srcId, cid , &tft_pf_input) )
+  {
+    case (AT_CMPL):                   /* Operation completed */
+      return (ATI_CMPL);
+    case (AT_EXCT):                   /* Operation in progress */
+//      curAtCmd    = AT_CMD_CGTFT; 
+      return (ATI_EXCT);
+    default:
+      cmdCmeError(CME_ERR_Unknown);   /* Command failed */
+      return (ATI_FAIL);
+  }
+
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   :                             ROUTINE : setatPlusCGTFT     |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGTFT=? command
+*/
+
+GLOBAL T_ATI_RSLT queatPlusCGTFT( char *cl, UBYTE srcId )
+{
+  T_ACI_RETURN            ret;
+  U8                      pdp_context_cid_array[PDP_CONTEXT_CID_MAX];
+  T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
+  T_TFT_INTERNAL         *p_tft_pf_node = NULL;
+  int                     i = 0;
+  USHORT                  pos = 0;
+
+  TRACE_FUNCTION("queatPlusCGTFT()");
+
+#ifdef FF_ATI_BAT
+{
+    T_BAT_cmd_send cmd;
+    T_BAT_no_parameter dummy;
+
+    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGTFT;
+    dummy.bat_dummy = 0xFF;
+    cmd.params.ptr_set_plus_cgtft = &dummy;
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    return(ATI_EXCT);
+}
+#else
+
+  memset( &pdp_context_cid_array, PDP_CONTEXT_CID_OMITTED, sizeof(pdp_context_cid_array) );
+
+  ret = qAT_PlusCGTFT(( T_ACI_CMD_SRC)srcId, (U8*) &pdp_context_cid_array[0]);
+
+  if (ret EQ AT_CMPL)
+  {
+    for ( i = 0; i < PDP_CONTEXT_CID_MAX AND pdp_context_cid_array[i] NEQ PDP_CONTEXT_CID_OMITTED; i++ )
+    {
+      p_pdp_context_node = pdp_context_find_node_from_cid( pdp_context_cid_array[i] );
+      p_tft_pf_node = p_pdp_context_node->p_tft_pf;
+      while( p_tft_pf_node )
+      {
+        switch( p_tft_pf_node->pf_attributes.ctrl_tft_pf_entry )
+        {
+          case NAS_is_tft_pf_ipv4:
+            pos = sprintf( g_sa, "+CGTFT: %d,%d,%d,",
+                           pdp_context_cid_array[i],
+                           p_tft_pf_node->pf_attributes.tft_pf_id,
+                           p_tft_pf_node->pf_attributes.tft_pf_precedence);
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_IPv4_SRC_ADDR_MASK )
+            {
+              pos += sprintf( g_sa + pos , "\"%d.%d.%d.%d.%d.%d.%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_addr[0],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_addr[1],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_addr[2],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_addr[3],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_mask[0],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_mask[1],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_mask[2],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipv4_src_addr_mask.tft_ipv4_mask[3] );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_PROTOCOL_OR_NEXT_HDR )
+            {
+              pos += sprintf( g_sa + pos, "%d,",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_protocol );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_DEST_PORT_RANGE )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_dest_port_range.low_limit,
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_dest_port_range.high_limit );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_SRC_PORT_RANGE )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_src_port_range.low_limit,
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_src_port_range.high_limit );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_IPSEC_SPI )
+            {
+              pos += sprintf( g_sa + pos, "%X,",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_ipsec_spi );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+              
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_TOS_AND_MASK )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_tos_and_mask.tos_value,
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv4.tft_tos_and_mask.tos_mask );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            break;
+
+          case NAS_is_tft_pf_ipv6:
+            pos = sprintf( g_sa, "+CGTFT: %d,%d,%d,",
+                          pdp_context_cid_array[i],
+                          p_tft_pf_node->pf_attributes.tft_pf_id,
+                          p_tft_pf_node->pf_attributes.tft_pf_precedence);
+            
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_IPv6_SRC_ADDR_MASK )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[0],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[1],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[2],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[3],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[4],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[5],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[6],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[7],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[8],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[9],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[10],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[11],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[12],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[13],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[14],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_addr[15],
+
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[0],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[1],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[2],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[3],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[4],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[5],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[6],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[7],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[8],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[9],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[10],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[11],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[12],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[13],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[14],
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipv6_src_addr_mask.tft_ipv6_mask[15]);
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_PROTOCOL_OR_NEXT_HDR )
+            {
+              pos += sprintf( g_sa + pos, "%d,",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_next_hdr );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_DEST_PORT_RANGE )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_dest_port_range.low_limit,
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_dest_port_range.high_limit );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_SRC_PORT_RANGE )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_src_port_range.low_limit,
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_src_port_range.high_limit );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_IPSEC_SPI )
+            {
+              pos += sprintf( g_sa + pos, "%X,",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_ipsec_spi );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+              
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_TOS_AND_MASK )
+            {
+              pos += sprintf( g_sa + pos, "\"%d.%d\",",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_tos_and_mask.tos_value,
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_tos_and_mask.tos_mask );
+            }
+            else
+            {
+              pos += sprintf( g_sa + pos, "," );
+            }
+
+            if( p_tft_pf_node->pf_attributes.tft_pf_valid_bits & NAS_TFT_ID_FLOW_LABEL )
+            {
+              pos += sprintf( g_sa + pos, "%d",
+                             p_tft_pf_node->pf_attributes.tft_pf_entry.tft_pf_ipv6.tft_flow_label );
+            }
+            
+            break;            
+        }
+
+        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+        p_tft_pf_node = p_tft_pf_node->p_next;
+      }
+      
+    }
+  }
+  else
+  {
+    cmdCmeError(CME_ERR_Unknown);
+    return (ATI_FAIL);
+  }
+
+  return (map_aci_2_ati_rslt(ret));
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   :                             ROUTINE : testatPlusCGTFT    |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGTFT?
+*/
+GLOBAL T_ATI_RSLT tesatPlusCGTFT( char *cl, UBYTE srcId )
+{
+  U8   pf_id_max;
+
+  pf_id_max = TFT_PF_ID_MAX;
+
+  TRACE_FUNCTION("tesatPlusCGTFT()");
+
+  sprintf( g_sa, "+CGTFT: <PDP_type = \"IP\">,   (1-%d),(0-255),\"a1.a2.a3.a4.m1.m2.m3.m4\" (0-255),(0-255),\"f.t\" (0-65535),\"f.t\" (0-65535),(0-FFFFFFFF),\"t.m\" (0-255),(0)", pf_id_max );
+  io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT);
+  
+  sprintf( g_sa, "+CGTFT: <PDP_type = \"IPV6\">, (1-%d),(0-255),\"a1.a2...a15.m1.m2...m15\" (0-255),(0-255),\"f.t\" (0-65535),\"f.t\" (0-65535),(0-FFFFFFFF),\"t.m\" (0-255),(0-FFFF)", pf_id_max );
+  io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT);
+
+  /* As for EDGE we are not supporting PDP_Type as "PPP" */
+  /*sprintf( g_sa, "+CGTFT: <PDP_type = \"PPP\">,  (1-%d),(0-255),\"a1.a2...a15.m1.m2...m15\" (0-255),(0-255),\"f.t\" (0-65535),\"f.t\" (0-65535),(0-FFFFFFFF),\"t.m\" (0-255),(0-FFFF)", pf_id_max );
+  io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT);*/
+
+  return (ATI_CMPL);
+}
+#endif /* REL99 */
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
+| STATE   : finnished                   ROUTINE : setatPlusCGQREQ    |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGQREQ  command (context QOS request)
+*/
+
+GLOBAL T_ATI_RSLT setatPlusCGQREQ (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = AT_FAIL;
+  T_PS_qos     input_qos;
+  U8           cid;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+  TRACE_FUNCTION("setatPlusCGQREQ ()");
+
+  cid = PDP_CONTEXT_CID_OMITTED;
+
+  input_qos.qos_r97.delay    = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.relclass = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.peak     = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.preced   = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.mean     = (U8) PDP_CONTEXT_QOS_OMITTED;
+
+  cl = parse( cl,"caaaar", &cid,
+                           1L ,&input_qos.qos_r97.preced,
+                           1L ,&input_qos.qos_r97.delay,
+                           1L ,&input_qos.qos_r97.relclass,
+                           1L ,&input_qos.qos_r97.peak,
+                           &input_qos.qos_r97.mean );
+  if ( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+  if ( input_qos.qos_r97.preced NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.preced    -= '0';
+  if ( input_qos.qos_r97.delay NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.delay     -= '0';
+  if ( input_qos.qos_r97.relclass NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.relclass  -= '0';
+  if ( input_qos.qos_r97.peak NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.peak      -= '0';
+  if ( input_qos.qos_r97.mean EQ 0xff )
+    input_qos.qos_r97.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;
+    cgqreq.precedence  = (T_BAT_precedence)input_qos.qos_r97.preced;
+    cgqreq.delay       = (T_BAT_delay)input_qos.qos_r97.delay;
+    cgqreq.reliability = (T_BAT_reliability)input_qos.qos_r97.relclass;
+    cgqreq.peak        = (T_BAT_peak)input_qos.qos_r97.peak;
+    cgqreq.mean        = (T_BAT_mean)input_qos.qos_r97.mean;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+
+    src_params->curAtCmd=AT_CMD_CGQREQ;
+    return(ATI_EXCT);
+  }
+#else
+  ret = sAT_PlusCGQREQ ((T_ACI_CMD_SRC)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
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
+| STATE   : finnished                   ROUTINE : queatPlusCGQREQ    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Reading +CGQREQ  command (context QOS request)
+*/
+
+GLOBAL T_ATI_RSLT queatPlusCGQREQ (char *cl, UBYTE srcId)
+{
+#ifndef FF_ATI_BAT
+  T_PS_qos                pdef_qos;
+  BOOL                    qos_valid          = FALSE;
+  T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
+#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
+  p_pdp_context_node = p_pdp_context_list;
+
+  while( p_pdp_context_node )
+  {
+    if (qAT_PlusCGQREQ ((T_ACI_CMD_SRC)srcId, p_pdp_context_node->cid, &qos_valid, &pdef_qos ) EQ AT_CMPL)
+    {
+      if( qos_valid )
+      {
+        sprintf( g_sa, "+CGQREQ: %hd,%d,%d,%d,%d,%d", 
+                       p_pdp_context_node->cid,
+                       pdef_qos.qos_r97.preced,
+                       pdef_qos.qos_r97.delay,
+                       pdef_qos.qos_r97.relclass,
+                       pdef_qos.qos_r97.peak,
+                       pdef_qos.qos_r97.mean );
+
+        io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT );
+      }
+    }
+    else
+    {
+      /* AT_FAIL has been returned */
+      cmdCmeError(CME_ERR_Unknown); /* The command is invalid for srcId */
+      return (ATI_FAIL);
+    }
+
+    p_pdp_context_node = p_pdp_context_node->p_next;
+  }
+
+  return (ATI_CMPL);
+#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_PS_min_qos input_qos;
+  U8           cid;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("setatPlusCGQMIN ()");
+
+  cid = PDP_CONTEXT_CID_OMITTED;
+
+  input_qos.qos_r97.delay    = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.relclass = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.peak     = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.preced   = (U8) PDP_CONTEXT_QOS_OMITTED;
+  input_qos.qos_r97.mean     = (U8) PDP_CONTEXT_QOS_OMITTED;
+
+  cl = parse( cl, "caaaar", &cid,
+                1L, &input_qos.qos_r97.preced,
+              1L, &input_qos.qos_r97.delay,
+              1L, &input_qos.qos_r97.relclass,
+              1L, &input_qos.qos_r97.peak,
+                  &input_qos.qos_r97.mean );
+
+  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.qos_r97.preced;
+   cgqmin.delay       = (T_BAT_delay)input_qos.qos_r97.delay;
+   cgqmin.reliability = (T_BAT_reliability)input_qos.qos_r97.relclass;
+   cgqmin.peak        = (T_BAT_peak)input_qos.qos_r97.peak;
+   cgqmin.mean        = (T_BAT_mean)input_qos.qos_r97.mean;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+
+    src_params->curAtCmd=AT_CMD_CGQMIN;
+    return(ATI_EXCT);
+  }
+
+#else
+
+
+  if ( input_qos.qos_r97.preced NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.preced    -= '0';
+  if ( input_qos.qos_r97.delay NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.delay     -= '0';
+  if ( input_qos.qos_r97.relclass NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.relclass  -= '0';
+  if ( input_qos.qos_r97.peak NEQ PDP_CONTEXT_QOS_OMITTED )
+    input_qos.qos_r97.peak      -= '0';
+  if ( input_qos.qos_r97.mean EQ 0xff )
+    input_qos.qos_r97.mean       = 0;
+
+
+
+  ret = sAT_PlusCGQMIN((T_ACI_CMD_SRC)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
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GPRS (8441)                 MODULE  : GACI_CMD           |
+| STATE   : finished                    ROUTINE : queatPlusCGQMIN    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Reading +CGQMIN command (context min QOS requirement)
+*/
+GLOBAL T_ATI_RSLT queatPlusCGQMIN (char *cl, UBYTE srcId)
+
+{
+#ifndef FF_ATI_BAT
+  T_PS_qos                pdef_qos;
+  BOOL                    qos_valid          = FALSE;
+  T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
+
+#endif
+
+#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
+
+  TRACE_FUNCTION("queatPlusCGQMIN ()");
+
+  p_pdp_context_node = p_pdp_context_list;
+
+  while( p_pdp_context_node )
+  {
+    if( qAT_PlusCGQMIN((T_ACI_CMD_SRC)srcId, p_pdp_context_node->cid, &qos_valid, &pdef_qos ) EQ AT_CMPL )
+    {
+      if (qos_valid)
+      {
+
+        /* In the privous version of alborg code is the paramters are ommited then
+           the code is sending ',' instead of default values. Now it changed 
+         */
+        sprintf( g_sa, "+CGQMIN: %hd,%d,%d,%d,%d,%d", 
+                       p_pdp_context_node->cid,
+                       pdef_qos.qos_r97.preced,
+                       pdef_qos.qos_r97.delay,
+                       pdef_qos.qos_r97.relclass,
+                       pdef_qos.qos_r97.peak,
+                       pdef_qos.qos_r97.mean );
+        io_sendMessage( srcId, g_sa, ATI_NORMAL_OUTPUT );
+      }
+    }
+    else
+    {
+      /* AT_FAIL has been returned */
+      cmdCmeError(CME_ERR_Unknown); /* The command is invalid for srcId */
+      return (ATI_FAIL);
+    }
+
+    p_pdp_context_node = p_pdp_context_node->p_next;
+    
+  }
+
+  return (ATI_CMPL);
+#endif
+}
+
+
+/*
++--------------------------------------------------------------------+
+| 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 ((T_ACI_CMD_SRC)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
+}
+
+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((T_ACI_CMD_SRC)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
+}
+
+
+/*
++--------------------------------------------------------------------+
+| 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)
+{
+  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 OR m_class EQ 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 ((T_ACI_CMD_SRC)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;
+//#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((T_ACI_CMD_SRC)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;
+  U8             count = 0;
+  U8             cid;
+  SHORT             cid_array[PDP_CONTEXT_CID_MAX + 1];
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("setatPlusCGACT ()");
+
+  end = cl;
+
+  if ( *cl NEQ ',' )
+    state = (T_CGACT_STATE) strtol(cl, &end, 10);
+
+  while ( *end EQ ',' )
+  {
+    cl = end;           /* advace to the next delimiter */
+    cl ++;              /* skip the delimiter */
+    cid = PDP_CONTEXT_CID_INVALID;
+
+    cid = (U8) strtol (cl, &end, 10);
+
+    if (cid < PDP_CONTEXT_CID_MIN OR cid > PDP_CONTEXT_CID_MAX OR count > PDP_CONTEXT_CID_MAX)
+    {
+      cmdCmeError(CME_ERR_OpNotAllow);
+      return (ATI_FAIL);
+    }
+    cid_array[count] = cid;
+    count ++;
+  }
+
+  if(count<12)
+  {
+    cid_array[count] = PDP_CONTEXT_CID_INVALID;
+  }
+  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) AND (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 ((T_ACI_CMD_SRC)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;
+  U8    count = 0;
+  SHORT    cid_array[PDP_CONTEXT_CID_MAX + 1];
+  BOOL  states[PDP_CONTEXT_CID_MAX + 1];
+#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((T_ACI_CMD_SRC)srcId, states, cid_array);
+  if (ret EQ AT_CMPL)
+  {
+    for( count = 0; count < PDP_CONTEXT_CID_MAX AND cid_array[count] NEQ PDP_CONTEXT_CID_INVALID; 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;
+  U8 count = 0, stop = 1;
+  U8 cid_array[PDP_CONTEXT_CID_MAX];
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("setatPlusCGDATA ()");
+
+  memset( &cid_array, PDP_CONTEXT_CID_INVALID, sizeof(cid_array) );
+
+  switch ( *cl )
+  {
+    case ',':
+      /* the L2P is unspecified */
+      *L2P = 0;
+      break;
+    case '\"':
+      cl++;
+      while (*cl AND stop)
+      {
+        if ( *cl NEQ '\"' AND 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] = (U8) strtol (cl, &end, 10);
+
+    if ( count >= PDP_CONTEXT_CID_MAX )
+    {
+      cmdCmeError(CME_ERR_OpNotAllow);
+      return (ATI_FAIL);
+    }
+    count ++;
+  }
+
+  cl = end;
+#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) AND (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
+
+
+/*
+ *  if no cid is given or if there is no matching context definition
+ *  the function sAT_PlusCGDATA will process this
+ */
+
+  /* establish communication between the TE and the network */
+  ret = sAT_PlusCGDATA ((T_ACI_CMD_SRC)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: ";
+  char               *end;
+
+  U8                 index = 0;
+#ifndef FF_ATI_BAT
+  T_ACI_RETURN       ret;
+  T_NAS_ip           pdp_addresses[PDP_CONTEXT_CID_MAX];
+#endif
+  SHORT              cid_array[PDP_CONTEXT_CID_MAX + 1];
+
+  TRACE_FUNCTION("setatPlusCGPADDR ()");
+
+  do
+  {
+    cid_array[index] = (U8) strtol (cl, &end, 10);
+    
+    if (cid_array[index] EQ 0x00) 
+      cid_array[index] = PDP_CONTEXT_CID_OMITTED;
+
+    index++;
+    cl = end;
+    if ( *cl EQ ',' )
+      cl++;
+  }
+  while ( *end EQ ',' );
+
+  cid_array[index] = PDP_CONTEXT_CID_INVALID;
+  cl = end;
+
+  index = 0;
+
+#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 = (U8)index;
+
+    if(cgpaddr.c_cid > 0)
+    {
+      for (n=0;((n<cgpaddr.c_cid) AND (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 ((T_ACI_CMD_SRC)srcId, cid_array, pdp_addresses );
+  
+  if( ret EQ AT_CMPL )
+  {
+    while( cid_array[index] NEQ PDP_CONTEXT_CID_INVALID )
+    {
+      if (index NEQ 0) 
+      {//to put a , between pdp adresses, if more than one exists.
+        sprintf( g_sa, ",");
+      }
+      switch( pdp_addresses[index].ctrl_ip_address )
+      {
+        case NAS_is_ip_not_present:
+          sprintf( g_sa, "%s%hd", me, cid_array[index] );
+          break;
+            
+        case NAS_is_ipv4:
+          sprintf( g_sa, "%s%hd,\"%d.%d.%d.%d\"", 
+                   me, 
+                   cid_array[index],
+                   pdp_addresses[index].ip_address.ipv4_addr.a4[0],
+                   pdp_addresses[index].ip_address.ipv4_addr.a4[1],
+                   pdp_addresses[index].ip_address.ipv4_addr.a4[2],
+                   pdp_addresses[index].ip_address.ipv4_addr.a4[3] );
+          break;
+            
+        case NAS_is_ipv6:
+          sprintf( g_sa, "%s%hd,\"%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\"", 
+                   me, 
+                   cid_array[index],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 0],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 1],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 2],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 3],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 4],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 5],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 6],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 7],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 8],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[ 9],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[10],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[11],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[12],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[13],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[14],
+                   pdp_addresses[index].ip_address.ipv6_addr.a6[15] );
+          break;
+      }
+
+      io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+      index ++;
+    }
+      
+    return (ATI_CMPL);    
+  }
+  else
+  {
+    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;
+  U8            index = 0;
+  U8            cid_array[PDP_CONTEXT_CID_MAX + 1];
+  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 ((T_ACI_CMD_SRC)srcId, cid_array );
+  switch (ret)
+  {
+    case (AT_CMPL):                         /*operation completed*/
+      pos = sprintf(g_sa,"%s(", me);
+      while( cid_array[index] NEQ PDP_CONTEXT_CID_INVALID )
+      {
+        if( index NEQ 0 )
+        {
+          g_sa[pos] = ','; pos++;
+        }
+        pos += sprintf(g_sa + pos,"%hd", cid_array[index]);
+        index ++;
+      }
+      
+      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 ((T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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] = "";
+  char         *end;
+  T_ACI_RETURN  ret = AT_FAIL;
+  U8            response;
+  U8            cid      = PDP_CONTEXT_CID_OMITTED;
+  U8            count    = 0;
+  U8            stop     = 1;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("setatPlusCGANS ()");
+
+/*
+ * Process parameters
+ */
+
+  response = (U8) strtol (cl, &end, 10);
+  cl = end;
+
+  if( *cl EQ ',' )
+  {
+    cl++;
+    switch ( *cl )
+    {
+      case ',':
+        /* the L2P is unspecified/omitted */
+        *L2P = 0;
+        break;
+      case '\"':
+        cl++;
+        while (*cl AND stop)
+        {
+          if ( *cl NEQ '\"' AND 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++; /* Remove the "," and convert the cid */
+      cid = ( U8 ) 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) AND (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 EQ TRUE) AND (at.rngPrms.mode EQ CRING_MOD_Gprs))
+      ati_stop_ring();
+
+    return(ATI_EXCT);
+  }
+
+#else
+
+
+  /* return a list of PDP addresses for the specified context identifier */
+  ret = sAT_PlusCGANS ((T_ACI_CMD_SRC)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 : atPlusCGEREP       |
++--------------------------------------------------------------------+
+
+  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 ( (T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+  ret = sAT_PlusCGSMS ( (T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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 ( (T_ACI_CMD_SRC)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)
+{
+
+  enum
+  {
+    ATD_CMD_NOT_VALID = 0,
+    ATD_CMD_98        = 1,
+    ATD_CMD_99        = 2
+  } atd_cmd_type = ATD_CMD_NOT_VALID;
+
+
+  U8            i          = 0;
+
+  U8            star_count = 0; 
+
+  char          tmp_cmd[40];
+  char          *p_tmp_cmd = tmp_cmd;
+  char          c_addr[MAX_B_SUBSCR_NUM_LEN];
+  char          L2P[MAX_L2P_LENGTH];
+  U8            cid_array[PDP_CONTEXT_CID_MAX];
+  U8            cid_length = PDP_CONTEXT_CID_MAX + 1;
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+  BOOL          src_flag = FALSE;
+#endif
+
+  T_PDP_TYPE    pdp_type = "IP";
+  T_PDP_CONTEXT pdp_context;
+  T_ACI_RETURN ret = AT_FAIL;
+  T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
+
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atGD ()");
+  
+  TRACE_EVENT ("ati_gprs, atGD, start");
+  //TRACE_EVENT (cl);
+  
+  memset( L2P, 0, sizeof( L2P ) );
+  memset( cid_array, PDP_CONTEXT_CID_INVALID, sizeof( cid_array ) );
+  cid_array[0] = PDP_CONTEXT_CID_OMITTED;
+
+  memset( tmp_cmd, 0, sizeof(tmp_cmd) );
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+    if( (ati_is_src_type((UBYTE)srcId, ATI_SRC_TYPE_TST) EQ TRUE) OR
+        (srcId EQ CMD_SRC_LCL) )
+    {
+      TRACE_EVENT ("Source Found is LOCAL");
+      /* if call not yet marked as WAP call, mark it now */
+      if (Wap_Call)
+      {
+        TRACE_EVENT ("ati_gprs, atGD, WAP Call for atd*98# OR atd*99#");
+        src_flag = TRUE;
+      }
+    }  
+#endif
+
+  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+=2;
+      }
+      else
+      {
+        *gprs_command = FALSE;
+        return (ATI_FAIL);
+      }
+      break;
+      
+    case '*':
+      cl++;
+      break;
+      
+    default:
+      *gprs_command = FALSE;
+      return (ATI_FAIL);
+  }
+
+  do
+  {
+    switch( *(cl + i) )
+    {
+      case '*': 
+        tmp_cmd[i] = ','; 
+        star_count++;  
+        break;
+
+      case '#': 
+        tmp_cmd[i] = 0;
+        break;
+
+      default : 
+        tmp_cmd[i] = *(cl + i); 
+        break;
+          }
+
+    i++;
+  }
+  while( *(cl + i) NEQ '#' AND i < 40 );
+
+  if( i EQ 40 )
+  {
+    *gprs_command = FALSE;
+    return (ATI_FAIL);
+  }
+
+  
+  if( tmp_cmd[0] EQ '9' AND
+      tmp_cmd[1] EQ '8' )
+  {
+    /* Character after *98 should be * or # for GPRS; otherwise
+       this is USSD (refer issue 16289) */
+    if( tmp_cmd[2] NEQ ',' AND
+        tmp_cmd[2] NEQ 0   )
+    {
+      *gprs_command = FALSE;
+      return (ATI_FAIL);
+    }
+
+    if ( tmp_cmd[2] NEQ 0  )
+      p_tmp_cmd = parse( &tmp_cmd[3], "i", &cid_length, &cid_array );
+    
+    if(p_tmp_cmd)
+      atd_cmd_type = ATD_CMD_98;
+  }
+  else if( tmp_cmd[0] EQ '9' AND
+           tmp_cmd[1] EQ '9' )
+  {
+    /* Character after *99 should be * or # for GPRS; otherwise
+       this is USSD (refer issue 16289) */
+    if( tmp_cmd[2] NEQ ',' AND
+        tmp_cmd[2] NEQ 0   )
+    {
+      *gprs_command = FALSE;
+      return (ATI_FAIL);
+    }
+
+    switch( star_count )
+    {
+      case 1:
+        tmp_cmd[i]   = ',';
+        tmp_cmd[i+1] = ',';
+        tmp_cmd[i+1] = 0;
+        break;
+
+      case 2:
+        tmp_cmd[i]   = ',';
+        tmp_cmd[i+1] = 0;
+        break;
+    }
+
+    if ( tmp_cmd[2] NEQ 0  )
+      p_tmp_cmd = parse( &tmp_cmd[3], "aai", (LONG)MAX_B_SUBSCR_NUM_LEN, c_addr,
+                                             (LONG)MAX_L2P_LENGTH, L2P, 
+                                             &cid_length, &cid_array );
+    if(p_tmp_cmd)
+      atd_cmd_type = ATD_CMD_99;
+  }
+  else
+  {
+    *gprs_command = FALSE;
+    return (ATI_FAIL);
+  }
+
+
+  switch( atd_cmd_type )
+  {
+    case ATD_CMD_98:
+    {  
+      strcpy( L2P, "PPP" );
+      strcpy( pdp_type, "IP" );
+
+      break;
+    }
+
+    case ATD_CMD_99:
+    {
+      if( ! strcmp(L2P,"") )
+      {
+        /* L2P is omitted use PPP as L2 protocol*/
+        strcpy( L2P, "PPP" );
+      }
+      
+      else if( !(strcmp(L2P, "1") AND strcmp(L2P,"PPP")) )
+      {
+        strcpy( L2P, "PPP" );
+      }
+            
+#if defined(FF_PKTIO) OR defined(FF_TCP_IP) OR defined (FF_PSI)
+      else if( !(strcmp(L2P, "901") AND strcmp(L2P, "M-PKT")) )
+      {
+        strcpy( L2P, "M-PKT" );
+      }
+#endif /* FF_PKTIO or FF_TCP_IP or FF_PSI */
+      else
+      {
+        cmdCmeError(CME_ERR_OpNotAllow);
+        return (ATI_FAIL);
+      }
+              
+      strcpy( pdp_type, "IP" );
+
+      break;
+    }
+  }
+
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    *gprs_command = FALSE;
+    return (ATI_FAIL);
+  }
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+  if (src_flag)
+  {
+    memset (work_cids, PDP_CONTEXT_CID_INVALID, PDP_CONTEXT_CID_MAX);
+    cid_pointer=0;
+  }
+#endif
+  /*
+   * If the cid is omitted a matching defined context is found or a new context is created.
+   */
+  if( cid_array[0] EQ PDP_CONTEXT_CID_OMITTED )
+  {
+    p_pdp_context_node = p_pdp_context_list;
+    while(p_pdp_context_node AND
+          strcmp(p_pdp_context_node->attributes.pdp_type, pdp_type) AND
+          p_pdp_context_node->internal_data.state NEQ PDP_CONTEXT_STATE_DEFINED )
+    {
+      p_pdp_context_node = p_pdp_context_node->p_next;
+    }
+    if(p_pdp_context_node)
+    {
+      cid_array[0] = p_pdp_context_node->cid;
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+      if (src_flag)
+      {
+        work_cids[cid_pointer] = cid_array[0];
+      }
+#endif
+    }
+    else
+    {
+      cid_array[0] = pdp_context_get_free_cid();
+      
+      memcpy( &pdp_context, &pdp_context_default.attributes, sizeof(T_PDP_CONTEXT) );
+      memcpy(  pdp_context.pdp_type, pdp_type, sizeof(T_PDP_TYPE));
+
+      sAT_PlusCGDCONT((T_ACI_CMD_SRC) srcId, cid_array[0], &pdp_context );
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+      if (src_flag)
+      {
+        work_cids[cid_pointer] = cid_array[0];
+      }
+#endif
+    }
+  }
+  else
+  {
+    i=0;
+    while( cid_array[i] NEQ PDP_CONTEXT_CID_INVALID )
+    {
+      p_pdp_context_node = pdp_context_find_node_from_cid( cid_array[i] );
+
+      if( p_pdp_context_node )
+      {
+        if( strcmp( p_pdp_context_node->attributes.pdp_type, pdp_type ) )
+          strcpy( p_pdp_context_node->attributes.pdp_type, pdp_type );
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+        if (src_flag)
+        {
+          work_cids[i] = cid_array[i];
+          cid_pointer = i;
+        }
+#endif
+      }
+      else
+      {
+        memcpy( &pdp_context, &pdp_context_default.attributes, sizeof(T_PDP_CONTEXT) );
+        memcpy(  pdp_context.pdp_type, pdp_type, sizeof(T_PDP_TYPE));
+          
+        if( sAT_PlusCGDCONT((T_ACI_CMD_SRC) srcId, cid_array[i], &pdp_context ) EQ AT_FAIL )
+        {
+          *gprs_command = FALSE;
+          return (ATI_FAIL); 
+        }
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+        if (src_flag)
+        {
+          work_cids[i] = cid_array[i];
+          cid_pointer = i;
+        }
+#endif
+      }
+      i++;
+    }
+  }
+
+  *gprs_command = TRUE;
+
+#if defined (FF_WAP) OR defined (FF_SAT_E)
+  if (src_flag)
+  {
+    BYTE  options;
+    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 );
+    }
+
+
+    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 );
+    }
+
+    /* get dti id */
+    srcc_new_count(link_no);
+    
+    wap_dti_id = dti_cntrl_new_dti(DTI_DTI_ID_NOTPRESENT);
+    p_pdp_context_node = pdp_context_find_node_from_cid( cid_array[0] );
+    p_pdp_context_node->internal_data.link_id_new =
+      dti_conn_compose_link_id (0,0, wap_dti_id, DTI_TUPLE_NO_NOTPRESENT );
+    p_pdp_context_node->internal_data.owner = ( T_ACI_CMD_SRC)srcId;
+
+    TRACE_EVENT_P1 ("ati_gprs, atGD, link_id_new = %0X", p_pdp_context_node->internal_data.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 = (T_ACI_CMD_SRC)smShrdPrm.owner;
+    smEntStat.curCmd = AT_CMD_CGDATA;
+
+    gpppEntStat.curCmd = AT_CMD_CGDATA;
+    gpppEntStat.entOwn = ( T_ACI_CMD_SRC)srcId;
+    gpppShrdPrm.owner  = (UBYTE) srcId;
+
+    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 /* of WAP OR SAT E */
+
+  if( cmhSM_sAT_A(( T_ACI_CMD_SRC) srcId, &ret ) EQ TRUE )
+  {
+    switch (ret)
+    {
+      case (AT_CMPL):                 /* Operation completed */
+        return (ATI_CMPL);
+      
+      case (AT_EXCT):
+/*      curAtCmd    = AT_CMD_CGANS; */
+        return (ATI_EXCT);
+        
+      default:
+        cmdCmeError(CME_ERR_Unknown); /* Command failed */
+        return (ATI_FAIL);
+    }
+  }
+  else
+  {
+
+    ret = sAT_PlusCGDATA ((T_ACI_CMD_SRC) 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
+
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+  ret = sAT_PercentCGAATT ((T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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( (T_ACI_CMD_SRC)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;
+
+  TRACE_FUNCTION("setatPercentCGMM()");
+
+  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( (T_ACI_CMD_SRC)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*/
+}
+
+
+T_ATI_RSLT setatPercentCGPCO_HEX (UBYTE srcId, USHORT cid,
+                                    UBYTE *pco_hex_string, USHORT len)
+{
+  UBYTE pco_len;
+  UBYTE   *pco_array;
+
+
+
+
+  TRACE_FUNCTION("setatPercentCGPCO_HEX():");
+  /* 
+   * The functionality of the command is changed due to the 
+   * introduction of dynamic data structures for PCO.
+   */
+
+  ACI_MALLOC (pco_array, ACI_PCO_MAX_LEN + 1);
+
+  pco_len = (UBYTE) utl_HexStrToBin( pco_hex_string, len, pco_array, ACI_PCO_MAX_LEN + 1 );
+
+  if(sAT_PercentCGPCO_HEX ((T_ACI_CMD_SRC)srcId, (U8) cid, pco_array, pco_len) EQ AT_FAIL )
+  {
+    cmdCmeError (CME_ERR_Unknown);
+    ACI_MFREE (pco_array);
+    return (ATI_FAIL);
+  }
+
+  ACI_MFREE (pco_array);
+  return (ATI_CMPL);  
+
+}
+
+
+
+T_ACI_RETURN setatPercentCGPCO_ASCII (UBYTE srcId, U8 cid, UBYTE *pco_ascii_string, USHORT len)
+{
+  CHAR          aut_prot[5];
+  CHAR          user[MAX_USER_LEN+1];   /* + '\0' */
+  CHAR          pwd[MAX_PSWD_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 ((T_ACI_RETURN)ATI_FAIL);
+  }
+  strupper (aut_prot);
+  if (strcmp (aut_prot, "PAP"))
+  {
+    cmdCmeError (CME_ERR_OpNotSupp);
+    return ((T_ACI_RETURN)ATI_FAIL);
+  }
+
+  if (sAT_PercentCGPCO ((T_ACI_CMD_SRC)srcId, cid,
+                        ACI_PCO_AUTH_PROT_PAP, user, pwd, dns1, dns2) EQ AT_FAIL)
+  {
+    cmdCmeError (CME_ERR_Unknown);
+    return ((T_ACI_RETURN)ATI_FAIL);
+  }
+  
+  return ((T_ACI_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
+*/
+
+LOCAL 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  EQ PDP_CONTEXT_CID_OMITTED )  /* for all available cid's: recurse */
+  {
+    for( i=1; i<=PDP_CONTEXT_CID_MAX; i++ )
+    {
+      queatPercentCGPCO(srcId, i);
+    }
+  }
+  else /* for a specific cid */
+  {
+    gateway = dns1 = dns2 = 0 ; /* Just in case... */
+    
+    if( qAT_PercentCGPCO((T_ACI_CMD_SRC)srcId, &gateway, &dns1, &dns2, cid) EQ AT_CMPL )
+    {
+      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);
+      
+      memset(g_sa,0,MAX_CMD_LEN);
+    }
+   }
+   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)
+{
+  U8                  cid = PDP_CONTEXT_CID_OMITTED;
+  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);
+    ACI_MFREE (pco_string);
+    return (ATI_FAIL);
+  }
+  
+  if( !((cid >= PDP_CONTEXT_CID_MIN AND cid <= PDP_CONTEXT_CID_MAX) OR cid EQ PDP_CONTEXT_CID_OMITTED) )
+  {
+    cmdCmeError (CME_ERR_OpNotSupp);
+    ACI_MFREE (pco_string);
+    return (ATI_FAIL);
+  }
+
+#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 EQ ATI_EXCT)
+    {
+      bat_send(ati_bat_get_client(srcId), &cmd);
+    }
+} /* FF_ATI_BAT */
+#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 = (T_ATI_RSLT)setatPercentCGPCO_HEX (srcId,cid, (UBYTE*)pco_string, (USHORT)strlen (pco_string));
+            break;
+
+          case CGPCO_FORMAT_ASCII:
+            ret = (T_ATI_RSLT)setatPercentCGPCO_ASCII (srcId, cid, (UBYTE*)pco_string, (USHORT)strlen (pco_string));
+            break;
+
+         default:
+            cmdCmeError (CME_ERR_OpNotSupp);
+          ret = ATI_FAIL;
+            break;
+         }
+    }
+    break;
+    
+    default:
+      cmdCmeError (CME_ERR_OpNotSupp);
+      ret = ATI_FAIL;
+      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 = AT_FAIL;
+
+  TRACE_FUNCTION("setatPercentCGPPP( )");
+
+  cl=parse(cl,"d",&protocol);
+  if(!cl)
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+#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((T_ACI_CMD_SRC)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((T_ACI_CMD_SRC)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
+  T_ACI_RETURN ret;
+#endif
+  char test_class[3]="";
+  T_PERCENT_CGCLASS m_class = PERCENT_CGCLASS_OMITTED;
+
+  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 EQ 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 ( (T_ACI_CMD_SRC)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;
+#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((T_ACI_CMD_SRC)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*/
+}
+
+#ifdef REL99
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : GACI_CMD           |
+| STATE   : devellopment                ROUTINE : setatPlusCGEQREQ   |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGEQREQ command
+            Set 3G Quality of Service Profile (Requested)
+*/
+GLOBAL T_ATI_RSLT setatPlusCGEQREQ( char *cl, UBYTE srcId )
+{
+  T_ACI_RETURN ret;
+  T_PS_qos     input_qos;
+  U8           cid;
+#ifdef FF_ATI_BAT
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+#endif
+  TRACE_FUNCTION("setatPlusCGEQREQ ()");
+
+  cid = PDP_CONTEXT_CID_OMITTED;
+
+  input_qos.qos_r99.tc           = QOS_R99_TC_OMITTED;
+  input_qos.qos_r99.order        = QOS_R99_ORDER_OMITTED;
+  input_qos.qos_r99.del_err_sdu  = QOS_R99_DEL_ERR_SDU_OMITTED;
+  input_qos.qos_r99.max_sdu      = QOS_R99_MAX_SDU_OMITTED;
+  input_qos.qos_r99.max_rate_ul  = QOS_R99_MAX_BR_UL_OMITTED;
+  input_qos.qos_r99.max_rate_dl  = QOS_R99_MAX_BR_DL_OMITTED;
+  input_qos.qos_r99.xfer_delay   = QOS_R99_XFER_DELAY_OMITTED;
+  input_qos.qos_r99.handling_pri = QOS_R99_HANDLING_PRIO_OMITTED;
+  input_qos.qos_r99.guar_br_ul   = QOS_R99_GUAR_BR_UL_OMITTED;
+  input_qos.qos_r99.guar_br_dl   = QOS_R99_GUAR_BR_DL_OMITTED;
+  input_qos.qos_r99.ber.ratio_mant = QOS_R99_RATIO_MANT_OMITTED;        /* Residual bit error ratio */
+  input_qos.qos_r99.ber.ratio_exp  = QOS_R99_RATIO_EXP_OMITTED;
+  input_qos.qos_r99.sdu_err_ratio.ratio_mant = QOS_R99_RATIO_MANT_OMITTED;
+  input_qos.qos_r99.sdu_err_ratio.ratio_exp  = QOS_R99_RATIO_EXP_OMITTED;
+
+  cl = parse( cl,"ccrrrrcreecrc", &cid,
+                                  &input_qos.qos_r99.tc,
+                                  &input_qos.qos_r99.max_rate_ul,
+                                  &input_qos.qos_r99.max_rate_dl,
+                                  &input_qos.qos_r99.guar_br_ul,
+                                  &input_qos.qos_r99.guar_br_dl,
+                                  &input_qos.qos_r99.order,
+                                  &input_qos.qos_r99.max_sdu,
+                                  &input_qos.qos_r99.sdu_err_ratio,
+                                  &input_qos.qos_r99.ber,            /* Residual bit error ratio */
+                                  &input_qos.qos_r99.del_err_sdu,
+                                  &input_qos.qos_r99.xfer_delay,
+                                  &input_qos.qos_r99.handling_pri );
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_cgeqreq cgeqreq;
+    cmd.ctrl_params  = BAT_CMD_SET_PLUS_CGEQREQ;
+    cmd.params.ptr_set_plus_cgeqreq = &cgeqreq;
+    
+    cgeqreq.cid          = cid;
+    cgeqreq.tc           = input_qos.qos_r99.tc;
+    cgeqreq.max_rate_ul  = input_qos.qos_r99.max_rate_ul;
+    cgeqreq.max_rate_dl  = input_qos.qos_r99.max_rate_dl;
+    cgeqreq.guar_br_ul   = input_qos.qos_r99.guar_br_ul;
+    cgeqreq.guar_br_dl   = input_qos.qos_r99.guar_br_dl; 
+    cgeqreq.order        = input_qos.qos_r99.order;
+    cgeqreq.max_sdu      = input_qos.qos_r99.max_sdu;
+    
+    /* sdu_err_ratio */
+    if (input_qos.qos_r99.sdu_err_ratio.ratio_mant NEQ 
+        QOS_R99_RATIO_MANT_OMITTED)
+    {
+      cgeqreq.v_sdu_err_ratio    = TRUE;
+      cgeqreq.c_sdu_err_ratio    = 2;
+      cgeqreq.sdu_err_ratio[0]   = input_qos.qos_r99.sdu_err_ratio.ratio_mant; 
+      if (input_qos.qos_r99.sdu_err_ratio.ratio_exp NEQ 
+          QOS_R99_RATIO_EXP_OMITTED)
+        cgeqreq.sdu_err_ratio[1] = input_qos.qos_r99.sdu_err_ratio.ratio_exp;
+      else
+        cgeqreq.sdu_err_ratio[1] = 1;
+    }
+    else
+    {
+      cgeqreq.v_sdu_err_ratio = FALSE;
+      cgeqreq.c_sdu_err_ratio = 0;      
+    }
+
+    /* ber */
+    if (input_qos.qos_r99.ber.ratio_mant NEQ QOS_R99_RATIO_MANT_OMITTED)
+    {
+      cgeqreq.v_ber    = TRUE;
+      cgeqreq.c_ber    = 2;
+      cgeqreq.ber[0]   = input_qos.qos_r99.ber.ratio_mant; 
+      if (input_qos.qos_r99.ber.ratio_exp NEQ QOS_R99_RATIO_EXP_OMITTED)
+        cgeqreq.ber[1] = input_qos.qos_r99.ber.ratio_exp;
+      else
+        cgeqreq.ber[1] = 1;
+    }
+    else
+    {
+      cgeqreq.v_ber = FALSE;
+      cgeqreq.c_ber = 0;      
+    }
+    
+    cgeqreq.del_err_sdu      = input_qos.qos_r99.del_err_sdu;
+    cgeqreq.xfer_delay       = input_qos.qos_r99.xfer_delay;
+    cgeqreq.handling_pri     = input_qos.qos_r99.handling_pri;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    src_params->curAtCmd=AT_CMD_CGEQREQ;
+    return(ATI_EXCT);
+}
+#else
+  ret = (T_ACI_RETURN)sAT_PlusCGEQREQ ((T_ACI_CMD_SRC)srcId, (U8)cid ,&input_qos); 
+  switch (ret)
+  {
+    case (AT_CMPL):                         /*operation completed*/
+      return (ATI_CMPL);
+    case (AT_EXCT):
+//      curAtCmd    = AT_CMD_CGEQREQ;
+      return (ATI_EXCT);
+    default:
+      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
+      return (ATI_FAIL);
+  }
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : GACI_CMD           |
+| STATE   : devellopment                ROUTINE : setatPlusCGEQMIN   |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CGEQMIN command
+            Set 3G Quality of Service Profile (Minimum)
+*/
+GLOBAL T_ATI_RSLT setatPlusCGEQMIN( char *cl, UBYTE srcId )
+{
+  T_ACI_RETURN ret;
+  T_PS_qos     input_qos;
+  U8           cid;
+#ifdef FF_ATI_BAT
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+#endif
+  TRACE_FUNCTION("setatPlusCGEQMIN ()");
+
+  cid = PDP_CONTEXT_CID_OMITTED;
+
+  input_qos.qos_r99.tc           = QOS_R99_TC_OMITTED;
+  input_qos.qos_r99.order        = QOS_R99_ORDER_OMITTED;
+  input_qos.qos_r99.del_err_sdu  = QOS_R99_DEL_ERR_SDU_OMITTED;
+  input_qos.qos_r99.max_sdu      = QOS_R99_MAX_SDU_OMITTED;
+  input_qos.qos_r99.max_rate_ul  = QOS_R99_MAX_BR_UL_OMITTED;
+  input_qos.qos_r99.max_rate_dl  = QOS_R99_MAX_BR_DL_OMITTED;
+  input_qos.qos_r99.xfer_delay   = QOS_R99_XFER_DELAY_OMITTED;
+  input_qos.qos_r99.handling_pri = QOS_R99_HANDLING_PRIO_OMITTED;
+  input_qos.qos_r99.guar_br_ul   = QOS_R99_GUAR_BR_UL_OMITTED;
+  input_qos.qos_r99.guar_br_dl   = QOS_R99_GUAR_BR_DL_OMITTED;
+  input_qos.qos_r99.ber.ratio_mant = QOS_R99_RATIO_MANT_OMITTED;        /* Residual bit error ratio */
+  input_qos.qos_r99.ber.ratio_exp  = QOS_R99_RATIO_EXP_OMITTED;
+  input_qos.qos_r99.sdu_err_ratio.ratio_mant = QOS_R99_RATIO_MANT_OMITTED;
+  input_qos.qos_r99.sdu_err_ratio.ratio_exp  = QOS_R99_RATIO_EXP_OMITTED;
+
+  cl = parse( cl,"ccrrrrcreecrc", &cid,
+                                  &input_qos.qos_r99.tc,
+                                  &input_qos.qos_r99.max_rate_ul,
+                                  &input_qos.qos_r99.max_rate_dl,
+                                  &input_qos.qos_r99.guar_br_ul,
+                                  &input_qos.qos_r99.guar_br_dl,
+                                  &input_qos.qos_r99.order,
+                                  &input_qos.qos_r99.max_sdu,
+                                  &input_qos.qos_r99.sdu_err_ratio,
+                                  &input_qos.qos_r99.ber,            /* Residual bit error ratio */
+                                  &input_qos.qos_r99.del_err_sdu,
+                                  &input_qos.qos_r99.xfer_delay,
+                                  &input_qos.qos_r99.handling_pri );
+  if( !cl )
+  {
+    cmdCmeError(CME_ERR_OpNotAllow);
+    return (ATI_FAIL);
+  }
+ 
+#ifdef FF_ATI_BAT
+{
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_cgeqmin cgeqmin;
+    cmd.ctrl_params                 = BAT_CMD_SET_PLUS_CGEQMIN;
+    cmd.params.ptr_set_plus_cgeqmin = &cgeqmin;
+    
+    cgeqmin.cid          = (T_BAT_pdp_cid)cid;
+    cgeqmin.tc           = input_qos.qos_r99.tc;
+    cgeqmin.max_rate_ul  = input_qos.qos_r99.max_rate_ul;
+    cgeqmin.max_rate_dl  = input_qos.qos_r99.max_rate_dl;
+    cgeqmin.guar_br_ul   = input_qos.qos_r99.guar_br_ul;
+    cgeqmin.guar_br_dl   = input_qos.qos_r99.guar_br_dl; 
+    cgeqmin.order        = input_qos.qos_r99.order;
+    cgeqmin.max_sdu      = input_qos.qos_r99.max_sdu;
+    
+    /* sdu_err_ratio */
+    if (input_qos.qos_r99.sdu_err_ratio.ratio_mant NEQ 
+        QOS_R99_RATIO_MANT_OMITTED)
+    {
+      cgeqmin.v_sdu_err_ratio    = TRUE;
+      cgeqmin.c_sdu_err_ratio    = 2;
+      cgeqmin.sdu_err_ratio[0]   = input_qos.qos_r99.sdu_err_ratio.ratio_mant; 
+      if (input_qos.qos_r99.sdu_err_ratio.ratio_exp NEQ 
+          QOS_R99_RATIO_EXP_OMITTED)
+        cgeqmin.sdu_err_ratio[1] = input_qos.qos_r99.sdu_err_ratio.ratio_exp;
+      else
+        cgeqmin.sdu_err_ratio[1] = 1;
+    }
+    else
+    {
+      cgeqmin.v_sdu_err_ratio = FALSE;
+      cgeqmin.c_sdu_err_ratio = 0;      
+    }
+
+    /* ber */
+    if (input_qos.qos_r99.ber.ratio_mant NEQ QOS_R99_RATIO_MANT_OMITTED)
+    {
+      cgeqmin.v_ber    = TRUE;
+      cgeqmin.c_ber    = 2;
+      cgeqmin.ber[0]   = input_qos.qos_r99.ber.ratio_mant; 
+      if (input_qos.qos_r99.ber.ratio_exp NEQ QOS_R99_RATIO_EXP_OMITTED)
+        cgeqmin.ber[1] = input_qos.qos_r99.ber.ratio_exp;
+      else
+        cgeqmin.ber[1] = 1;
+    }
+    else
+    {
+      cgeqmin.v_ber = FALSE;
+      cgeqmin.c_ber = 0;      
+    }
+    
+    cgeqmin.del_err_sdu      = input_qos.qos_r99.del_err_sdu;
+    cgeqmin.xfer_delay       = input_qos.qos_r99.xfer_delay;
+    cgeqmin.handling_pri     = input_qos.qos_r99.handling_pri;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    src_params->curAtCmd=AT_CMD_CGEQMIN;
+    return(ATI_EXCT);
+}
+#else
+  ret = sAT_PlusCGEQMIN ((T_ACI_CMD_SRC)srcId, cid ,&input_qos); 
+  switch (ret)
+  {
+    case (AT_CMPL):                         /*operation completed*/
+      return (ATI_CMPL);
+    case (AT_EXCT):
+//      curAtCmd    = AT_CMD_CGEQMIN;
+      return (ATI_EXCT);
+    default:
+      cmdCmeError(CME_ERR_Unknown);         /*Command failed*/
+      return (ATI_FAIL);
+  }
+#endif /* FF_ATI_BAT */
+
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   : finished                    ROUTINE : setatPlusCGEQNEG   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Query of 3G QoS Profile (Negotiated)
+*/
+GLOBAL T_ATI_RSLT setatPlusCGEQNEG (char *cl, UBYTE srcId)
+{
+  char        *me="+CGEQNEG: ";
+  T_PS_qos     pdef_qos;
+  int          i;
+  BOOL         qos_valid;
+  U8           cid_array[PDP_CONTEXT_CID_MAX+1], current_cid;
+  int          no_of_cids;
+  char         *end;
+#ifdef FF_ATI_BAT
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+#endif
+  TRACE_FUNCTION("setatPlusCGEQNEG ()");
+
+  /* Parse all the cids into the cid array */
+  no_of_cids = 0;
+
+  --cl; /* Decreased due to no comma the first time! */
+  do
+  {
+    /* Remove the "," */
+    cl++;
+
+    /* Set the entry to omitted. */
+    cid_array[no_of_cids] = PDP_CONTEXT_CID_OMITTED;
+
+    /* Parse the value */
+    cid_array[no_of_cids] = ( U8 ) strtol (cl, &end, 10);
+    cl = end;
+
+    if( cid_array[no_of_cids] EQ 0 )
+      cid_array[no_of_cids] = PDP_CONTEXT_CID_OMITTED;
+    
+    /* If a cid is omitted no cids must be specified at all. */
+    if( cid_array[no_of_cids] EQ PDP_CONTEXT_CID_OMITTED )
+    {
+      if( no_of_cids NEQ 0 )
+      {
+        /* Don't accept omitted cids inside if not the first. (AT+CGCMOD=1,2,,3 is not allowed). */
+        cmdCmeError(CME_ERR_OpNotSupp);
+        return (ATI_FAIL);
+      }
+      /* Break the while */
+      break;
+    }
+    if( (!cl) OR (cid_array[no_of_cids] < PDP_CONTEXT_CID_MIN) OR (cid_array[no_of_cids] > PDP_CONTEXT_CID_MAX) OR (no_of_cids >= PDP_CONTEXT_CID_MAX) )
+    {
+      cmdCmeError(CME_ERR_OpNotSupp);
+      return(ATI_FAIL);
+    }
+    no_of_cids++;
+  } while ( *cl EQ ',' );
+  cid_array[no_of_cids] = PDP_CONTEXT_CID_OMITTED;
+
+#ifdef FF_ATI_BAT
+{
+  T_BAT_cmd_send cmd;
+  T_BAT_cmd_set_plus_cgeqneg cgeqneg;
+  UBYTE n;
+  cmd.ctrl_params = BAT_CMD_SET_PLUS_CGEQNEG;
+  cmd.params.ptr_set_plus_cgeqneg=&cgeqneg;
+
+  for (n=0;((n<no_of_cids) AND (n<BAT_MAX_PDP_CID));n++)
+
+    cgeqneg.cid[n]=(T_BAT_pdp_cid)cid_array[n];
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    src_params->curAtCmd=AT_CMD_CGEQNEG;
+    return(ATI_EXCT);
+}
+#else
+  /* Calculate number of cids: If the first cid is omitted it is treated as all cids. */
+  if (cid_array[0] EQ PDP_CONTEXT_CID_OMITTED)
+    no_of_cids = PDP_CONTEXT_CID_MAX;
+  
+  for(i = 0; i<no_of_cids; i++)
+  {
+    /* If the first cid is omitted it is treated as all cids */ 
+    if (cid_array[0] EQ PDP_CONTEXT_CID_OMITTED)
+      current_cid = i+1;
+    else
+      current_cid = cid_array[i];
+
+    if (sAT_PlusCGEQNEG ((T_ACI_CMD_SRC)srcId, current_cid, &qos_valid, &pdef_qos) EQ AT_CMPL)
+    {
+      if (qos_valid)
+      {
+        /* Format the return string with the Release 99 QoS */
+        sprintf(g_sa,"%s%hd,%d,%d,%d,%d,%d,%d,%d,%dE%d,%dE%d,%d,%d,%d", me, current_cid,
+          pdef_qos.qos_r99.tc,                       /*< traffic class                                      */
+          pdef_qos.qos_r99.max_rate_ul,              /*< max bit-rate uplink                                */
+          pdef_qos.qos_r99.max_rate_dl,              /*< max bit-rate downlink                              */
+          pdef_qos.qos_r99.guar_br_ul,               /*< guaranteed bit-rate uplink                         */
+          pdef_qos.qos_r99.guar_br_dl,               /*< guaranteed bit-rate downlink                       */
+          pdef_qos.qos_r99.order,                    /*< delivery order                                     */
+          pdef_qos.qos_r99.max_sdu,                  /*< max SDU size                                       */
+          pdef_qos.qos_r99.sdu_err_ratio.ratio_mant, /*< SDU error ratio (format is the same as ber)        */
+          pdef_qos.qos_r99.sdu_err_ratio.ratio_exp,  /*<                                                    */
+          pdef_qos.qos_r99.ber.ratio_mant,           /*< Residual bit error ratio (ratio_mant E ratio_exp   */
+          pdef_qos.qos_r99.ber.ratio_exp,            /*< (Ex. 10E2)                                         */
+          pdef_qos.qos_r99.del_err_sdu,              /*< delivery of erroneous SDU                          */
+          pdef_qos.qos_r99.xfer_delay,               /*< transfer delay                                     */
+          pdef_qos.qos_r99.handling_pri);            /*< traffic handling priority                          */
+      
+        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+      }
+    }
+    else
+    {
+      cmdCmeError(CME_ERR_Unknown); /* The command is invalid for srcId */
+      return (ATI_FAIL);
+    }
+  }
+
+  return (ATI_CMPL);
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   : finished                    ROUTINE : setatPlusCGCMOD    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Modify indicated or all contexts.
+*/
+GLOBAL T_ATI_RSLT setatPlusCGCMOD (char *cl, UBYTE srcId)
+{
+  U8           cid_array[PDP_CONTEXT_CID_MAX + 1];
+  int          no_of_cids;
+  char         *end;
+  T_ACI_RETURN ret;
+#ifdef FF_ATI_BAT
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+#endif
+   
+  TRACE_FUNCTION("setatPlusCGCMOD ()");
+
+  --cl; /* No comma the first time!!! */
+
+  /* Parse all the cids into the cid array */
+  no_of_cids = 0;
+  do
+  {
+    /* Remove the "," */
+    cl++;
+
+    /* Set the entry to omitted. */
+    cid_array[no_of_cids] = PDP_CONTEXT_CID_OMITTED;
+
+    /* Parse the value */
+    cid_array[no_of_cids] = (U8) strtol (cl, &end, 10);
+    cl = end;
+
+    if( cid_array[no_of_cids] EQ 0 )
+      cid_array[no_of_cids] = PDP_CONTEXT_CID_OMITTED;
+
+    /* If a cid is omitted no cids must be specified at all. */
+    if( cid_array[no_of_cids] EQ PDP_CONTEXT_CID_OMITTED )
+    {
+      if (no_of_cids NEQ 0)
+      {
+        /* Don't accept omitted cids inside if not the first. (AT+CGCMOD=1,2,,3 is not allowed). */
+        cmdCmeError(CME_ERR_OpNotSupp);
+        return (ATI_FAIL);
+      }
+      /* Break the while */
+      break;
+    }
+    if ( (!cl) OR (cid_array[no_of_cids] < PDP_CONTEXT_CID_MIN) OR (cid_array[no_of_cids] > PDP_CONTEXT_CID_MAX) OR (no_of_cids >= PDP_CONTEXT_CID_MAX) )
+    {
+      cmdCmeError(CME_ERR_OpNotSupp);
+      return (ATI_FAIL);
+    }
+    no_of_cids++;
+  } while ( *cl EQ ',' );
+  cid_array[no_of_cids] = PDP_CONTEXT_CID_INVALID;
+
+#ifdef FF_ATI_BAT
+{
+  T_BAT_cmd_send cmd;
+  T_BAT_cmd_set_plus_cgcmod cgcmod;
+  UBYTE n;
+  cmd.ctrl_params = BAT_CMD_SET_PLUS_CGCMOD;
+  cmd.params.ptr_set_plus_cgcmod=&cgcmod;
+
+  for (n=0;((n<no_of_cids) AND (n<BAT_MAX_PDP_CID));n++)
+    cgcmod.cid[n]=(T_BAT_pdp_cid)cid_array[n];
+    bat_send(ati_bat_get_client(srcId), &cmd);
+
+    src_params->curAtCmd=AT_CMD_CGCMOD;
+    return(ATI_EXCT);
+}
+#else
+  ret = sAT_PlusCGCMOD ((T_ACI_CMD_SRC)srcId, cid_array);
+  switch ( ret )
+  {
+    case AT_EXCT:
+      cmdErrStr   = NULL;
+//      curAtCmd    = AT_CMD_CGCMOD;
+      return (ATI_EXCT);
+    case AT_CMPL:
+      /* The command can not return AT_CMPL!! This is an error! */
+      cmdCmeError(CME_ERR_Unknown);
+      return (ATI_FAIL);
+  }
+  return (map_aci_2_ati_rslt(ret));
+#endif /*FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   : finished                    ROUTINE : queatPlusCGEQREQ   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Query of 3G QoS Profile (Requested)
+*/
+GLOBAL T_ATI_RSLT queatPlusCGEQREQ (char *cl, UBYTE srcId)
+{
+  char        *me="+CGEQREQ: ";
+  T_PS_qos     pdef_qos;
+  U8           cid;
+  BOOL         qos_valid = FALSE;
+
+  TRACE_FUNCTION("queatPlusCGEQREQ ()");
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_no_parameter dummy;
+
+    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGEQREQ;
+    dummy.bat_dummy = 0xFF;
+    cmd.params.ptr_set_plus_cgeqreq = &dummy;
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    return(ATI_EXCT);
+  }
+#else
+
+  for ( cid = PDP_CONTEXT_CID_MIN; cid <= PDP_CONTEXT_CID_MAX; cid++ )
+  {
+    if (qAT_PlusCGEQREQ ((T_ACI_CMD_SRC)srcId, cid, &qos_valid, &pdef_qos) EQ AT_CMPL)
+    {
+      if (qos_valid)
+      {
+        /* Format the return string with the Release 99 QoS */
+        sprintf(g_sa,"%s%hd,%d,%d,%d,%d,%d,%d,%d,\"%dE%d\",\"%dE%d\",%d,%d,%d", me, cid,
+          pdef_qos.qos_r99.tc,                       /*< traffic class                                      */
+          pdef_qos.qos_r99.max_rate_ul,              /*< max bit-rate uplink                                */
+          pdef_qos.qos_r99.max_rate_dl,              /*< max bit-rate downlink                              */
+          pdef_qos.qos_r99.guar_br_ul,               /*< guaranteed bit-rate uplink                         */
+          pdef_qos.qos_r99.guar_br_dl,               /*< guaranteed bit-rate downlink                       */
+          pdef_qos.qos_r99.order,                    /*< delivery order                                     */
+          pdef_qos.qos_r99.max_sdu,                  /*< max SDU size                                       */
+          pdef_qos.qos_r99.sdu_err_ratio.ratio_mant, /*< SDU error ratio (format is the same as ber)        */
+          pdef_qos.qos_r99.sdu_err_ratio.ratio_exp,  /*<                                                    */
+          pdef_qos.qos_r99.ber.ratio_mant,           /*< Residual bit error ratio (ratio_mant E ratio_exp   */
+          pdef_qos.qos_r99.ber.ratio_exp,            /*< (Ex. 10E2)                                         */
+          pdef_qos.qos_r99.del_err_sdu,              /*< delivery of erroneous SDU                          */
+          pdef_qos.qos_r99.xfer_delay,               /*< transfer delay                                     */
+          pdef_qos.qos_r99.handling_pri);            /*< traffic handling priority                          */
+      
+        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+      }
+    }
+    else
+    {
+      /* AT_FAIL has been returned */
+      cmdCmeError(CME_ERR_Unknown); /* The command is invalid for srcId */
+      return (ATI_FAIL);
+    }
+  }
+  return (ATI_CMPL);
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   : finished                    ROUTINE : queatPlusCGEQMIN   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Query of 3G QoS Profile (Minimum)
+*/
+GLOBAL T_ATI_RSLT queatPlusCGEQMIN (char *cl, UBYTE srcId)
+{
+  char         *me="+CGEQMIN: ";
+  T_PS_min_qos pdef_qos;
+  U8           cid;
+  BOOL         qos_valid;
+
+  TRACE_FUNCTION("queatPlusCGEQMIN ()");
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_no_parameter dummy;
+
+    cmd.ctrl_params = BAT_CMD_SET_PLUS_CGEQMIN;
+    dummy.bat_dummy = 0xFF;
+    cmd.params.ptr_set_plus_cgeqmin = &dummy;
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    return(ATI_EXCT);
+  }
+#else
+
+  for ( cid = PDP_CONTEXT_CID_MIN; cid <= PDP_CONTEXT_CID_MAX; cid++ )
+  {
+    if (qAT_PlusCGEQMIN ((T_ACI_CMD_SRC)srcId, cid, &qos_valid, &pdef_qos) EQ AT_CMPL)
+    {
+      if (qos_valid)
+      {
+        /* Format the return string with the Release 99 QoS */
+        sprintf(g_sa,"%s%hd", me, cid);
+
+        /* Format the return string with the Release 99 QoS */
+        sprintf(g_sa,"%s%hd,%d,%d,%d,%d,%d,%d,%d,\"%dE%d\",\"%dE%d\",%d,%d,%d", me, cid,
+          pdef_qos.qos_r99.tc,                       /*< traffic class                                      */
+          pdef_qos.qos_r99.max_rate_ul,              /*< max bit-rate uplink                                */
+          pdef_qos.qos_r99.max_rate_dl,              /*< max bit-rate downlink                              */
+          pdef_qos.qos_r99.guar_br_ul,               /*< guaranteed bit-rate uplink                         */
+          pdef_qos.qos_r99.guar_br_dl,               /*< guaranteed bit-rate downlink                       */
+          pdef_qos.qos_r99.order,                    /*< delivery order                                     */
+          pdef_qos.qos_r99.max_sdu,                  /*< max SDU size                                       */
+          pdef_qos.qos_r99.sdu_err_ratio.ratio_mant, /*< SDU error ratio (format is the same as ber)        */
+          pdef_qos.qos_r99.sdu_err_ratio.ratio_exp,  /*<                                                    */
+          pdef_qos.qos_r99.ber.ratio_mant,           /*< Residual bit error ratio (ratio_mant E ratio_exp   */
+          pdef_qos.qos_r99.ber.ratio_exp,            /*< (Ex. 10E2)                                         */
+          pdef_qos.qos_r99.del_err_sdu,              /*< delivery of erroneous SDU                          */
+          pdef_qos.qos_r99.xfer_delay,               /*< transfer delay                                     */
+          pdef_qos.qos_r99.handling_pri);            /*< traffic handling priority                          */
+
+        io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+      }
+    }
+    else
+    {
+      /* AT_FAIL has been returned */
+      cmdCmeError(CME_ERR_Unknown); /* The command is invalid for srcId */
+      return (ATI_FAIL);
+    }
+  }
+  return (ATI_CMPL);
+#endif /* FF_ATI_BAT */
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   : finished                    ROUTINE : tesatPlusCGEQNEG   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Test function for 3G QoS Profile (Negotiated)
+            Return cids for all active contexts.
+*/
+GLOBAL T_ATI_RSLT tesatPlusCGEQNEG (char *cl, UBYTE srcId)
+{
+  char        *me="+CGEQNEG: ";
+  BOOL         context_activated, first_time = TRUE;
+  U8           cid;
+
+  TRACE_FUNCTION("tesatPlusCGEQNEG ()");
+
+  for (cid = 1; cid<=PDP_CONTEXT_CID_MAX; cid++)
+  {
+    if (tAT_PlusCGEQNEG_CGCMOD ((T_ACI_CMD_SRC)srcId, cid, &context_activated) EQ AT_CMPL)
+    {
+      if (context_activated)
+      {
+        if (first_time)
+        {
+          /* First time: Place command name and no comma in front of cid */
+          sprintf(g_sa,"%s%d", me, cid);
+          first_time = FALSE;
+        }
+        else
+        {
+          /* Subsequent time: Append sa with ",<cid>" */
+          sprintf(g_sa,"%s,%d", g_sa, cid);
+        }
+      }
+    }
+    else
+    {
+      /* AT_FAIL has been returned */
+      cmdCmeError(CME_ERR_Unknown);
+      return (ATI_FAIL);
+    }
+  }
+  if (!first_time)
+  {
+    /* Only send something if any contexts were activated (first_time NEQ TRUE) */
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+  }
+
+  return (ATI_CMPL);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : UMTS                        MODULE  : ATI_GPRS           |
+| STATE   : finished                    ROUTINE : tesatPlusCGCMOD    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Test function for 3G Context Modifify command.
+            Return cids for all active contexts.
+*/
+GLOBAL T_ATI_RSLT tesatPlusCGCMOD (char *cl, UBYTE srcId)
+{
+  char        *me="+CGCMOD: ";
+  BOOL         context_activated, first_time = TRUE;
+  U8           cid;
+
+  TRACE_FUNCTION("tesatPlusCGCMOD ()");
+
+  for (cid = PDP_CONTEXT_CID_MIN; cid <= PDP_CONTEXT_CID_MAX; cid++)
+  {
+    if (tAT_PlusCGEQNEG_CGCMOD ((T_ACI_CMD_SRC)srcId, cid, &context_activated) EQ AT_CMPL)
+    {
+      if (context_activated)
+      {
+        if (first_time)
+        {
+          /* First time: Place command name and no comma in front of cid */
+          sprintf(g_sa,"%s%d", me, cid);
+          first_time = FALSE;
+        }
+        else
+        {
+          /* Subsequent time: Append sa with ",<cid>" */
+          sprintf(g_sa,"%s,%d", g_sa, cid);
+        }
+      }
+    }
+    else
+    {
+      /* AT_FAIL has been returned */
+      cmdCmeError(CME_ERR_Unknown);
+      return (ATI_FAIL);
+    }
+  }
+  if (!first_time)
+  {
+    /* Only send something if any contexts were activated (first_time NEQ TRUE) */
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+  }
+
+  return (ATI_CMPL);
+}
+
+#endif /* REL99 */
+
+#endif /* GPRS */
+