diff src/aci2/aci/ati_sms.c @ 3:93999a60b835

src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 26 Sep 2016 00:29:36 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aci2/aci/ati_sms.c	Mon Sep 26 00:29:36 2016 +0000
@@ -0,0 +1,3765 @@
+/*
++----------------------------------------------------------------------------- 
+|  Project :  GSM-F&D (8411)
+|  Modul   :  ATI
++----------------------------------------------------------------------------- 
+|  Copyright 2002 Texas Instruments Berlin, AG 
+|                 All rights reserved. 
+| 
+|                 This file is confidential and a trade secret of Texas 
+|                 Instruments Berlin, AG 
+|                 The receipt of or possession of this file does not convey 
+|                 any rights to reproduce or disclose its contents or to 
+|                 manufacture, use, or sell anything it may describe, in 
+|                 whole, or in part, without the specific written consent of 
+|                 Texas Instruments Berlin, AG. 
++----------------------------------------------------------------------------- 
+|  Purpose :  AT Command Interpreter: SMS related functions.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef ATI_SMS_C
+#define ATI_SMS_C
+
+#undef DUMMY_ATI_STRINGS
+
+#include "aci_all.h"
+
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_io.h"
+#include "aci_cmd.h"
+#include "l4_tim.h"
+
+#include "aci_mem.h"
+
+#include "aci_lst.h"
+#include "conc_sms.h"
+#include "aci_prs.h"
+
+#include "ati_int.h"
+
+#include "cmh_sms.h"
+#include "psa.h"
+#include "psa_sms.h"
+#include "aci.h"
+
+#ifdef FF_ATI_BAT
+
+#include "typedefs.h"
+#include "gdd.h"
+#include "bat.h"
+
+#include "ati_bat.h"
+
+#endif /*FF_ATI_BAT*/
+
+EXTERN T_SMS_SHRD_PRM smsShrdPrm;
+
+const SMS_Memory sms_mem [] =
+{
+  {"ME",  SMS_STOR_Me},
+  {"SM",  SMS_STOR_Sm},
+  {0,0}
+};
+
+#if defined (SMS_PDU_SUPPORT)
+LOCAL T_ATI_RSLT atPlusCMGSText (char *cl, UBYTE srcId);
+LOCAL T_ATI_RSLT atPlusCMGWText (char *cl, UBYTE srcId);
+LOCAL T_ATI_RSLT atPlusCMGCText (char *cl, UBYTE srcId);
+LOCAL T_ATI_RSLT atPlusCNMAText (char *cl, UBYTE srcId);
+#endif
+
+/* move the define into aci_cmd.h */
+
+GLOBAL void         cmd_clearCnmiBuf    (void);
+
+LOCAL  T_CNMI_BUFFER    cnmiBuf;
+GLOBAL BOOL             cnmiFlushInProgress   = FALSE;
+GLOBAL S16              waitForCnmaFromBuffer_SrcId = CMD_SRC_NONE;
+LOCAL  CHAR daBuf[MAX_SMS_NUM_LEN];
+
+EXTERN SHORT  cmhSMS_getPrfRge ( void );
+EXTERN BOOL check_str(char * string,char * sample);
+
+#ifdef _SIMULATION_
+GLOBAL char subBuf[MAX_SUBADDR_LEN];
+#endif /* _SIMULATION_ */
+
+GLOBAL SHORT  toda_val;
+GLOBAL SHORT  fo, ct, pid, mn;
+
+GLOBAL UBYTE  cpmsCallType = NONE_CALL;
+
+/*
+ *
+ ----------------------------SMS Commands-----------------------------------
+ *
+ */
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCSMS         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CSMS command (Select Message Service)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCSMS (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = AT_FAIL;
+  T_ACI_CSMS_SERV service;
+
+  TRACE_FUNCTION("atPlusCSMS()");
+
+  /*input functionality*/
+  cl = parse (cl,"d",&service);
+  if ( !cl OR service > 1)
+  {
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return (ATI_FAIL);
+  }
+  ret = sAT_PlusCSMS(srcId,service);
+  if (ret EQ AT_FAIL)
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+  return (ATI_CMPL);
+}
+
+GLOBAL T_ATI_RSLT queatPlusCSMS (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = AT_FAIL;
+  T_ACI_CSMS_SERV service;
+  T_ACI_CSMS_SUPP mt;
+  T_ACI_CSMS_SUPP mo;
+  T_ACI_CSMS_SUPP bm;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+
+  ret = qAT_PlusCSMS(srcId,&service,&mt,&mo,&bm);
+  if (ret EQ AT_CMPL)
+  {
+    sprintf(g_sa,"+CSMS: %d,%d,%d,%d",service,mt,mo,bm);
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    return (ATI_CMPL);
+  }
+  if (ret EQ AT_EXCT)
+  {
+    src_params->curAtCmd    = AT_CMD_CSMS;
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCPMS         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CPMS command (Select Preferred Message Storage)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCPMS (char *cl, UBYTE srcId)
+{
+  CHAR*              me         = "+CPMS: ";
+  CHAR               memstr1[3] = {0};
+  CHAR               memstr2[3] = {0};
+  CHAR               memstr3[3] = {0};
+  T_ACI_RETURN       ret = AT_FAIL;
+  T_ACI_SMS_STOR_OCC mem1;
+  T_ACI_SMS_STOR_OCC mem2;
+  T_ACI_SMS_STOR_OCC mem3;
+  BOOL               f1         = TRUE;
+  BOOL               f2         = TRUE;
+  BOOL               f3         = TRUE;
+  SHORT              i;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCPMS()");
+
+  mem1.mem = SMS_STOR_NotPresent;
+  mem2.mem = SMS_STOR_NotPresent;
+  mem3.mem = SMS_STOR_NotPresent;
+
+  /*input functionality*/
+  cl = parse ( cl, "sss", (LONG)3, memstr1,
+                          (LONG)3, memstr2,
+                          (LONG)3, memstr3 );
+
+  strupper ( memstr1 );
+  strupper ( memstr2 );
+  strupper ( memstr3 );
+
+  for ( i=0; sms_mem[i].name NEQ NULL; i++ )
+  {
+    if ( ( strcmp ( sms_mem[i].name, memstr1 ) EQ 0 ) AND f1 )
+    {
+      mem1.mem = sms_mem[i].stor;
+      f1       = FALSE;
+    }
+
+    if ( ( strcmp ( sms_mem[i].name, memstr2 ) EQ 0 ) AND f2 )
+    {
+      mem2.mem = sms_mem[i].stor;
+      f2       = FALSE;
+    }
+
+    if ( ( strcmp ( sms_mem[i].name, memstr3 ) EQ 0 ) AND f3 )
+    {
+      mem3.mem = sms_mem[i].stor;
+      f3       = FALSE;
+    }
+  }
+
+  if (!cl OR f1 /*OR f2 OR f3*/ )
+  {
+    cmdCmsError ( CMS_ERR_OpNotAllowed );
+    return (ATI_FAIL);
+  }
+
+#ifdef FF_ATI_BAT
+{
+  T_BAT_cmd_send     cmd;
+  T_BAT_cmd_set_plus_cpms cpms;
+  cmd.ctrl_params              = BAT_CMD_SET_PLUS_CPMS;
+  cmd.params.ptr_set_plus_cpms = &cpms;
+
+  cpms.mem1 = (T_BAT_plus_cpms_mem1)mem1.mem;
+  cpms.mem2 = (T_BAT_plus_cpms_mem2)mem2.mem;
+  cpms.mem3 = (T_BAT_plus_cpms_mem3)mem3.mem;
+  
+  TRACE_FUNCTION("atPlusCPMS() calls bat_send() <=== as APPLICATION");
+  bat_send(ati_bat_get_client(srcId), &cmd);
+
+  return (AT_EXCT);
+}
+#else /* FF_ATI_BAT */
+
+  ret = sAT_PlusCPMS ( srcId, mem1.mem, mem2.mem, mem3.mem );
+
+  switch(ret)
+  {
+    case(AT_CMPL):
+    {
+      src_params->curAtCmd     = AT_CMD_NONE;
+      return (ATI_CMPL);
+    }
+    default:
+    {
+      cmdCmsError (CMS_ERR_NotPresent);  // use aciErrDesc
+      return (ATI_FAIL);
+    }
+  }
+  #endif /* FF_ATI_BAT */
+}
+
+GLOBAL T_ATI_RSLT queatPlusCPMS (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN       ret;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  /*returns current Memory setting*/
+  ret = qAT_PlusCPMS ( srcId );
+
+  if ( ret EQ AT_CMPL )
+  {
+    src_params->curAtCmd     = AT_CMD_NONE;
+    return (ATI_CMPL);
+  }
+  else if ( ret EQ AT_EXCT )
+  {
+    src_params->curAtCmd     = AT_CMD_CPMS;
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError ( CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGF         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGF command (Select Message Format)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCMGF (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = AT_FAIL;
+  T_ACI_CMGF_MOD mode=CMGF_MOD_NotPresent;
+
+  TRACE_FUNCTION("atPlusCMGF()");
+
+  /*
+   * input functionality
+   */
+  cl = parse(cl,"d",&mode);
+  if ( cl)
+  {
+    switch (mode)
+    {
+      case CMGF_MOD_Pdu:  /* PDU mode */
+#if !defined (SMS_PDU_SUPPORT)
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+#else
+         break;
+#endif
+       case CMGF_MOD_Txt:  /* Text Mode */
+       default:
+         break;
+     }
+   }
+   else
+   {
+     /*
+      * parse problems
+      */
+     cmdCmsError(CMS_ERR_OpNotAllowed);
+     return (ATI_FAIL);
+   }
+   /*
+    * Parameter is allowed then set
+    */
+   ret = sAT_PlusCMGF (srcId,mode);
+   if (ret EQ AT_FAIL)
+   {
+     cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+     return (ATI_FAIL);
+   }
+   return (map_aci_2_ati_rslt(ret));
+}
+
+GLOBAL T_ATI_RSLT queatPlusCMGF (char *cl, UBYTE srcId)
+{
+  char *me="+CMGF: ";
+  T_ACI_RETURN ret = AT_FAIL;
+  T_ACI_CMGF_MOD mode=CMGF_MOD_NotPresent;
+
+  TRACE_FUNCTION("queatPlusCMGF()");
+
+  /*
+   * returns current message format PDU/TEXT
+   */
+  ret = qAT_PlusCMGF(srcId, &mode);
+  if (ret EQ AT_CMPL)
+  {
+    sprintf(g_sa,"%s%d",me,mode);
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    return (ATI_CMPL);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCSCA         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CSCA command (Select Message Service Centre)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCSCA (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN  ret = ATI_FAIL;
+  T_ACI_TOA     tosca;
+  T_ACI_TOA    *p_tosca;
+  SHORT         octet=0;
+  CHAR          sca[MAX_SMS_NUM_LEN];
+
+  memset (sca, 0, sizeof(sca));
+  p_tosca=&tosca;
+
+  TRACE_FUNCTION("atPlusCSCA()");
+
+  /*input functionality*/
+  cl = parse (cl,"sr",(LONG)MAX_SMS_NUM_LEN,sca,&octet);
+  if ( !cl OR octet > 0xC9 OR sca[0] EQ '\0')
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+  if(octet EQ 0)
+    p_tosca=NULL;
+  else
+  {
+    tosca=toa_demerge(octet);
+    if (tosca.ton < 0 OR tosca.npi < 0)
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+  }
+#ifdef FF_ATI_BAT
+{
+  T_BAT_cmd_send     cmd;
+  T_BAT_cmd_set_plus_csca csca;
+  
+  cmd.ctrl_params              = BAT_CMD_SET_PLUS_CSCA;
+  cmd.params.ptr_set_plus_csca = &csca;
+
+  csca.c_sca = strlen(sca);  
+  memcpy(csca.sca, sca, csca.c_sca);
+  csca.tosca = octet;  
+
+  TRACE_FUNCTION("atPlusCSCA() calls bat_send() <=== as APPLICATION");
+  bat_send(ati_bat_get_client(srcId), &cmd);
+
+  return (AT_EXCT);
+}
+#else /* FF_ATI_BAT */
+ 
+  ret = sAT_PlusCSCA(srcId,sca,p_tosca);
+  if (ret EQ AT_FAIL)
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+  return (map_aci_2_ati_rslt(ret));
+#endif /* FF_ATI_BAT */
+}
+
+GLOBAL T_ATI_RSLT queatPlusCSCA (char *cl, UBYTE srcId)
+{
+#ifdef FF_ATI_BAT
+  T_BAT_cmd_send     cmd;
+  T_BAT_no_parameter dummy;
+  
+  cmd.ctrl_params              = BAT_CMD_QUE_PLUS_CSCA;
+  dummy.bat_dummy              = 0xFF;
+  cmd.params.ptr_que_plus_csca = &dummy;
+
+  TRACE_FUNCTION("queatPlusCSCA() calls bat_send() <=== as APPLICATION");
+  bat_send(ati_bat_get_client(srcId), &cmd);
+
+  return (AT_EXCT);
+
+#else /* FF_ATI_BAT */
+
+  T_ACI_RETURN  ret = AT_FAIL;
+  T_ACI_TOA     tosca;
+  SHORT         octet=0;
+  CHAR          sca[MAX_SMS_NUM_LEN];
+
+  ret = qAT_PlusCSCA (srcId,sca,&tosca);
+  if (ret EQ AT_CMPL)
+  {
+    octet=toa_merge(tosca);
+    sprintf(g_sa, "+CSCA: \"%s%s\",%d", (tosca.ton EQ TON_International)?"+":"", sca, octet);
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    return (ATI_CMPL);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+#endif /* FF_ATI_BAT */  
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : aci_decodeVpabs    |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function decodes a given string to the T_ACI_VP_ABS
+            enumeration type.
+*/
+LOCAL BOOL aci_decodeVpabs ( CHAR*         vpabs_str,
+                             T_ACI_VP_ABS* vpabs_enum )
+{
+  if ( strlen( vpabs_str ) NEQ 20 OR
+
+       vpabs_str[2]  NEQ '/' OR vpabs_str[5]  NEQ '/' OR
+       vpabs_str[8]  NEQ ',' OR vpabs_str[11] NEQ ':' OR
+       vpabs_str[14] NEQ ':' OR
+
+       ( vpabs_str[17] NEQ '+' AND vpabs_str[17] NEQ '-' ) OR
+
+       vpabs_str[18] < '0' OR vpabs_str[18] > '9' OR
+       vpabs_str[19] < '0' OR vpabs_str[19] > '9'             )
+
+    return FALSE;
+
+  vpabs_enum->year  [0] = vpabs_str[0]  - 0x30;
+  vpabs_enum->year  [1] = vpabs_str[1]  - 0x30;
+
+  vpabs_enum->month [0] = vpabs_str[3]  - 0x30;
+  vpabs_enum->month [1] = vpabs_str[4]  - 0x30;
+
+  vpabs_enum->day   [0] = vpabs_str[6]  - 0x30;
+  vpabs_enum->day   [1] = vpabs_str[7]  - 0x30;
+
+  vpabs_enum->hour  [0] = vpabs_str[9]  - 0x30;
+  vpabs_enum->hour  [1] = vpabs_str[10] - 0x30;
+
+  vpabs_enum->minute[0] = vpabs_str[12] - 0x30;
+  vpabs_enum->minute[1] = vpabs_str[13] - 0x30;
+
+  vpabs_enum->second[0] = vpabs_str[15] - 0x30;
+  vpabs_enum->second[1] = vpabs_str[16] - 0x30;
+
+  vpabs_enum->timezone  = (SHORT) atoi( &vpabs_str[17] );
+
+  return TRUE;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : aci_decodeVpenh    |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function decodes a given string to the T_ACI_VP_ENH
+            type.
+*/
+LOCAL BOOL aci_decodeVpenh ( CHAR*         vpenh_str,
+                             T_ACI_VP_ENH* vpenh )
+{
+  UBYTE shift_byte = 0;
+
+  if (vpenh_str[0] EQ '\0')
+  {
+    return FALSE;
+  }
+
+  /* functionality indicator */
+  vpenh->func_ind = (vpenh_str[0]  - 0x30) << 4;
+  vpenh->func_ind += (vpenh_str[1]  - 0x30);
+
+  /* extension octet */
+  if (vpenh->func_ind & TP_VPF_ENH_EXT_BIT_MASK)
+  {
+    shift_byte = 2;
+    vpenh->ext_oct = (vpenh_str[2]  - 0x30) << 4;
+    vpenh->ext_oct += (vpenh_str[3]  - 0x30);
+  }
+
+  if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) > TP_VPF_ENH_HRS)
+  {
+    return FALSE;
+  }
+
+  /* process validity period values */
+  if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_REL)
+  {
+    utl_HexStrToBin ((UBYTE*)&vpenh_str[2+shift_byte], 2, &vpenh->val.vpenh_relative, 1);
+  }
+  else if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_SEC)
+  {
+    utl_HexStrToBin ((UBYTE*)&vpenh_str[2+shift_byte], 2, &vpenh->val.vpenh_seconds, 1);
+  }
+  else if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_HRS)
+  {
+    vpenh->val.vpenh_hours.hour  [0] = vpenh_str[3+shift_byte] - 0x30;
+    vpenh->val.vpenh_hours.hour  [1] = vpenh_str[2+shift_byte] - 0x30;
+
+    vpenh->val.vpenh_hours.minute[0] = vpenh_str[5+shift_byte] - 0x30;
+    vpenh->val.vpenh_hours.minute[1] = vpenh_str[4+shift_byte] - 0x30;
+
+    vpenh->val.vpenh_hours.second[0] = vpenh_str[7+shift_byte] - 0x30;
+    vpenh->val.vpenh_hours.second[1] = vpenh_str[6+shift_byte] - 0x30;
+  }
+
+  return TRUE;
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCSMP         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CSMP command (Select Text Mode Parameters)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCSMP (char *cl, UBYTE srcId)
+{
+
+  char*         me            = "+CSMP: ";
+  T_ACI_RETURN  ret           = AT_FAIL;
+  SHORT         fo            = ACI_NumParmNotPresent,
+                vprel         = ACI_NumParmNotPresent,
+                pid           = ACI_NumParmNotPresent,
+                dcs           = ACI_NumParmNotPresent;
+  USHORT        i             = 0;
+  char          vpabs_str[25] = {'\0'},
+                vpenh_str[15] = {'\0'},
+                fo_str[4];
+
+  T_ACI_VP_ABS  vpabs;
+  T_ACI_VP_ABS* pVpabs        = NULL;
+  T_ACI_VP_ENH  vpenh;
+
+  TRACE_FUNCTION("atPlusCSMP()");
+
+   /*input functionality*/
+   while (*cl NEQ ',' AND *cl NEQ '\0' AND i < sizeof(fo_str) - 1)
+   {
+     fo_str[i]=*cl;
+     cl++;
+     i++;
+   }
+   if (*cl)
+   {
+     cl++;
+   }
+   fo_str[i]='\0';
+   if (strlen (fo_str) > 0)
+   {
+     fo=atoi(fo_str);
+   }
+   if (fo > 255)
+   {
+     cmdCmsError(CMS_ERR_OpNotAllowed);
+     return 0;
+   }
+   if (fo NEQ ACI_NumParmNotPresent AND
+       (fo & TP_VPF_MASK) EQ TP_VPF_ABSOLUTE)
+   {
+     pVpabs = &vpabs;
+
+     cl = parse(cl,"srr",(LONG)25,vpabs_str,&pid,&dcs);
+
+     if (!cl OR strlen(vpabs_str) > 20 OR pid > 255 OR
+         dcs > 255 OR !aci_decodeVpabs (vpabs_str, &vpabs))
+     {
+       cmdCmsError(CMS_ERR_OpNotAllowed);
+       return (ATI_FAIL);
+     }
+   }
+   else if (fo NEQ ACI_NumParmNotPresent AND
+       (fo & TP_VPF_MASK) EQ TP_VPF_ENHANCED)
+   {
+     cl = parse(cl,"srr",(LONG)19,vpenh_str,&pid,&dcs);
+     if (!cl OR strlen(vpenh_str) > 14 OR pid > 255 OR
+         dcs > 255 OR !aci_decodeVpenh (vpenh_str, &vpenh))
+     {
+       cmdCmsError(CMS_ERR_OpNotAllowed);
+       return (ATI_FAIL);
+     }
+   }
+   else if (fo NEQ ACI_NumParmNotPresent AND
+       (fo & TP_VPF_MASK) EQ TP_VPF_RELATIVE)
+   {
+     cl = parse(cl,"rrr",&vprel,&pid,&dcs);
+   }
+   else
+   {
+     if (*cl EQ '\"')
+     {
+       pVpabs = &vpabs;
+
+       cl = parse(cl,"srr",(LONG)25,vpabs_str,&pid,&dcs);
+
+       if (!cl OR strlen(vpabs_str) > 20 OR pid > 255 OR
+           dcs > 255 OR !aci_decodeVpabs (vpabs_str, &vpabs))
+       {
+         cmdCmsError(CMS_ERR_OpNotAllowed);
+         return (ATI_FAIL);
+       }
+     }
+     else
+     {
+       cl = parse(cl,"rrr",&vprel,&pid,&dcs);
+
+       if ( !cl OR vprel > 255 OR pid > 255 OR dcs > 255)
+       {
+         cmdCmsError(CMS_ERR_OpNotAllowed);
+         return (ATI_FAIL);
+       }
+     }
+   }
+   ret = sAT_PlusCSMP(srcId,fo,vprel,pVpabs,&vpenh,pid,dcs);
+   if (ret EQ AT_FAIL)
+   {
+     cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+     return (ATI_FAIL);
+   }
+   return (map_aci_2_ati_rslt(ret));
+}
+
+GLOBAL T_ATI_RSLT queatPlusCSMP (char *cl, UBYTE srcId)
+{
+  char*         me            = "+CSMP: ";
+  T_ACI_RETURN  ret           = AT_FAIL;
+  SHORT         fo            = ACI_NumParmNotPresent,
+                vprel         = ACI_NumParmNotPresent,
+                pid           = ACI_NumParmNotPresent,
+                dcs           = ACI_NumParmNotPresent,
+                i             = 0;
+  char          vpabs_str[25] = {'\0'};
+  char          vpenh_str[15] = {'\0'};
+  T_ACI_VP_ABS  vpabs;
+  T_ACI_VP_ENH  vpenh;
+
+  TRACE_FUNCTION("queatPlusCSMP()");
+
+  ret = qAT_PlusCSMP(srcId,&fo,&vprel,&vpabs,&vpenh,&pid,&dcs);
+  if (ret EQ AT_CMPL)
+  {
+    if ((fo & TP_VPF_MASK) EQ TP_VPF_ABSOLUTE)   /*Bits 4,3 -> 11*/
+    {
+      sprintf(vpabs_str,"\"%d%d/%d%d/%d%d,%d%d:%d%d:%d%d%+03d\"",
+              vpabs.year  [0], vpabs.year  [1],
+              vpabs.month [0], vpabs.month [1],
+              vpabs.day   [0], vpabs.day   [1],
+              vpabs.hour  [0], vpabs.hour  [1],
+              vpabs.minute[0], vpabs.minute[1],
+              vpabs.second[0], vpabs.second[1],
+              vpabs.timezone);
+      sprintf(g_sa,"%s%d,%s,%d,%d",me,fo,vpabs_str,pid,dcs);
+    }
+    else if ((fo & TP_VPF_MASK) EQ TP_VPF_ENHANCED)
+    {
+      aci_encodeVpenh ( vpenh_str, &vpenh );
+      sprintf(g_sa,"%s%d,\"%s\",%d,%d",me,fo,vpenh_str,pid,dcs);
+    }
+    else if ((fo & TP_VPF_MASK) EQ TP_VPF_RELATIVE) /*Bits 4,3 -> 10*/
+    {
+      sprintf(g_sa,"%s%d,%d,%d,%d",me,fo,vprel,pid,dcs);
+    }
+    else
+    {
+      sprintf(g_sa,"%s%d,,%d,%d",me,fo,pid,dcs);
+    }
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    return (ATI_CMPL);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCSDH         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CSDH command (Show Text Mode Parameters)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCSDH (char *cl, UBYTE srcId)
+{
+
+  T_ACI_CSDH_SHOW ena = CSDH_SHOW_Disable;
+
+  TRACE_FUNCTION("atPlusCSDH()");
+
+   /*input functionality*/
+   cl = parse(cl,"d",&ena);
+   if ( !cl )
+   {
+     cmdCmsError(CMS_ERR_OpNotAllowed);
+     return (ATI_FAIL);
+   }
+   ati_user_output_cfg[srcId].CSDH_stat=ena;
+   return (ATI_CMPL);
+}
+
+GLOBAL T_ATI_RSLT tesatPlusCSDH (char *cl, UBYTE srcId)
+{
+  return(atPlusCSDH (cl, srcId));
+}
+
+GLOBAL T_ATI_RSLT queatPlusCSDH (char *cl, UBYTE srcId)
+{
+  sprintf(g_sa,"+CSDH: %d",ati_user_output_cfg[srcId].CSDH_stat);
+  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+  return (ATI_CMPL);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCSCB         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CSCB command (select cell broadcast message type)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCSCB (char *cl, UBYTE srcId)
+{
+  char            *me="+CSCB: ";
+  T_ACI_RETURN    ret = AT_FAIL;
+  T_ACI_CSCB_MOD  mode;
+  char            mids_str[6*MAX_CBM_TYPES]={0};    /* CHECK IF LONG ENOUGH !!*/
+  char            dcss_str[4*MAX_CBM_TYPES]={0};
+  CHAR            buf[6]={0};
+  USHORT          mids[MAX_CBM_TYPES];
+  UBYTE           dcss[MAX_CBM_TYPES];
+  SHORT           pos=0,i=0,j=0;
+
+#ifdef FF_ATI_BAT
+  T_BAT_cmd_set_plus_cscb cscb;
+#endif
+
+
+  TRACE_FUNCTION("atPlusCSCB()");
+
+   /*input functionality*/
+   cl = parse(cl,"dss",&mode,(LONG)sizeof(mids_str),mids_str,(LONG)sizeof(dcss_str),dcss_str);
+   if ( !cl )
+   {
+     cmdCmsError(CMS_ERR_OpNotAllowed);
+     return (ATI_FAIL);
+   }
+   i = j = 0;
+   memset (mids, NOT_PRESENT_8BIT, sizeof (mids));
+   while (mids_str[i] NEQ '\0' AND j < MAX_CBM_TYPES - 1)
+   {
+     pos=0;
+     while (mids_str[i] >= '0'  AND  mids_str[i] <= '9')
+     {
+       if (pos >= 5)
+       {
+         cmdCmsError(CMS_ERR_OpNotAllowed);
+         return (ATI_FAIL);
+       }
+       buf[pos++]=mids_str[i];
+       i++;
+     }
+     buf[pos]='\0';
+     if (mids_str[i] NEQ ','  AND  mids_str[i] NEQ '-'  AND  mids_str[i] NEQ '\0')
+     {
+       cmdCmsError(CMS_ERR_OpNotAllowed);
+       return (ATI_FAIL);
+     }
+     else
+     {
+       if (mids_str[i] EQ ',' OR mids_str[i] EQ '\0')
+       {
+         i++;
+         mids[j++]=atoi(buf);
+         mids[j++]=atoi(buf);
+       }
+       else
+       {
+         i++;
+         mids[j++]=atoi(buf);
+         pos=0;
+         while (mids_str[i] NEQ ','  AND  mids_str[i] NEQ '\0')
+         {
+           if (pos >= 5)
+           {
+             cmdCmsError(CMS_ERR_OpNotAllowed);
+             return (ATI_FAIL);
+           }
+           buf[pos++]=mids_str[i];
+           i++;
+         }
+         i++;
+         mids[j++]=atoi(buf);
+       }
+     }
+   }
+ 
+   if (compact(&mids_str[i],(USHORT)strlen(&mids_str[i])) NEQ 0)
+   {
+     cmdCmsError(CMS_ERR_OpNotAllowed);
+     return (ATI_FAIL);
+   }
+
+#ifdef FF_ATI_BAT
+   memset(cscb.mids, NOT_PRESENT_8BIT, sizeof(cscb.mids));
+   cscb.v_mids = j ? TRUE : FALSE;
+   cscb.c_mids = (U8)j;
+   memcpy(cscb.mids, mids, j*2);
+#endif
+
+   i = j = 0;
+   memset (dcss, NOT_PRESENT_8BIT, sizeof (dcss));
+   while (dcss_str[i] NEQ '\0' AND j < MAX_CBM_TYPES - 1)
+   {
+     pos=0;
+     while (dcss_str[i] >= '0'  AND  dcss_str[i] <= '9')
+     {
+       if (pos >= 3)
+       {
+         cmdCmsError(CMS_ERR_OpNotAllowed);
+         return (ATI_FAIL);
+       }
+       buf[pos++]=dcss_str[i];
+       i++;
+     }
+     buf[pos]='\0';
+     if (dcss_str[i] NEQ ','  AND  dcss_str[i] NEQ '-'  AND  dcss_str[i] NEQ '\0')
+     {
+       cmdCmsError(CMS_ERR_OpNotAllowed);
+       return (ATI_FAIL);
+     }
+     else
+     {
+       if (dcss_str[i] EQ ',' OR dcss_str[i] EQ '\0')
+       {
+         i++;
+         dcss[j++]=atoi(buf);
+         dcss[j++]=atoi(buf);
+       }
+       else
+       {
+         i++;
+         dcss[j++]=atoi(buf);
+         pos=0;
+         while (dcss_str[i] NEQ ','  AND  dcss_str[i] NEQ '\0')
+         {
+           if (pos >= 3)
+           {
+             cmdCmsError(CMS_ERR_OpNotAllowed);
+             return (ATI_FAIL);
+           }
+           buf[pos++]=dcss_str[i];
+           i++;
+         }
+         i++;
+         dcss[j++]=atoi(buf);
+       }
+     }
+   }
+   if (compact(&dcss_str[i],(USHORT)strlen(&dcss_str[i])) NEQ 0)
+   {
+     cmdCmsError(CMS_ERR_OpNotAllowed);
+     return (ATI_FAIL);
+   }
+   
+#ifdef FF_ATI_BAT
+   {
+      T_BAT_cmd_send cmd;
+
+      cmd.ctrl_params = BAT_CMD_SET_PLUS_CSCB;
+      cmd.params.ptr_set_plus_cscb = &cscb;
+
+      cscb.mode = (T_BAT_VAL_plus_cscb_mode)mode;
+            
+      memset(cscb.dcss, NOT_PRESENT_8BIT, sizeof(cscb.dcss));
+      cscb.v_dcss = j ? TRUE : FALSE;;
+      cscb.c_dcss = (U8)j;
+      memcpy(cscb.dcss, dcss, cscb.c_dcss);
+      
+      
+      TRACE_FUNCTION("atPlusCSCB() calls bat_send() <=== as APPLICATION");
+      bat_send(ati_bat_get_client(srcId), &cmd);
+      return (AT_EXCT);
+   }
+#else /* FF_ATI_BAT */
+   ret=sAT_PlusCSCB(srcId,mode,mids,dcss);
+   if (ret EQ AT_FAIL)
+   {
+     cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+     return (ATI_FAIL);
+   }
+   return (map_aci_2_ati_rslt(ret));
+#endif /* FF_ATI_BAT */
+}
+
+GLOBAL T_ATI_RSLT queatPlusCSCB (char *cl, UBYTE srcId)
+{
+#ifdef FF_ATI_BAT
+  T_BAT_cmd_send     cmd;
+  T_BAT_no_parameter dummy;
+  
+  cmd.ctrl_params              = BAT_CMD_QUE_PLUS_CSCB;
+  dummy.bat_dummy              = 0xFF;
+  cmd.params.ptr_que_plus_cscb = &dummy;
+
+  TRACE_FUNCTION("queatPlusCSCB() calls bat_send() <=== as APPLICATION");
+  bat_send(ati_bat_get_client(srcId), &cmd);
+
+  return (AT_EXCT);
+
+#else /* FF_ATI_BAT */
+  T_ACI_CSCB_MOD  mode;
+  char            mids_str[6*MAX_CBM_TYPES+1]={'\0'}; /* +1 for '\0' */  /* CHECK IF LONG ENOUGH !!*/
+  char            dcss_str[4*MAX_CBM_TYPES+1]={'\0'};
+  USHORT          mids[MAX_CBM_TYPES];
+  UBYTE           dcss[MAX_CBM_TYPES];
+  SHORT           pos=0,i=0;
+  T_ACI_RETURN    ret = AT_FAIL;
+
+  TRACE_FUNCTION("queatPlusCSCB()");
+
+  ret = qAT_PlusCSCB(srcId, &mode,mids,dcss);
+  if (ret EQ AT_CMPL)
+  {
+    /*
+     *-----------------------------------------------------------
+     * assemble the string for message identifiers
+     *-----------------------------------------------------------
+     */
+    pos = i = 0;
+    while( mids[i]   NEQ 0xFFFF   AND
+           mids[i+1] NEQ 0xFFFF   AND
+           i < MAX_CBM_TYPES - 1    )
+    {
+      if ( mids[i] EQ mids[i+1] )
+        pos += sprintf ( mids_str + pos, "%d,", mids[i] );
+      else
+        pos += sprintf ( mids_str + pos, "%d-%d,", mids[i], mids[i+1] );  /* "65534-65535," max 12 chars */
+
+      i += 2;
+    }
+
+    /*lint -e(661) -e(662) */   /* lint 7.5 has here some problems ... */
+    if ( pos > 0 )              /* remove the last ',' */
+    {
+        mids_str[pos-1] = '\0';
+    }
+
+    /*
+     *-----------------------------------------------------------
+     * assemble the string for data coding schemes
+     *-----------------------------------------------------------
+     */
+    pos = i = 0;
+    while( dcss[i]   NEQ 0xFF    AND
+           dcss[i+1] NEQ 0xFF    AND
+           i < MAX_CBM_TYPES - 1     )
+    {
+      if ( dcss[i] EQ dcss[i+1] )
+        pos += sprintf ( dcss_str + pos, "%d,", dcss[i] );
+      else
+        pos += sprintf ( dcss_str + pos, "%d-%d,", dcss[i], dcss[i+1] );
+
+      i += 2;
+    }
+
+    /*lint -e(661) -e(662) */
+    if ( pos > 0 )    /* remove the last ',' */
+    {
+      dcss_str[pos-1] = '\0';
+    }
+
+    sprintf(g_sa,"+CSCB: %d,\"%s\",\"%s\"",mode,mids_str,dcss_str);
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    return (ATI_CMPL);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+#endif /* FF_ATI_BAT */
+}
+
+#ifdef FF_HOMEZONE
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPercentCBHZ      |
++--------------------------------------------------------------------+
+
+  PURPOSE : %CBHZ command (set homezone activity)
+*/
+
+GLOBAL T_ATI_RSLT setatPercentCBHZ (char *cl, UBYTE srcId)
+{
+  T_ACI_CBHZ_MOD  mode    = CBHZ_MOD_NotPresent;
+  T_ACI_CS        dcs     = CS_NotPresent;
+  UBYTE           timeout = NOT_PRESENT_8BIT;
+  T_ACI_RETURN    ret     = AT_FAIL;
+
+  TRACE_FUNCTION("setatPercentCBHZ()");
+
+
+  /*input functionality*/
+
+  /*check first parameter */
+  switch (*cl)
+  {
+    case '0':
+    case '1':
+      mode = *cl - 0x30;
+      cl++;
+      break;
+
+    default:
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+  }
+
+  /* check second parameter */
+  if  ( *cl NEQ '\0' )
+  {
+    if ( *cl NEQ ',')
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+    cl++;
+
+    if ( (*cl >= '0') AND (*cl <= '9') )
+    {
+      dcs = *cl -0x30;
+      cl++;
+    }
+
+    /* check third parameter */
+    if  ( *cl NEQ '\0' )
+    {
+      if ( *cl NEQ ',')
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+      cl++;
+
+      cl = parse(cl,"d",&timeout);
+      if  ( *cl NEQ '\0' )
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+    }
+  }
+
+  /* parameters ok... process homezone request */
+  ret = sAT_PercentCBHZ(srcId,mode,dcs,timeout);
+  if (ret EQ AT_FAIL)
+  {
+    cmdCmeError(CME_ERR_Unknown);
+    return (ATI_FAIL);
+  }
+
+  return (ATI_CMPL);
+}
+
+
+GLOBAL T_ATI_RSLT tesatPercentCBHZ (char *cl, UBYTE srcId)
+{
+  TRACE_FUNCTION("tesatPercentCBHZ()");
+
+  sprintf( g_sa, "%s: (%d,%d),(%d-%d),(%d-%d)",
+             "%CBHZ", CBHZ_MOD_NotActive, CBHZ_MOD_Active,
+             CS_GsmDef, CS_Ascii, CBHZ_MIN_TIMEOUT, CBHZ_MAX_TIMEOUT);
+
+
+  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+
+  return (ATI_CMPL);
+}
+
+GLOBAL T_ATI_RSLT queatPercentCBHZ (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN    ret;
+  T_ACI_CBHZ_MOD  mode;
+  T_ACI_CS        dcs;
+  UBYTE           timeout;
+
+  TRACE_FUNCTION("queatPercentCBSHZ()");
+
+  ret = qAT_PercentCBHZ(srcId, &mode, &dcs, &timeout);
+
+  if (ret EQ AT_FAIL)
+  {
+    cmdCmeError(CME_ERR_Unknown);
+    return (ATI_FAIL);
+  }
+
+  /*
+   *-----------------------------------------------------------
+   * assemble the string for output
+   *-----------------------------------------------------------
+   */
+
+  sprintf( g_sa, "%s: %d,%d,%d", "%CBHZ", mode, dcs, timeout);
+
+  io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+
+  return (ATI_CMPL);
+}
+#endif /* FF_HOMEZONE */
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCSAS         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CSAS command (Save SMS Profile)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCSAS (char *cl, UBYTE srcId)
+{
+  SHORT        profile  = -1;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCSAS()");
+
+  if ( *cl EQ '\0' )
+  {
+    profile = 1;
+  }
+  else
+  {
+    cl = parse ( cl, "r", &profile );
+    if ( !cl )
+    {
+      cmdCmsError ( CMS_ERR_MemFail );
+      return (ATI_FAIL);
+    }
+    profile++;
+  }
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_csas csas;
+
+    cmd.ctrl_params = BAT_CMD_SET_PLUS_CSAS;
+    cmd.params.ptr_set_plus_csas = &csas;
+
+    csas.profile = profile;
+
+    TRACE_FUNCTION("atPlusCSAS() calls bat_send() <=== as APPLICATION");
+    bat_send(ati_bat_get_client(srcId), &cmd);
+    return (AT_EXCT);
+  }
+#else /* FF_ATI_BAT */
+  switch (sAT_PlusCSAS (srcId, profile))
+  {
+    case AT_EXCT:
+      src_params->curAtCmd    = AT_CMD_CSAS;
+      return (ATI_EXCT);
+
+    case AT_BUSY:
+      return (ATI_BUSY);
+
+    case AT_CMPL:
+      return (ATI_CMPL_NO_OUTPUT);
+
+    case AT_FAIL:           /* execution of command failed */
+    default:
+      cmdCmsError ( CMS_ERR_NotPresent);  /* use aciErrDesc */
+      return (ATI_FAIL);
+  }
+#endif /* FF_ATI_BAT */
+}
+
+GLOBAL T_ATI_RSLT tesatPlusCSAS (char *cl, UBYTE srcId)
+{
+  SHORT        profile  = -1;
+
+  if ((profile = cmhSMS_getPrfRge ()) < 1)
+  {
+    cmdCmsError ( CMS_ERR_MemFail );
+    return (ATI_FAIL);
+  }
+  else
+  {
+    sprintf ( g_sa, "+CSAS: (0-%d)", profile - 1 );
+    io_sendMessage ( srcId, g_sa, ATI_NORMAL_OUTPUT );
+    return (ATI_CMPL);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCRES         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CRES command (Load SMS Profile)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCRES (char *cl, UBYTE srcId)
+{
+  SHORT        profile  = -1;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCRES()");
+
+  if ( *cl EQ '\0' )
+  {
+    profile = 1;
+  }
+  else
+  {
+    cl = parse ( cl, "r", &profile );
+
+    if ( !cl )
+    {
+      cmdCmsError ( CMS_ERR_MemFail );
+      return (ATI_FAIL);
+    }
+    profile++;
+  }
+
+  switch (sAT_PlusCRES (srcId, profile))
+  {
+    case AT_EXCT:
+      src_params->curAtCmd    = AT_CMD_CRES;
+      return (ATI_EXCT);
+
+    case AT_BUSY:
+      return (ATI_BUSY);
+
+    case AT_CMPL:
+      io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+      return (ATI_CMPL_NO_OUTPUT);
+
+    case AT_FAIL:
+    default:
+      cmdCmsError ( CMS_ERR_NotPresent);  // use aciErrDesc
+      return (ATI_FAIL);
+  }
+}
+
+GLOBAL T_ATI_RSLT tesatPlusCRES (char *cl, UBYTE srcId)
+{
+  T_ACI_CRES    profile;
+  T_ACI_RETURN  result;
+
+  result = tAT_PlusCRES (srcId, &profile);
+  switch (result)
+  {
+    case AT_FAIL:
+      cmdCmsError ( CMS_ERR_MemFail );
+      return (ATI_FAIL);
+
+    case AT_CMPL:
+      break;
+
+    default:
+      cmdCmsError ( CMS_ERR_MemFail );
+      return (ATI_FAIL); 
+  }
+
+  sprintf ( g_sa, "+CRES: (%d-%d)", profile.min, profile.max);
+  io_sendMessage ( srcId, g_sa, ATI_NORMAL_OUTPUT );
+  return (ATI_CMPL);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGR         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGR command (Read Message)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCMGR (char *cl, UBYTE srcId)
+{
+  char *me="+CMGR: ";
+  T_ACI_RETURN ret = AT_FAIL;
+  SHORT idx=-1;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCMGR()");
+
+#ifndef WIN32
+   cl = parse(cl,"r",&idx);
+#else
+   cl = parse(cl,"rd",&idx, &smsReadMode );
+#endif
+  if ( !cl OR idx > 255 OR idx < 0)
+  {
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return (ATI_FAIL);
+  }
+
+#ifdef FF_ATI_BAT
+
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_cmgr cmgr;
+
+    cmd.ctrl_params=BAT_CMD_SET_PLUS_CMGR;
+    cmd.params.ptr_set_plus_cmgr=&cmgr;
+
+    cmgr.sms_index=(U16)idx;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+
+    src_params->curAtCmd=AT_CMD_CMGR;
+    return(ATI_EXCT);
+  }
+
+#else
+
+#ifndef _CONC_TESTING_
+#ifndef _SIMULATION_
+  ret = sAT_PlusCMGR_Gl(srcId, (UBYTE)idx, SMS_READ_Normal, NULL);
+#else
+  ret = sAT_PlusCMGR_Gl(srcId, (UBYTE)idx, smsReadMode , NULL);
+#endif
+#else
+#ifndef _SIMULATION_
+  ret = sAT_PlusCMGR (srcId, (UBYTE)idx, SMS_READ_Normal);
+#else
+  ret = sAT_PlusCMGR (srcId, (UBYTE)idx, smsReadMode );
+#endif
+#endif
+ if ( ret EQ AT_CMPL )
+ {
+   return (ATI_CMPL);
+ }
+ else if (ret EQ AT_EXCT)
+ {
+   src_params->curAtCmd    = AT_CMD_CMGR;
+   return (ATI_EXCT);
+ }
+ else
+ {
+   cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+   return (ATI_FAIL);
+ }
+
+#endif /*FF_ATI_BAT*/
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGS         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGS command (SEND Message)
+*/
+
+GLOBAL T_ATI_RSLT tesatPlusCMGS (char *cl, UBYTE srcId)
+{
+  io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+  return ATI_CMPL_NO_OUTPUT;
+}
+
+GLOBAL T_ATI_RSLT queatPlusCMGS (char *cl, UBYTE srcId)
+{
+  cmdCmsError(CMS_ERR_OpNotAllowed); /* querying CMGS not specified in 07.05 */
+  return (ATI_FAIL);
+}
+
+
+GLOBAL T_ATI_RSLT atPlusCMGS (char *cl, UBYTE srcId)
+#if defined (SMS_PDU_SUPPORT)
+{
+  T_ACI_CMGF_MOD mode;
+  
+  TRACE_FUNCTION("atPlusCMGS()");
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+  {
+    /*
+     * handle PDU mode
+     */
+    return (atPlusCMGSPdu (cl, srcId));
+  }
+  else
+  {
+    /*
+     * handle Text mode
+     */
+    return (atPlusCMGSText (cl, srcId));
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)            MODULE  : ACI_CMD              |
+| STATE   : code                      ROUTINE : str_to_bcd           |
++--------------------------------------------------------------------+
+
+  PURPOSE : A very specialised routine for converting a 2-byte string
+            into one byte of BCD, intended to be used by atPlusCMGSText()
+            only.
+*/
+LOCAL UBYTE str_to_bcd(
+  CHAR *str)
+{
+  UBYTE bcd;
+  UBYTE n;
+
+  for (n=0;n<2;n++)
+  {
+    bcd>>=4;
+
+    if ((str[n]<'0') || (str[n]>'9'))
+      bcd+=0xF0;
+    else
+      bcd+=(str[n]-'0')<<4;
+  }
+
+  return(bcd);
+}
+
+
+LOCAL T_ATI_RSLT atPlusCMGSText(char *cl, UBYTE srcId)
+#endif /* (SMS_PDU_SUPPORT) */
+{
+         T_ACI_VP_ABS  vpabs;
+         SHORT         fo,
+                       vprel,
+                       pid,
+                       dcs;
+         CHAR*         me        = "+CMGS: ";
+         T_ACI_RETURN  ret       = AT_FAIL;
+         T_ACI_TOA     toda;
+         T_ACI_TOA*    p_toda;
+  GLOBAL SHORT         toda_val  = 0;
+         T_ACI_SM_DATA msg;
+         USHORT        lenMsg;
+         CHAR*         da = daBuf;
+
+  static T_ACI_TOA     tosca;
+  static T_ACI_TOA    *p_tosca;
+#ifdef _SIMULATION_
+  CHAR         *sca =subBuf;
+#endif /* _SIMULATION_ */
+  SHORT         octet=0;
+  static SHORT         isReply;
+
+#ifdef _CONC_TESTING_
+  T_SM_DATA_EXT msg_conc;
+#endif
+
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  if (src_params->text_mode EQ CMD_MODE)
+  {
+    TRACE_FUNCTION("atPlusCMGSText() CMD_MODE");
+    memset (da, 0, MAX_SMS_NUM_LEN);
+    /* input functionality */
+    da[0]='\0';
+#ifndef WIN32
+    cl = parse (cl,"sr",(LONG)MAX_SMS_NUM_LEN,da,&toda_val);
+    if ( !cl OR da[0] EQ '\0')
+    {
+      cmdCmsError (CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+#else
+    *sca    ='\0';
+    isReply = -1;
+    cl = parse (cl,"srsrb",(LONG)MAX_SMS_NUM_LEN,da,&toda_val,
+                           (LONG)MAX_SMS_NUM_LEN,sca,&octet,&isReply);
+    if ( !cl OR da[0] EQ '\0')
+    {
+      cmdCmsError (CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+    if (octet EQ 0)
+    {
+      p_tosca=NULL;
+    }
+    else
+    {
+      tosca=toa_demerge(octet);
+      if (tosca.ton < 0 OR tosca.npi < 0)
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+    }
+#endif
+    if (toda_val)
+    {
+      toda=toa_demerge(toda_val);
+      if (toda.ton < 0 OR toda.npi < 0)
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+    }
+
+    src_params->text_mode = TXT_MODE;
+    return (ATI_EXCT);
+  } /* end of if (src_params->text_mode EQ CMD_MODE) */
+  else
+  {
+    TRACE_FUNCTION("atPlusCMGSText() TXT_MODE");
+
+    src_params->text_mode = CMD_MODE;
+    /* if the character sent is ESC, then abort command CLB 16.11.00 */
+    if (*cl EQ 0x1B)
+    {
+      TRACE_EVENT("Send message command cancelled by user");
+
+      return ATI_CMPL_NO_OUTPUT;
+    }
+
+    if ( toda_val EQ 0 )
+    {
+#ifndef _SIMULATION_
+#endif /* ndef _SIMULATION_ */
+      p_toda = NULL;
+    }
+    else
+    {
+      toda   = toa_demerge ( toda_val );
+      p_toda = &toda;
+    }
+
+    qAT_PlusCSMP  ( srcId, &fo, &vprel, &vpabs, NULL, &pid, &dcs );
+
+    srcId_cb = srcId;
+    if (ati_user_output_cfg[srcId].cscsChset EQ CSCS_CHSET_Ucs2 )
+    {
+      utl_smDtaFromTe ((UBYTE*)cl,
+                       (USHORT)MINIMUM(strlen(cl),sizeof(msg.data)*4),
+                       msg.data,
+                       &lenMsg,
+                       (UBYTE)fo,
+                       (UBYTE)dcs );
+    }
+    else if (ati_user_output_cfg[srcId].cscsChset EQ CSCS_CHSET_Hex )
+    {
+      utl_smDtaFromTe ((UBYTE*)cl,
+                       (USHORT)MINIMUM(strlen(cl),sizeof(msg.data)*2),
+                       msg.data,
+                       &lenMsg,
+                       (UBYTE)fo,
+                       (UBYTE)dcs );
+    }
+    else
+    {
+      utl_smDtaFromTe ((UBYTE*)cl,
+                       (USHORT)MINIMUM(strlen(cl),sizeof(msg.data)),
+                       msg.data,
+                       &lenMsg,
+                       (UBYTE)fo,
+                       (UBYTE)dcs );
+    }
+    msg.len = (UBYTE)lenMsg;
+
+#if 0  /* #ifdef FF_ATI_BAT */
+
+    {
+      T_BAT_cmd_send cmd;
+      T_BAT_cmd_set_plus_cmgs cmgs;
+      UBYTE len;
+      UBYTE i;
+      U8 *p;
+      CHAR clean_da[MAX_SMS_NUM_LEN+1];
+
+      cmd.ctrl_params=BAT_CMD_SET_PLUS_CMGS;
+      cmd.params.ptr_set_plus_cmgs=&cmgs;
+
+      /*
+      *   The BAT uses only PDU format, so we must convert the data.
+      *   This code is sufficient to allow tests ACIPHB75-78 to pass - at
+      *   the time of writing, these are the only tests we have available
+      *   for +CMGS. When it comes to other tests, some enhancements will
+      *   certainly be required.
+      */
+
+      p=cmgs.pdu;
+
+      /*
+      *   SCA - Service Centre Address
+      */
+      len=(UBYTE)strlen(sca);
+
+      if (len==0)
+      {
+        /*
+        *   No service centre address indicated. If we use a zero length
+        *   to indicate the default SCA, we will have problems later in
+        *   DecodeRPAddress(). The version below seems to be fine.
+        */
+        *p++=0x01;
+        *p++=0x80;        
+      }
+      else
+      {
+        /*
+        *   The length is the number of octets in the parameter, not
+        *   the number of address digits.
+        */
+        *p++=(U8)((len+1)/2)+1;
+
+        /*
+        *   Type of number.
+        */
+        *p++=(tosca.ton==TON_International) ? 0x91:0x81;
+
+        /*
+        *   Convert the address from string format to BCD format.
+        */
+        for (i=0;i<len;i+=2)
+          *p++=str_to_bcd(&sca[i]);
+      }
+
+      /*
+      *   PDU type
+      */
+      *p++=0x01;
+
+      /*
+      *   MR - Message reference
+      */
+      *p++=0x00;
+
+      /*
+      *   DA - Destination Address
+      *   The length is the number of address digits, not the number of
+      *   octets in the parameter.
+      */
+
+      /*
+      *   First, make a clean version of the string, getting rid of
+      *   any unwanted characters.
+      */
+      {
+        SHORT cctr,dctr;
+        CHAR c;
+
+        memset(clean_da,0,sizeof(clean_da));
+
+        cctr=0;
+
+        for (dctr=0;dctr<MAX_SMS_NUM_LEN;dctr++)
+        {
+          c=da[dctr];
+
+          if ((c>='0') && (c<='9'))
+            clean_da[cctr++]=c;
+        }
+      }
+      
+      len=(UBYTE)strlen(clean_da);
+
+      *p++=(U8)len;
+
+      /*
+      *   Type of number.
+      */
+      *p++=(toda.ton==TON_International) ? 0x91:0x81;
+
+      /*
+      *   Convert the address from string format to BCD format.
+      */
+      for (i=0;i<len;i+=2)
+        *p++=str_to_bcd(&clean_da[i]);
+
+      /*
+      *   PID - Protocol Identifier
+      */
+      *p++=(U8)pid;
+
+      /*
+      *   DCS - Data Coding Scheme
+      */
+      *p++=(U8)dcs;
+
+      /*
+      *   VP - Validity Period
+      *   Not included here.
+      */
+
+      /*
+      *   UDL - User Data Length
+      */
+      *p++=0x00;
+
+      /*
+      *   UD - User Data
+      *   Not included here.
+      */
+      
+      /*
+      *   Length calculated by seeing how far the pointer has come
+      *   from where it started.
+      */
+      cmgs.c_pdu=(U8)(p-cmgs.pdu);
+
+      bat_send(ati_bat_get_client(srcId), &cmd);
+    }
+
+#else
+
+#ifndef _CONC_TESTING_
+#ifndef _SIMULATION_
+    ret = sAT_PlusCMGS_Gl(srcId, da, p_toda, &msg, NULL, NULL, NULL, -1, NULL, NULL);
+#else
+    ret = sAT_PlusCMGS_Gl(srcId, da, p_toda, &msg, NULL, sca, p_tosca, isReply, NULL, NULL);
+#endif
+#else
+    ACI_MALLOC(msg_conc.data, msg.len);
+    memcpy ( msg_conc.data, msg.data, msg.len);
+    msg_conc.len = msg.len;
+#ifndef _SIMULATION_
+    ret = sAT_PlusCMGS (srcId, da, p_toda, &msg_conc, NULL, NULL, -1);
+#else
+    ret = sAT_PlusCMGS (srcId, da, p_toda, &msg_conc, sca, p_tosca, isReply);
+#endif
+#endif
+
+    if ( ret NEQ AT_EXCT )
+    {
+      cmdCmsError (CMS_ERR_NotPresent);  // use aciErrDesc
+      return (ATI_FAIL);
+    }
+    /*
+     *  rCI_OK will emitting +CMGS: <mr>[,<scts>]
+     */
+#endif
+
+    return (ATI_EXCT);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMSS         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMSS command (send message from storage)
+*/
+
+GLOBAL T_ATI_RSLT atPlusCMSS (char *cl, UBYTE srcId)
+{
+  CHAR         *me="+CMSS: ",
+               *p_da;
+  T_ACI_RETURN  ret = AT_FAIL;
+  T_ACI_TOA     toda;
+  T_ACI_TOA    *p_toda;
+  SHORT         index=-1,
+                toda_val=0;
+  CHAR          da[MAX_SMS_NUM_LEN];
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCMSS()");
+
+  p_toda=&toda;
+  p_da=da;
+  /*input functionality*/
+  da[0]='\0';
+  cl = parse(cl,"rsr",&index,(LONG)MAX_SMS_NUM_LEN,da,&toda_val);
+  if ( !cl OR toda_val > 0xC9 OR index > 255 OR index < 0)
+  {
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return (ATI_FAIL);
+  }
+  p_toda=&toda;
+  if(toda_val EQ 0)
+  {
+    p_toda=NULL;
+  }
+  else
+  {
+    toda=toa_demerge(toda_val);
+    if (toda.ton < 0 OR toda.npi < 0)
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+  }
+  if(!da[0])
+    p_da=NULL;
+
+#ifdef _CONC_TESTING_
+  ret = sAT_PlusCMSS(srcId,(UBYTE)index,p_da,p_toda);
+#else
+  ret = sAT_PlusCMSS_Gl(srcId, (UBYTE)index, p_da, p_toda, NULL, NULL);
+#endif
+  if (ret EQ AT_EXCT)
+  {
+    src_params->curAtCmd    = AT_CMD_CMSS;
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCNMA         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CNMA command (new message acknowledgement)
+*/
+GLOBAL T_ATI_RSLT queatPlusCNMA (char *cl, UBYTE srcId)
+{
+  cmdCmsError(CMS_ERR_OpNotAllowed); /* querying CNMA not specified in 07.05 */
+  return (ATI_FAIL);
+}
+
+GLOBAL T_ATI_RSLT tesatPlusCNMA (char *cl, UBYTE srcId)
+{
+  T_ACI_CMGF_MOD mode;
+
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+  {
+    /*
+     * handle PDU mode: response is +CNMA: (list of supported <n>s)
+     */
+    io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+    return ATI_CMPL_NO_OUTPUT;
+  }
+  else
+  {
+    /*
+     * handle Text mode: there is no response
+     */
+    io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+    return ATI_CMPL_NO_OUTPUT;
+  }
+}
+
+
+GLOBAL T_ATI_RSLT atPlusCNMA (char *cl, UBYTE srcId)
+#if defined (SMS_PDU_SUPPORT)
+{
+  T_ACI_CMGF_MOD         mode;
+  T_CNMI_BUFFER_ELEMENT *psMsgInCnmiBuffer = NULL;
+
+  if(srcId NEQ smsShrdPrm.smsSrcId)
+  {
+    cmdCmsError(CMS_ERR_NoCnmaAckExpect);
+    return ( ATI_FAIL );
+  }
+  
+  if( waitForCnmaFromBuffer_SrcId NEQ CMD_SRC_NONE )
+  { /* incomming +CNMA acknowledges an +CMT from CNMI buffer 
+       -> acknowledge has been sent to SMS entity */
+    TIMERSTOP( ACI_CNMA_TIMER_HANDLE );
+    cmd_clearFirstCnmiMessage(); /* The first message in CNMI buffer is cleared */
+    waitForCnmaFromBuffer_SrcId = CMD_SRC_NONE;
+    /* look for more messages in CNMI buffer for this srcId */
+    cmd_flushCnmiBufOneByOne();
+    return(ATI_CMPL);
+  }
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+    /*
+     * handle PDU mode
+     */
+    return atPlusCNMAPdu (cl,srcId);
+  else
+    /*
+     * handle Text mode
+     */
+    return atPlusCNMAText (cl,srcId);
+}
+
+LOCAL T_ATI_RSLT atPlusCNMAText (char *cl, UBYTE srcId)
+#endif /* (SMS_PDU_SUPPORT) */
+{
+  TRACE_FUNCTION("atPlusCNMAText()");
+
+  switch (*cl)
+  {
+    case(0x0):
+      switch (sAT_PlusCNMA(srcId))
+      {
+        case( AT_CMPL ):
+          cmdAtError ( atOk );
+          return (ATI_CMPL);
+
+        default:
+          cmdCmsError (CMS_ERR_NotPresent);  // use aciErrDesc
+          return (ATI_FAIL);
+      }
+    default:
+      cmdCmeError(CME_ERR_Unknown);
+      return (ATI_FAIL);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGW         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGW command (Write message to memory)
+*/
+
+GLOBAL T_ATI_RSLT tesatPlusCMGW (char *cl, UBYTE srcId)
+{
+  io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+  return ATI_CMPL_NO_OUTPUT;
+}
+
+GLOBAL T_ATI_RSLT queatPlusCMGW (char *cl, UBYTE srcId)
+{
+  cmdCmsError(CMS_ERR_OpNotAllowed); /* querying CMGW not specified in 07.05 */
+  return (ATI_FAIL);
+}
+
+
+GLOBAL T_ATI_RSLT atPlusCMGW (char *cl, UBYTE srcId)
+#if defined (SMS_PDU_SUPPORT)
+{
+  T_ACI_CMGF_MOD mode;
+
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+    /*
+     * handle PDU mode
+     */
+    return atPlusCMGWPdu (cl, srcId);
+  else
+    /*
+     * handle Text mode
+     */
+    return atPlusCMGWText (cl, srcId);
+}
+LOCAL T_ATI_RSLT atPlusCMGWText(char *cl, UBYTE srcId)
+#endif /* (SMS_PDU_SUPPORT) */
+{
+  T_ACI_VP_ABS  vpabs;
+  SHORT         fo,
+                vprel,
+                pid,
+                dcs;
+  CHAR*         me = "+CMGW: ";
+  T_ACI_RETURN  ret;
+  T_ACI_TOA     toa;
+  T_ACI_TOA*    p_toa;
+  CHAR          txtStat[15] = {0x00};
+  USHORT        i;
+  T_ACI_SM_DATA msg;
+  USHORT        lenMsg;
+  static T_ACI_SMS_STAT stat;
+
+  static T_ACI_TOA     tosca;
+  static T_ACI_TOA    *p_tosca;
+#ifdef _SIMULATION_
+  CHAR         *sca =subBuf;
+#endif /* ndef _SIMULATION_ */
+  SHORT         octet=0;
+  static SHORT         isReply;
+#ifdef _CONC_TESTING_
+  T_SM_DATA_EXT msg_conc;
+#endif
+  CHAR         *da = daBuf;
+
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCMGWText()");
+
+  p_toa=&toa;
+  toda_val=0;
+
+  if (src_params->text_mode EQ CMD_MODE)
+  {
+    memset(da, 0, MAX_SMS_NUM_LEN);
+    stat = SMS_STAT_NotPresent;
+    /*input functionality*/
+    *da='\0';                      /*sets global destination address to empty string*/
+#ifndef WIN32
+    cl = parse(cl,"srs",(LONG)MAX_SMS_NUM_LEN,
+                        da,
+                        &toda_val,
+                        (LONG)sizeof(txtStat),
+                        txtStat);
+    if ( !cl )
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+#else
+    *sca='\0';
+    isReply = -1;
+    cl = parse(cl,"srssrb",(LONG)MAX_SMS_NUM_LEN,
+                       da,
+                       &toda_val,
+                       (LONG)sizeof(txtStat),
+                       txtStat,
+                       (LONG)MAX_SMS_NUM_LEN,sca,&octet,&isReply);
+    if ( !cl )
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+    if(octet EQ 0)
+      p_tosca = NULL;
+    else
+    {
+      tosca=toa_demerge(octet);
+      if (tosca.ton < 0 OR tosca.npi < 0)
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return 0;
+      }
+      p_tosca = &tosca;
+    }
+#endif
+    if (toda_val)
+    {
+      toa = toa_demerge(toda_val);
+      if (toa.ton < 0 OR toa.npi < 0)
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+    }
+    i = 0;
+    while ( sms_stat[i].name                     NEQ NULL AND
+            strcmp ( sms_stat[i].name, txtStat ) NEQ 0        )
+    {
+      i++;
+    }
+    stat = sms_stat[i].stat;
+
+    src_params->text_mode = TXT_MODE;
+    return (ATI_EXCT);
+  } /* end of if (src_params->text_mode EQ CMD_MODE) */
+  else
+  {
+    src_params->text_mode = CMD_MODE;
+    /* if the character sent is ESC, then abort command CLB 16.11.00 */
+    if (*cl EQ 0x1B)
+    {
+      TRACE_EVENT("Send message command cancelled by user");
+
+      return ATI_CMPL_NO_OUTPUT;
+    }
+
+    if ( toda_val EQ 0 )
+      p_toa = NULL;
+    else
+    {
+      toa   = toa_demerge ( toda_val );
+      p_toa = &toa;
+    }
+
+    qAT_PlusCSMP  ( srcId, &fo, &vprel, &vpabs, NULL, &pid, &dcs );
+
+    srcId_cb = srcId;
+    utl_smDtaFromTe ( (UBYTE*)cl,
+                      (USHORT)strlen(cl),
+                      (UBYTE*)msg.data,
+                      &lenMsg,
+                      (UBYTE)fo,
+                      (UBYTE)dcs );
+
+    msg.len = (UBYTE)lenMsg;
+
+#ifndef _CONC_TESTING_
+#ifndef _SIMULATION_
+    ret = sAT_PlusCMGW_Gl( srcId,
+                           CMGW_IDX_FREE_ENTRY,
+                           da, p_toa, stat, NOT_PRESENT_8BIT,
+                           &msg, NULL, NULL, NULL, -1,
+                           NULL, NULL);
+#else
+    ret = sAT_PlusCMGW_Gl( srcId,
+                           CMGW_IDX_FREE_ENTRY,
+                           da, p_toa, stat, NOT_PRESENT_8BIT,
+                           &msg, NULL, sca, p_tosca, isReply,
+                           NULL, NULL);
+#endif
+#else
+    ACI_MALLOC(msg_conc.data, msg.len);
+    memcpy ( msg_conc.data, msg.data, msg.len);
+    msg_conc.len = msg.len;
+#ifndef _SIMULATION_
+    ret = sAT_PlusCMGW ( srcId,
+                         CMGW_IDX_FREE_ENTRY,
+                         da, p_toa, stat, NOT_PRESENT_8BIT,
+                         &msg_conc, NULL, NULL, -1 );
+#else
+    ret = sAT_PlusCMGW ( srcId,
+                         CMGW_IDX_FREE_ENTRY,
+                         da, p_toa, stat, NOT_PRESENT_8BIT,
+                         &msg_conc, sca, p_tosca, isReply );
+#endif
+#endif
+
+    if ( ret NEQ AT_EXCT )
+    {
+      cmdCmsError (CMS_ERR_NotPresent);  // use aciErrDesc
+      return (ATI_FAIL);
+    }
+    /*
+     *  rCI_OK will emitting +CMGW: <index>
+     */
+    return (ATI_EXCT);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGD         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGD command (delete message from storage)
+*/
+
+GLOBAL T_ATI_RSLT setatPlusCMGD (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = ATI_FAIL;
+  SHORT index=-1;
+  UBYTE status = CMGD_DEL_INDEX;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  src_params->curAtCmd = AT_CMD_CMGD;
+
+  /*input functionality*/
+  if(!cl OR !*cl)
+  {
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return ret;
+  }
+
+  cl=parse(cl,"rr",&index,&status);
+  if ( !cl OR (index > 255) OR (index < 0) OR
+    ((status < CMGD_DEL_INDEX) OR (status > CMGD_DEL_ALL)))
+  {
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return ret;
+  }
+
+#ifdef FF_ATI_BAT
+  {
+  T_BAT_cmd_send cmd;
+  T_BAT_cmd_set_plus_cmgd my_bat_set_plus_cmgd;
+
+  TRACE_FUNCTION("setatPlusCMGD() calls bat_send() <=== as APPLICATION");
+
+  memset(&my_bat_set_plus_cmgd, 0, sizeof(my_bat_set_plus_cmgd));
+  cmd.ctrl_params = BAT_CMD_SET_PLUS_CMGD;
+  cmd.params.ptr_set_plus_cmgd = &my_bat_set_plus_cmgd;
+
+  my_bat_set_plus_cmgd.index = (U8)index;
+  my_bat_set_plus_cmgd.status = status;
+
+  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("setatPlusCMGD()");
+  /*-----------------------------------------------------------------------
+   *  Del flag is greater than zero, set index as Zero so that SMS module 
+   *  starts searching for records satisfying the status from first record
+   *-----------------------------------------------------------------------
+   */
+  if ( status > CMGD_DEL_INDEX )
+  {
+    index = 0;
+  }
+#ifdef _CONC_TESTING_
+  ret = sAT_PlusCMGD(srcId,(UBYTE)index, status);
+#else
+  ret = sAT_PlusCMGD_Gl(srcId, (UBYTE)index, status, NULL, NULL);
+#endif
+
+  if (ret EQ AT_EXCT)
+  {
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+
+#endif /* no FF_ATI_BAT*/
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGC         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGC command (Send SMS command)
+*/
+
+GLOBAL T_ATI_RSLT tesatPlusCMGC (char *cl, UBYTE srcId)
+{
+  io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+  return ATI_CMPL_NO_OUTPUT;
+}
+
+GLOBAL T_ATI_RSLT queatPlusCMGC (char *cl, UBYTE srcId)
+{
+  cmdCmsError(CMS_ERR_OpNotAllowed); /* querying CMGC not specified in 07.05 */
+  return (ATI_FAIL);
+}
+
+GLOBAL T_ATI_RSLT atPlusCMGC (char *cl, UBYTE srcId)
+#if defined (SMS_PDU_SUPPORT)
+{
+  T_ACI_CMGF_MOD mode;
+
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+    /*
+     * handle PDU mode
+     */
+    return atPlusCMGCPdu (cl, srcId);
+  else
+    /*
+     * handle Text mode
+     */
+    return atPlusCMGCText (cl, srcId);
+}
+
+LOCAL T_ATI_RSLT atPlusCMGCText(char *cl, UBYTE srcId)
+#endif /* (SMS_PDU_SUPPORT) */
+{
+/*  char           buf[80]; */
+  T_ACI_RETURN   ret = AT_FAIL;
+  T_ACI_TOA      toa;
+  T_ACI_TOA*     p_toa;
+  T_ACI_CMD_DATA cmd;
+  USHORT         lenCmd;
+  CHAR*          da = daBuf;
+
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("atPlusCMGCText()");
+  p_toa=&toa;
+  if (src_params->text_mode EQ CMD_MODE)
+  {
+    memset(da, 0, MAX_SMS_NUM_LEN);
+    fo=-1;
+    ct=-1;
+    pid=-1;
+    mn=-1;
+    toda_val=0;
+    /*input functionality*/
+    da[0]='\0';
+    cl = parse(cl,"rrrrsr",&fo,&ct,&pid,&mn,(LONG)MAX_SMS_NUM_LEN,da,&toda_val);
+
+    if ( !cl OR  fo > 255 OR ct > 255 OR
+          pid > 255 OR mn > 255 OR toda_val > 0xC9 OR da[0] EQ '\0')
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+    if(toda_val)
+    {
+      toa = toa_demerge(toda_val);
+      if (toa.ton < 0 OR toa.npi < 0)
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+    }
+
+    src_params->text_mode = TXT_MODE;
+    return (ATI_EXCT);
+  } /* end of if (src_params->text_mode EQ CMD_MODE) */
+  else
+  {
+    src_params->text_mode = CMD_MODE;
+    p_toa=&toa;
+    if(toda_val EQ 0)
+    {
+      p_toa = NULL;
+    }
+    else
+    {
+      toa = toa_demerge(toda_val);
+    }
+    if (!(check_str(cl,"0123456789ABCDEF")))
+    {
+      cmdCmsError(CMS_ERR_OpNotAllowed);
+      return (ATI_FAIL);
+    }
+    utl_hexToGsm ( (UBYTE*)cl,
+                   (USHORT)strlen(cl),
+                   (UBYTE*)cmd.data,
+                   &lenCmd,
+                   GSM_ALPHA_Def,
+                   CSCS_ALPHA_8_Bit);
+    cmd.len = (UBYTE)lenCmd;
+
+#ifndef _CONC_TESTING_
+    ret = sAT_PlusCMGC_Gl (srcId,fo,ct,pid,mn,da,p_toa,&cmd,NULL);
+#else
+    ret= sAT_PlusCMGC(srcId,fo,ct,pid,mn,da,p_toa,&cmd);
+#endif
+
+    if ( ret NEQ AT_EXCT )
+    {
+      cmdCmsError (CMS_ERR_NotPresent);  // use aciErrDesc
+      return (ATI_FAIL);
+    }
+    /*
+     *  rCI_OK will emitting +CMGC: <mr>[,<scts>]
+     */
+    return (ATI_EXCT);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCMGL         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMGL command (List Messages)
+*/
+
+GLOBAL T_ATI_RSLT queatPlusCMGL (char *cl, UBYTE srcId)
+{
+  TRACE_FUNCTION("queatPlusCMGL()");
+    cmdCmsError ( CMS_ERR_OpNotAllowed );
+    return (ATI_FAIL);
+}
+
+GLOBAL T_ATI_RSLT tesatPlusCMGL (char *cl, UBYTE srcId)
+{
+#ifdef SMS_PDU_SUPPORT
+  T_ACI_CMGF_MOD mode;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("tesatPlusCMGL()");
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+  /*
+   * handle PDU mode
+   */
+    io_sendMessage(srcId, "+CMGL: (0,1,2,3,4)", ATI_NORMAL_OUTPUT);
+  else
+  /*
+   * handle Text mode
+   */
+#endif
+   io_sendMessage(srcId, "+CMGL: (\"REC UNREAD\",\"REC READ\",\"STO UNSENT\",\"STO SENT\",\"ALL\")", ATI_NORMAL_OUTPUT);
+
+  return (ATI_CMPL);
+}
+
+GLOBAL T_ATI_RSLT atPlusCMGL (char *cl, UBYTE srcId)
+{
+#ifndef FF_ATI_BAT
+  T_ACI_RETURN   ret;
+#endif
+
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+#ifdef SMS_PDU_SUPPORT
+  T_ACI_CMGF_MOD mode;
+#endif
+  CHAR           txtStat[15];
+  USHORT         i;
+
+  TRACE_FUNCTION("atPlusCMGL()");
+
+
+  if (*cl EQ '\0')
+  {
+    cmglStat = SMS_STAT_NotPresent;
+#ifdef WIN32
+    smsReadMode  = SMS_READ_Normal;
+#endif
+  }
+  else
+  {
+    /*
+     * Request of a list of stored SMS messages
+     * Parameter stat is optional
+     */
+#ifdef SMS_PDU_SUPPORT
+    /*
+     * request current mode
+     */
+    qAT_PlusCMGF(srcId, &mode);
+    if (mode EQ 0)
+    {
+#ifndef WIN32
+      /*
+       * On the target is the definition according GSM 7.05 CMGL=[stat]
+       */
+      cmglStat = SMS_STAT_All;
+      cl = parse (cl, "d", &cmglStat);
+      if ( !cl OR cmglStat < SMS_STAT_RecUnread OR cmglStat > SMS_STAT_All)
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return NULL;
+      }
+#else
+      /*
+       * Under Windows the definition is CMGL=[stat],[preview]
+       * to test the capabilities of the functional interface
+       */
+      cl = parse (cl, "dd", &cmglStat, &smsReadMode );
+      if ( !cl OR ((cmglStat < SMS_STAT_RecUnread OR cmglStat > SMS_STAT_All)
+           AND smsReadMode  EQ SMS_READ_NotPresent))
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+#endif
+    }
+    else
+#endif
+    {
+#ifndef WIN32
+      /*
+       * On the target is the definition according GSM 7.05 CMGL=[stat]
+       */
+      cl = parse (cl, "s", (LONG)sizeof(txtStat), txtStat);
+      if ( !cl OR txtStat[0] EQ '\0')
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+#else
+      /*
+       * Under Windows the definition is CMGL=[stat],[preview]
+       * to test the capabilities of the functional interface
+       */
+      cl = parse (cl, "sd", (LONG)sizeof(txtStat), txtStat, &smsReadMode );
+      if ( !cl OR (txtStat[0] EQ '\0' AND smsReadMode  EQ SMS_READ_NotPresent))
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+      if (txtStat[0] EQ '\0')
+        strcpy (txtStat, sms_stat[4].name); /* ALL as default */
+#endif
+      i = 0;
+      while ( sms_stat[i].name NEQ NULL            AND
+              strcmp ( sms_stat[i].name, txtStat ) NEQ 0 )
+        i++;
+
+      if ( sms_stat[i].name EQ NULL )
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+
+      cmglStat = sms_stat[i].stat;
+    }
+  }
+
+#ifdef FF_ATI_BAT
+
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_plus_cmgl cmgl;
+
+    cmd.ctrl_params=BAT_CMD_SET_PLUS_CMGL;
+    cmd.params.ptr_set_plus_cmgl=&cmgl;
+
+    /*
+    *   T_ACI_SMS_STAT and T_BAT_plus_cmgl_stat are not quite
+    *   identical - the ACI version has the extra value
+    *   SMS_STAT_Invalid.
+    */
+    if (cmglStat EQ SMS_STAT_Invalid)
+      cmgl.stat=BAT_CMGL_STAT_NOT_PRESENT;
+    else
+      cmgl.stat=(T_BAT_plus_cmgl_stat)cmglStat;
+
+    bat_send(ati_bat_get_client(srcId),&cmd);
+
+    src_params->curAtCmd=AT_CMD_CMGL;
+    return(ATI_EXCT);
+  }
+
+#else
+
+  /*
+   * Request the first five SMS messages
+   */
+#ifndef WIN32
+  ret = sAT_PlusCMGL ( srcId, cmglStat, 0, SMS_READ_Normal );
+#else
+  ret = sAT_PlusCMGL ( srcId, cmglStat, 0, smsReadMode  );
+#endif
+
+  if ( ret EQ AT_EXCT )
+  {
+    src_params->curAtCmd = AT_CMD_CMGL;
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError ( CMS_ERR_NotPresent );  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+
+#endif /*FF_ATI_BAT*/
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPlusCNMI         |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CNMI command (new messgae indication settings )
+*/
+
+GLOBAL T_ATI_RSLT  atPlusCNMI (char *cl, UBYTE srcId)
+{
+  T_ACI_CNMI_MT  mt   = CNMI_MT_NotPresent;
+  T_ACI_CNMI_BM  bm   = CNMI_BM_NotPresent;
+  T_ACI_CNMI_DS  ds   = CNMI_DS_NotPresent;
+  T_ACI_CNMI_MOD mode = CNMI_MOD_NotPresent;
+  T_ACI_CNMI_BFR bfr  = CNMI_BFR_NotPresent;
+  T_ACI_RETURN   ret  = AT_FAIL;
+
+  TRACE_FUNCTION("atPlusCNMI()");
+
+  /* input functionality */
+  cl = parse ( cl, "ddddd", &mode, &mt, &bm, &ds, &bfr );
+
+  if ( !cl                              OR
+        mode <  CNMI_MOD_NotPresent     OR
+        mode >  CNMI_MOD_BufferAndFlush OR
+        bfr  <  CNMI_BFR_NotPresent     OR
+        bfr  >  CNMI_BFR_Clear          OR
+      ( bfr  EQ CNMI_BFR_Flush          AND
+        strlen ( cl ) > 0                   ) )
+  {
+      io_sendConfirm ( srcId, cmdCmsError ( CMS_ERR_OpNotAllowed ), ATI_ERROR_OUTPUT );
+      cmdErrStr = NULL;
+      return ATI_FAIL_NO_OUTPUT;
+  }
+
+  ret = sAT_PlusCNMI ( srcId, mt, bm, ds );
+  if ( (ret EQ AT_FAIL) OR (ret EQ AT_BUSY) )
+  {
+    io_sendConfirm ( srcId, cmdCmsError ( CMS_ERR_NotPresent ), ATI_ERROR_OUTPUT );
+    cmdErrStr = NULL;
+    return ATI_FAIL_NO_OUTPUT;
+  }
+
+  /* 
+   *----------------------Issue 25033--------------------------------
+   * The source ID issuing the CNMI command is stored and henceforth 
+   * all the unsolicited SMS indications are sent to this source 
+   *-----------------------------------------------------------------
+   */
+  if(srcId NEQ CMD_SRC_LCL)
+	  smsShrdPrm.smsSrcId = srcId;
+
+  if ( bfr  NEQ CNMI_BFR_NotPresent )
+    at.CNMI_bfr  = ( UBYTE ) bfr;
+
+  if ( mode NEQ CNMI_MOD_NotPresent )
+    at.CNMI_mode = ( UBYTE ) mode;
+
+  if (mode EQ CNMI_MOD_DiscardOrForward OR  /* 07.05:3.4.1: check for <mode> 1...3  */
+      mode EQ CNMI_MOD_BufferAndFlush)
+  {
+    if ( at.CNMI_bfr EQ CNMI_BFR_Flush )
+    {
+      io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+      cmdErrStr = NULL;
+
+      if( smsShrdPrm.CSMSservice NEQ CSMS_SERV_GsmPh2Plus )
+      {
+        cmd_flushCnmiBuf();
+      }
+      else
+      {
+        cmd_flushCnmiBufOneByOne();
+      }
+      return ATI_CMPL_NO_OUTPUT;
+    }
+    else
+    {
+      cmd_clearCnmiBuf ();
+    }
+  }
+
+  io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+  cmdErrStr = NULL;
+
+  return ATI_CMPL_NO_OUTPUT;
+}
+
+GLOBAL T_ATI_RSLT  tesatPlusCNMI (char *cl, UBYTE srcId)
+{
+  /* query parameter ranges */
+  io_sendMessage ( srcId, "+CNMI: (0-2),(0-3),(0,2),(0,1),(0,1)", ATI_NORMAL_OUTPUT );
+  io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+  cmdErrStr = NULL;
+
+  return ATI_CMPL_NO_OUTPUT;
+}
+
+GLOBAL T_ATI_RSLT  queatPlusCNMI (char *cl, UBYTE srcId)
+{
+  char*          me   = "+CNMI: ";
+  T_ACI_CNMI_MT  mt   = CNMI_MT_NotPresent;
+  T_ACI_CNMI_BM  bm   = CNMI_BM_NotPresent;
+  T_ACI_CNMI_DS  ds   = CNMI_DS_NotPresent;
+  T_ACI_CNMI_MOD mode = CNMI_MOD_NotPresent;
+  T_ACI_CNMI_BFR bfr  = CNMI_BFR_NotPresent;
+
+  if ( qAT_PlusCNMI ( srcId, &mt, &bm, &ds ) EQ AT_CMPL )
+  {
+    sprintf ( g_sa,"%s%d,%d,%d,%d,%d", me, at.CNMI_mode,
+                                     mt, bm, ds, at.CNMI_bfr );
+    io_sendMessage ( srcId, g_sa, ATI_NORMAL_OUTPUT );
+  }
+  else
+  {
+    io_sendConfirm ( srcId, cmdCmsError ( CMS_ERR_NotPresent ), ATI_ERROR_OUTPUT );
+    cmdErrStr = NULL;
+    return ATI_FAIL_NO_OUTPUT;
+  }
+
+  io_sendConfirm ( srcId, cmdAtError ( atOk ), ATI_NORMAL_OUTPUT );
+  cmdErrStr = NULL;
+  return ATI_CMPL_NO_OUTPUT;
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : setatPercentCPRSM  |
++--------------------------------------------------------------------+
+
+  PURPOSE : %CPRSM set command 
+            set the receiving of SMS to 
+            1 -- Pause    or  
+            2 -- Resume
+           
+*/
+
+GLOBAL T_ATI_RSLT setatPercentCPRSM (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret     = AT_FAIL;
+  T_ACI_CPRSM_MOD mode = CPRSM_MOD_NotPresent;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  src_params->curAtCmd = AT_CMD_CPRSM;
+  
+  /* parse command */
+  cl = parse (cl, "d", &mode);
+
+  /* check whether parsing has been successful */ 
+  if (!cl)
+  {
+    /* undefined value for mode */
+    TRACE_EVENT("+CPRSM ERROR: parse cmd failed!");
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return ATI_FAIL;    
+  }
+
+#ifdef FF_ATI_BAT
+  {
+  T_BAT_cmd_send cmd;
+  T_BAT_cmd_set_percent_cprsm my_bat_set_percent_cprsm;
+
+  TRACE_FUNCTION("setatPercentCPRSM() calls bat_send() <=== as APPLICATION");
+
+  memset(&my_bat_set_percent_cprsm, 0, sizeof(my_bat_set_percent_cprsm));
+  cmd.ctrl_params = BAT_CMD_SET_PERCENT_CPRSM;
+  cmd.params.ptr_set_percent_cprsm = &my_bat_set_percent_cprsm;
+
+  my_bat_set_percent_cprsm.mode = mode;
+
+  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("setatPercentCPRSM()");
+
+  switch (mode) /* check which mode has to be set and set it */ 
+  {
+    case(CPRSM_MOD_Resume):
+    case(CPRSM_MOD_Pause):
+    {     
+      /* AT interface function called */
+      ret = sAT_PercentCPRSM(srcId, mode);
+      break;
+    }
+    default:
+      /* undefined value for mode */
+      TRACE_EVENT_P1("+CPRSM ERROR: undefined value for mode: %d", mode);
+      cmdCmsError(CMS_ERR_OpNotSup);
+      return ATI_FAIL;
+  }
+
+  /* check result */
+  switch (ret)
+  {
+    case (AT_CMPL):
+      /* operation successfully completed */
+      break;
+    case (AT_EXCT):
+      /* operation still executing */
+      src_params->curAtCmd = AT_CMD_COPS;
+      break;
+    default:
+      /* unknown result type */
+      TRACE_EVENT_P1("+CPRSM ERROR: undefined result: %d", ret);
+      cmdCmsError(CMS_ERR_UnknownErr);  /*Command failed*/
+      return ATI_FAIL;
+  }
+
+  /* map error to ATI type and return */ 
+  return (map_aci_2_ati_rslt(ret)); 
+
+#endif /* no FF_ATI_BAT*/
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : queatPercentCPRSM  |
++--------------------------------------------------------------------+
+
+  PURPOSE : %CPRSM query command 
+            request the current state of the pause flag for receiving SMS
+*/
+
+GLOBAL T_ATI_RSLT queatPercentCPRSM (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = ATI_FAIL;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("queatPercentCPRSM()");
+
+  ret = qAT_PercentCPRSM( srcId );
+
+
+  if (ret EQ AT_EXCT)
+  {
+    src_params->curAtCmd = AT_CMD_CPRSM;
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+    return (ATI_FAIL);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : cmd_clearCnmiBuf   |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function clears the buffer for storing new message
+            indications while the serial interface is reserved for
+            data transmission.
+*/
+GLOBAL void cmd_clearCnmiBuf (void)
+{
+  UBYTE i;
+
+  for ( i = 0; i < CNMI_BUF_SIZE; i++ )
+    cnmiBuf.sCnmiElement[i].type = CNMI_NONE;
+
+  cnmiBuf.next = 0;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : cmd_flushCnmiBuf   |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function flushes the buffer for storing new message
+            indications while the serial interface is released from
+            data transmission.
+*/
+GLOBAL void cmd_flushCnmiBuf (void)
+{
+  UBYTE i            = cnmiBuf.next;
+  UBYTE entries_read = 0;
+
+  TRACE_FUNCTION("cmd_flushCnmiBuf");
+
+  if ( cnmiBuf.sCnmiElement[0].type EQ CNMI_NONE )
+  {
+    entries_read = CNMI_BUF_SIZE; /* no need to read anything at all */
+    //moreEntries = FALSE;
+  }
+  else if ( cnmiBuf.next                            EQ CNMI_BUF_SIZE OR
+            cnmiBuf.sCnmiElement[cnmiBuf.next].type EQ CNMI_NONE )
+  {
+    i = 0;
+  }
+
+  cnmiFlushInProgress = TRUE;
+
+  while ( entries_read < CNMI_BUF_SIZE /*moreEntries*/ )
+  {
+    if (smsShrdPrm.pDecMsg)
+    { /* clear p_sm buffer */
+      ACI_MFREE(smsShrdPrm.pDecMsg);
+      smsShrdPrm.pDecMsg = NULL;
+    }
+
+    switch ( cnmiBuf.sCnmiElement[i].type )
+    {
+      
+      case ( CNMI_CMT ):
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCMT ( &cnmiBuf.sCnmiElement[i].indct.cmt );
+        break;
+
+      case ( CNMI_CMTI ):
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCMTI ( cnmiBuf.sCnmiElement[i].indct.cmti.mem,
+                       cnmiBuf.sCnmiElement[i].indct.cmti.index );
+        break;
+
+      case ( CNMI_CBM ):
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCBM (  &cnmiBuf.sCnmiElement[i].indct.cbm );
+        break;
+
+      case ( CNMI_CDS ):
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCDS (  &cnmiBuf.sCnmiElement[i].indct.cds );
+        break;
+
+      default:
+//      moreEntries = FALSE;
+        break;
+    }
+
+    cnmiBuf.sCnmiElement[i].type = CNMI_NONE;
+    i++;
+    entries_read++;
+
+    if ( i EQ CNMI_BUF_SIZE )
+      i = 0;
+  }
+
+  cnmiFlushInProgress = FALSE;
+  cnmiBuf.next        = 0;
+}
+
+/*
++--------------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD                  |
+| STATE   : code                        ROUTINE : cmd_flushCnmiBufOneByOne |
++--------------------------------------------------------------------------+
+
+  PURPOSE : This function flushes the CNMI buffer in case of Phase2+ mode,
+            while the serial interface is released from
+            data transmission or an +CNMI <bfr>==Flush is requested.
+*/
+
+GLOBAL void cmd_flushCnmiBufOneByOne(void)
+{ /* flushing +CMT one by one, because acknowledge is necessary */
+  T_CNMI_BUFFER_ELEMENT* psMsgInCnmiBuffer = NULL;
+  UINT16                 uiCnmiMsgCounter  = 0;
+  BOOL                   bEndLoop          = FALSE;
+
+  for( uiCnmiMsgCounter=0;
+       (uiCnmiMsgCounter<cmd_getNumberOfCnmiEntrys()) && 
+       (waitForCnmaFromBuffer_SrcId EQ CMD_SRC_NONE); 
+       uiCnmiMsgCounter++ )
+  { /* there are entrys in the CNMI buffer --> read it */
+    psMsgInCnmiBuffer = cmd_getCnmiMessage(uiCnmiMsgCounter); /* FIFO */
+
+    if( psMsgInCnmiBuffer EQ NULL )
+    {
+      TRACE_EVENT("ati_switch_mode() : Error at CNMI-buffer handling: NULL-pointer access!!");
+      return;
+    }
+    
+    cnmiFlushInProgress = TRUE; /* needed for the rCI_...commands */
+
+    if (smsShrdPrm.pDecMsg)
+    { /* clear p_sm buffer */
+      ACI_MFREE(smsShrdPrm.pDecMsg);
+      smsShrdPrm.pDecMsg = NULL;
+    }
+
+    switch ( psMsgInCnmiBuffer->type )
+    {
+      case ( CNMI_CMTI ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCMTI ( psMsgInCnmiBuffer->indct.cmti.mem, psMsgInCnmiBuffer->indct.cmti.index );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      case ( CNMI_CBM ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCBM (  &psMsgInCnmiBuffer->indct.cbm );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      case ( CNMI_CDS ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCDS (  &psMsgInCnmiBuffer->indct.cds );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      /* special handling for +CMT --> acknowledge needed */
+      case ( CNMI_CMT ) :
+      {
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCMT ( &psMsgInCnmiBuffer->indct.cmt );
+        TIMERSTART(ACI_CNMA_TIMER_VALUE, ACI_CNMA_TIMER_HANDLE);
+        waitForCnmaFromBuffer_SrcId = smsShrdPrm.smsSrcId;
+        break;
+      }
+      default:
+        TRACE_EVENT("ati_switch_mode() : wrong CNMI-buffer handling: wrong Msg. type");
+    }
+  }
+  cnmiFlushInProgress = FALSE;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : cmd_addCnmiNtry    |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function add a new entry to the buffer for storing
+            new message indications while the serial interface is
+            reserved for data transmission.
+*/
+GLOBAL void cmd_addCnmiNtry ( UBYTE type, T_CNMI_IND* newInd )
+{
+  TRACE_FUNCTION("cmd_addCnmiNtry");
+
+  if ( type > CNMI_CDS OR type < CNMI_CMT )
+    return;
+
+  if ( cnmiBuf.next EQ CNMI_BUF_SIZE )
+  {
+    cnmiBuf.next = 0;
+  }
+
+  switch ( type )
+  {
+    case ( CNMI_CMT ):
+      cnmiBuf.sCnmiElement[cnmiBuf.next].indct.cmt  = newInd -> cmt;
+      break;
+
+    case ( CNMI_CMTI ):
+      cnmiBuf.sCnmiElement[cnmiBuf.next].indct.cmti = newInd -> cmti;
+      break;
+
+
+    case ( CNMI_CBM ):
+      cnmiBuf.sCnmiElement[cnmiBuf.next].indct.cbm  = newInd -> cbm;
+      break;
+
+    case ( CNMI_CDS ):
+      cnmiBuf.sCnmiElement[cnmiBuf.next].indct.cds  = newInd -> cds;
+      break;
+  }
+
+  cnmiBuf.sCnmiElement[cnmiBuf.next].type  = type;
+  cnmiBuf.next++;
+}
+
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : getNumberOfCnmiEntrys |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function is the responsible to get the count 
+            of CNMI entrys in the CNMI buffer.
+*/
+GLOBAL UINT16 cmd_getNumberOfCnmiEntrys(void)
+{
+  return cnmiBuf.next;
+}
+
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : getCnmiMessage        |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function is the responsible to get an entire Msg.
+            from the CNMI buffer. That means, this function only returns
+            the pointer to the beginning of the CNMI buffer element.
+            If the buffer is empty or if the uiIndex parameter is bigger
+            than allowed, the return pointer will be NULL.
+*/
+GLOBAL T_CNMI_BUFFER_ELEMENT* cmd_getCnmiMessage(UINT16 uiIndex)
+{
+  T_CNMI_BUFFER_ELEMENT* psCnmiBufferElement = NULL;
+
+  if( (cnmiBuf.next EQ 0) OR
+      (cnmiBuf.sCnmiElement[0].type EQ CNMI_NONE) OR
+      (uiIndex >= CNMI_BUF_SIZE ) )
+  {
+    return NULL;
+  }
+
+  psCnmiBufferElement = &cnmiBuf.sCnmiElement[uiIndex];
+  return psCnmiBufferElement; /* returns the pointer to the element */
+}
+
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : clearFirstCnmiMessage |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function is the responsible to clear an entire Msg.
+            specified by uiIndex from the CNMI buffer.
+            After succesful return, the message was delete from the CNMI
+            buffer and the buffer has been resorted.
+*/
+GLOBAL BOOL cmd_clearCnmiMessage(UINT16 uiIndex)
+{
+  UINT16 uiBufCount;
+
+  if( (cnmiBuf.next EQ 0) OR
+      (cnmiBuf.sCnmiElement[0].type EQ CNMI_NONE))
+  {
+    return FALSE; /* CNMI buffer is empty or flushing is in progress */
+  }
+
+  /* delete first entry while resorting the buffer */
+  for( uiBufCount = uiIndex; uiBufCount<(CNMI_BUF_SIZE-1); uiBufCount++ )
+  {
+    memcpy( &cnmiBuf.sCnmiElement[uiBufCount], &cnmiBuf.sCnmiElement[uiBufCount+1], sizeof(T_CNMI_BUFFER_ELEMENT) );
+  }
+
+  cnmiBuf.next--;
+
+  return TRUE;
+}
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : getCnmiMessage        |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function is the responsible to get the first entire Msg.
+            from the CNMI buffer. That means, this function only returns
+            the pointer to the beginning of the CNMI buffer.
+            If the buffer is empty, the return pointer will be NULL.
+*/
+GLOBAL T_CNMI_BUFFER_ELEMENT* cmd_getFirstCnmiMessage(void)
+{
+  return cmd_getCnmiMessage(0);
+}
+
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : clearFirstCnmiMessage |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function is the responsible to clear the first entire Msg.
+            from the CNMI buffer. After succesful return, the 
+            message was delete from the CNMI buffer.
+*/
+GLOBAL BOOL cmd_clearFirstCnmiMessage(void)
+{
+  return cmd_clearCnmiMessage(0);
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : rCI_IoMode         |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function will be called when IO mode of serial
+            interface has changed.
+*/
+GLOBAL void rCI_IoMode ( void )
+{
+  TRACE_FUNCTION ( "rCI_IoMode (): actually not awaited !!" );
+
+/*  if ( io_getIoMode () EQ IO_MODE_CMD AND
+       at.CNMI_mode    EQ CNMI_MOD_Buffer )
+    cmd_flushCnmiBuf (CMD_SRC_ATI);*/
+}
+
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : cmd_handleCnmaTimeout |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function will be called when the +CNMA Timer has expired.
+            Now all to be acknowledged +CMT messages whithin the CNMI
+            buffer must be stored in the non-volatile buffer e.g. SIM...
+            Note: all other Msgs. different from +CMT will be deliver
+            to the source and remove from buffer. */
+
+GLOBAL void cmd_handleCnmaTimeout( void )
+{
+  UINT16                 uiCnmiMsgCounter  = 0;
+  T_CNMI_BUFFER_ELEMENT *psMsgInCnmiBuffer = NULL;
+
+  TRACE_FUNCTION ( "cmd_handleCnmaTimeout()" );
+
+  cmhSMS_resetMtDsCnmiParam();
+
+  if( waitForCnmaFromBuffer_SrcId EQ CMD_SRC_NONE OR 
+      waitForCnmaFromBuffer_SrcId NEQ smsShrdPrm.smsSrcId)
+  {
+    TRACE_EVENT("cmd_handleCnmaTimeout() : Error at CNMI-buffer handling: No +CNMA acknowledge expected!!");
+    waitForCnmaFromBuffer_SrcId = CMD_SRC_NONE;
+    return;
+  }
+
+  for( uiCnmiMsgCounter=0; uiCnmiMsgCounter<cmd_getNumberOfCnmiEntrys(); uiCnmiMsgCounter++ )
+  { /* there are entrys in the CNMI buffer --> read it */
+    psMsgInCnmiBuffer = cmd_getCnmiMessage(uiCnmiMsgCounter); /* FIFO */
+
+    if( psMsgInCnmiBuffer EQ NULL )
+    {
+      TRACE_EVENT("cmd_handleCnmaTimeout() : Error at CNMI-buffer handling: NULL-pointer access!!");
+      waitForCnmaFromBuffer_SrcId = CMD_SRC_NONE;
+      return;
+    }
+    
+    cnmiFlushInProgress = TRUE;
+
+    switch ( psMsgInCnmiBuffer->type )
+    {
+      case ( CNMI_CMTI ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCMTI ( psMsgInCnmiBuffer->indct.cmti.mem, psMsgInCnmiBuffer->indct.cmti.index );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      case ( CNMI_CBM ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCBM (  &psMsgInCnmiBuffer->indct.cbm );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      case ( CNMI_CDS ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCDS (  &psMsgInCnmiBuffer->indct.cds );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      /* special handling for +CMT --> acknowledge needed */
+      case ( CNMI_CMT ) :
+      {
+        T_ACI_SM_DATA sPduData;
+
+        waitForCnmaFromBuffer_SrcId = CMD_SRC_NONE; /* clear CNMA waiting flag */
+        srcId_cb = smsShrdPrm.smsSrcId;
+        sPduData.len = psMsgInCnmiBuffer->indct.cmt.sms_sdu.l_buf / 8; /* l_buf is in BIT !! */
+        memcpy( &sPduData.data, &psMsgInCnmiBuffer->indct.cmt.sms_sdu.buf, SIM_PDU_LEN );
+        cmhSMS_storePduToSim( smsShrdPrm.smsSrcId, SMS_RECORD_REC_UNREAD, &sPduData );
+        cnmiFlushInProgress = FALSE;
+        return; /* only one SMS can be stored at the SIM here */
+      }
+
+      default:
+        TRACE_EVENT("cmd_handleCnmaTimeout() : wrong CNMI-buffer handling: wrong Msg. type");
+    }
+    cnmiFlushInProgress = FALSE;
+  }
+}
+
+/*
++-----------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD               |
+| STATE   : code                        ROUTINE : cmd_handleCnmaTimeout |
++-----------------------------------------------------------------------+
+
+  PURPOSE : This function stores the next message - correxponding
+            to a specified source - into the non volatile memory.
+            Note: all other Msgs. different from +CMT will be deliver
+            to the source and remove from buffer.
+*/
+GLOBAL BOOL cmd_storeNextCnmiBufMsgToSim( void )
+{
+  UINT16                 uiCnmiMsgCounter  = 0;
+  T_CNMI_BUFFER_ELEMENT *psMsgInCnmiBuffer = NULL;
+
+  TRACE_FUNCTION ( "cmd_storeNextCnmiBufMsgToSim()" );
+
+  if( smsShrdPrm.uiInternalSmsStorage EQ CMD_SRC_NONE OR
+      smsShrdPrm.uiInternalSmsStorage NEQ smsShrdPrm.smsSrcId)
+  {
+    TRACE_EVENT("cmd_storeNextCnmiBufMsgToSim() : no valid source -> abort !!");
+    smsShrdPrm.uiInternalSmsStorage = CMD_SRC_NONE;
+    return(FALSE);
+  }
+
+  for( uiCnmiMsgCounter=0; uiCnmiMsgCounter<cmd_getNumberOfCnmiEntrys(); uiCnmiMsgCounter++ )
+  { /* there are entrys in the CNMI buffer --> read it */
+    psMsgInCnmiBuffer = cmd_getCnmiMessage(uiCnmiMsgCounter); /* FIFO */
+
+    if( psMsgInCnmiBuffer EQ NULL )
+    {
+      TRACE_EVENT("cmd_storeNextCnmiBufMsgToSim() : Error at CNMI-buffer handling: NULL-pointer access!!");
+      smsShrdPrm.uiInternalSmsStorage = CMD_SRC_NONE;
+      return(FALSE);
+    }
+    
+    cnmiFlushInProgress = TRUE;
+
+    switch ( psMsgInCnmiBuffer->type )
+    {
+      case ( CNMI_CMTI ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCMTI ( psMsgInCnmiBuffer->indct.cmti.mem, psMsgInCnmiBuffer->indct.cmti.index );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      case ( CNMI_CBM ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCBM (  &psMsgInCnmiBuffer->indct.cbm );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      case ( CNMI_CDS ) :
+        srcId_cb = smsShrdPrm.smsSrcId;
+        rCI_PlusCDS (  &psMsgInCnmiBuffer->indct.cds );
+        cmd_clearCnmiMessage(uiCnmiMsgCounter);
+        uiCnmiMsgCounter--;
+        break;
+
+      /* special handling for +CMT --> acknowledge needed */
+      case ( CNMI_CMT ) :
+      {
+        T_ACI_SM_DATA sPduData;
+
+        srcId_cb = smsShrdPrm.smsSrcId;
+        sPduData.len = psMsgInCnmiBuffer->indct.cmt.sms_sdu.l_buf / 8; /* l_buf is in BIT !! */
+        memcpy( &sPduData.data, &psMsgInCnmiBuffer->indct.cmt.sms_sdu.buf, SIM_PDU_LEN );
+        cmhSMS_storePduToSim( smsShrdPrm.smsSrcId, SMS_RECORD_REC_UNREAD, &sPduData );
+        cnmiFlushInProgress = FALSE;
+        return(TRUE); /* only one SMS can be stored at the SIM here */
+      }
+
+      default:
+        TRACE_EVENT("cmd_handleCnmaTimeout() : wrong CNMI-buffer handling: wrong Msg. type");
+    }
+    cnmiFlushInProgress = FALSE;
+  }
+  smsShrdPrm.uiInternalSmsStorage = CMD_SRC_NONE; /* no more +CMT has to be store */
+  return(FALSE);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : setatPlusCMMS      |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMMS command (More Messages To Send)
+*/
+
+GLOBAL T_ATI_RSLT setatPlusCMMS (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = AT_FAIL;
+  UBYTE        mode = 0;
+
+  TRACE_FUNCTION("setatPlusCMMS()");
+
+  cl = parse (cl,"r",&mode);
+
+  /*
+   * no mode values allowed other than 0-2
+   */
+  if ( !cl OR (mode < CMMS_MODE_DEF OR mode > CMMS_MODE_TWO))
+  {
+    cmdCmsError(CMS_ERR_OpNotAllowed);
+    return (ATI_FAIL);
+  }
+  ret = sAT_PlusCMMS(srcId,mode);
+  if (ret NEQ AT_CMPL)
+  {
+    cmdCmsError(CMS_ERR_UnknownErr);  
+    return (ret);
+  }
+  return (map_aci_2_ati_rslt(ret));
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : queatPlusCMMS      |
++--------------------------------------------------------------------+
+
+  PURPOSE : +CMMS query command 
+*/
+GLOBAL T_ATI_RSLT queatPlusCMMS (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN  ret = AT_FAIL;
+  UBYTE         mode = CMMS_MODE_DEF;
+  
+  TRACE_FUNCTION("queatPlusCMMS()");
+
+  ret = qAT_PlusCMMS (srcId,&mode);
+  if (ret EQ AT_CMPL)
+  {
+    sprintf(g_sa, "+CMMS: %d",  mode);
+    io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
+    return (ATI_CMPL);
+  }
+  else
+  {
+    cmdCmsError(CMS_ERR_NotPresent);  
+    return (ATI_FAIL);
+  }
+}
+
+/*
++-------------------------------------------------------------------------+
+| PROJECT : GSM-F&D                      MODULE  : ATI_SMS                |
+| STATE   : finished                     ROUTINE : txt_rdmode_to_smsrdmode|
++-------------------------------------------------------------------------+
+
+  PURPOSE : converts the text read mode to smsReadMode.
+
+*/
+GLOBAL T_ATI_RSLT txt_rdmode_to_smsrdmode(char *txt_rdmode)
+{
+  UBYTE i = 0;
+
+   if (txt_rdmode[0] EQ '\0')
+   {
+     strcpy (txt_rdmode, sms_rdmode[0].name); /* NORMAL as default */
+   }
+   while ( sms_rdmode[i].name NEQ NULL      AND
+              strcmp ( sms_rdmode[i].name, txt_rdmode ) NEQ 0 )
+   {
+      i++;
+   }
+
+   if ( sms_rdmode[i].name EQ NULL )
+   {
+      cmdCmsError ( CMS_ERR_OpNotAllowed );
+      return (ATI_FAIL);
+   }
+   smsReadMode  = sms_rdmode[i].rdmode;
+   return ATI_CMPL;
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPercentCMGL      |
++--------------------------------------------------------------------+
+
+  PURPOSE : %CMGL command (List Message)
+*/
+
+GLOBAL T_ATI_RSLT atPercentCMGL (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN   ret;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+#ifdef SMS_PDU_SUPPORT
+  T_ACI_CMGF_MOD mode;
+#endif
+  CHAR           txtStat[15]= {0};
+  CHAR           txtRdMode[20] = {0};
+  USHORT         i;
+
+  TRACE_FUNCTION("atPercentCMGL()");
+
+  cmglStat = SMS_STAT_NotPresent;
+  smsReadMode  = SMS_READ_NotPresent;
+
+  if (*cl EQ '\0')
+  {
+    smsReadMode  = SMS_READ_Normal;
+  }
+  else
+  {
+    /*
+     * Request of a list of stored SMS messages
+     * Parameter stat is optional
+     */
+#ifdef SMS_PDU_SUPPORT
+    /*
+     * request current mode
+     */
+    qAT_PlusCMGF(srcId, &mode);
+    if (mode EQ 0)
+    {
+
+      /*
+       * %CMGL=[stat],[preview]
+       */
+      cl = parse (cl, "dd", &cmglStat, &smsReadMode );
+      if ( !cl 
+            OR ((cmglStat < SMS_STAT_RecUnread OR cmglStat > SMS_STAT_All)
+                  AND smsReadMode  EQ SMS_READ_NotPresent) 
+            OR (cmglStat < SMS_STAT_RecUnread AND smsReadMode > SMS_READ_NotPresent) 
+            OR (smsReadMode  > SMS_READ_StatusChange))
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+    }
+    else
+#endif
+    {
+
+      /*
+       * %CMGL=[stat],[preview]
+       */
+      cl = parse (cl, "ss", (LONG)sizeof(txtStat), txtStat, 
+                  (LONG)sizeof(txtRdMode), txtRdMode);
+      if ( !cl OR (txtStat[0] EQ '\0' AND txtRdMode[0] NEQ '\0'))
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+      if (txtStat[0] EQ '\0')
+        strcpy (txtStat, sms_stat[4].name); /* ALL as default */
+
+      i = 0;
+      while ( sms_stat[i].name NEQ NULL            AND
+              strcmp ( sms_stat[i].name, txtStat ) NEQ 0 )
+        i++;
+
+      if ( sms_stat[i].name EQ NULL )
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+      cmglStat = sms_stat[i].stat;
+
+      ret = txt_rdmode_to_smsrdmode(txtRdMode);
+      if (ret EQ ATI_FAIL)
+      {
+        return (ret);
+      }
+    }
+  }
+
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_percent_cmgl cmgl;
+
+    cmd.ctrl_params=BAT_CMD_SET_PERCENT_CMGL;
+    cmd.params.ptr_set_percent_cmgl=&cmgl;
+
+    /*
+    *   T_ACI_SMS_STAT and T_BAT_percent_cmgl_stat are not quite
+    *   identical - the ACI version has the extra value
+    *   SMS_STAT_Invalid.
+    */
+    if (cmglStat EQ SMS_STAT_Invalid)
+      cmgl.stat=BAT_CMGL_STAT_NOT_PRESENT;
+    else
+      cmgl.stat=(T_BAT_percent_cmgl_stat)cmglStat;
+
+    cmgl.rdmode = smsReadMode ;
+
+    bat_send(ati_bat_get_client(srcId),&cmd);
+
+    src_params->curAtCmd=AT_CMD_P_CMGL;
+    return(ATI_EXCT);
+  }
+
+#else
+
+  ret = sAT_PercentCMGL ( srcId, cmglStat, smsReadMode  );
+
+  if ( ret EQ AT_EXCT )
+  {
+    src_params->curAtCmd = AT_CMD_P_CMGL;
+    return (ATI_EXCT);
+  }
+  else
+  {
+    cmdCmsError ( CMS_ERR_NotPresent );  
+    return (ATI_FAIL);
+  }
+#endif
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : atPercentCMGR         |
++--------------------------------------------------------------------+
+
+  PURPOSE : %CMGR command (Read Message)
+*/
+
+GLOBAL T_ATI_RSLT atPercentCMGR (char *cl, UBYTE srcId)
+{
+  T_ACI_RETURN ret = AT_FAIL;
+  SHORT idx=-1;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+#ifdef SMS_PDU_SUPPORT
+  T_ACI_CMGF_MOD mode;
+#endif
+  CHAR           txtRdMode[20]={0};
+
+
+  TRACE_FUNCTION("atPercentCMGR()");
+
+  smsReadMode  = SMS_READ_Normal;
+
+#ifdef SMS_PDU_SUPPORT
+    /*
+     * request current mode
+     */
+    qAT_PlusCMGF(srcId, &mode);
+    if (mode EQ 0)
+    {
+      /*
+       * %CMGR=[index],[preview]
+       */
+      cl = parse (cl, "rd", &idx, &smsReadMode );
+      if ( !cl OR idx > 255 OR idx < 0 OR smsReadMode  > SMS_READ_StatusChange)
+      {
+        cmdCmsError ( CMS_ERR_OpNotAllowed );
+        return (ATI_FAIL);
+      }
+    }
+    else
+#endif
+    {
+      /*
+       * %CMGR=[index],[preview]
+       */
+      cl = parse (cl, "rs", &idx, 
+                  (LONG)sizeof(txtRdMode), txtRdMode);
+  
+      if ( !cl OR idx > 255 OR idx < 0)
+      {
+        cmdCmsError(CMS_ERR_OpNotAllowed);
+        return (ATI_FAIL);
+      }
+      ret = txt_rdmode_to_smsrdmode(txtRdMode);
+      if (ret EQ ATI_FAIL)
+      {
+        return (ret);
+      }
+    }
+
+#ifdef FF_ATI_BAT
+  {
+    T_BAT_cmd_send cmd;
+    T_BAT_cmd_set_percent_cmgr cmgr;
+
+    cmd.ctrl_params=BAT_CMD_SET_PERCENT_CMGR;
+    cmd.params.ptr_set_percent_cmgr=&cmgr;
+
+    cmgr.sms_index=(U16)idx;
+    
+    cmgr.rdmode = smsReadMode ;
+
+    bat_send(ati_bat_get_client(srcId), &cmd);
+
+    src_params->curAtCmd=AT_CMD_P_CMGR;
+    return(ATI_EXCT);
+  }
+
+#else
+
+#ifndef _CONC_TESTING_
+  ret = sAT_PercentCMGR_Gl(srcId, (UBYTE)idx, smsReadMode , NULL);
+#else
+  ret = sAT_PercentCMGR (srcId, (UBYTE)idx, smsReadMode );
+#endif
+ if ( ret EQ AT_CMPL )
+ {
+   return (ATI_CMPL);
+ }
+ else if (ret EQ AT_EXCT)
+ {
+   src_params->curAtCmd    = AT_CMD_P_CMGR;
+   return (ATI_EXCT);
+ }
+ else
+ {
+   cmdCmsError(CMS_ERR_NotPresent);  // use aciErrDesc
+   return (ATI_FAIL);
+ }
+
+#endif /*FF_ATI_BAT*/
+}
+
+GLOBAL T_ATI_RSLT tesatPercentCMGL (char *cl, UBYTE srcId)
+{
+#ifdef SMS_PDU_SUPPORT
+  T_ACI_CMGF_MOD mode;
+  T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, srcId, search_ati_src_id);
+
+  TRACE_FUNCTION("tesatPercentCMGL()");
+  /*
+   * request current mode
+   */
+  qAT_PlusCMGF(srcId, &mode);
+  if (mode EQ 0)
+  /*
+   * handle PDU mode
+   */
+    io_sendMessage(srcId, "+CMGL: (0,1,2,3,4), (0,1,2)", ATI_NORMAL_OUTPUT);
+  else
+  /*
+   * handle Text mode
+   */
+#endif
+   io_sendMessage(srcId, "+CMGL: (\"REC UNREAD\",\"REC READ\",\"STO UNSENT\",\"STO SENT\",\"ALL\"), \
+                                 (\"READ NORMAL\",\"READ PREVIEW\",\"STATUS CHANGE\")", ATI_NORMAL_OUTPUT);
+
+  return (ATI_CMPL);
+}
+
+#endif /* ATI_SMS_C */