diff g23m/condat/ms/src/aci/aci_util.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m/condat/ms/src/aci/aci_util.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,3028 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GSM-PS (6147)
+|  Modul   :  ACI_UTIL
++----------------------------------------------------------------------------- 
+|  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 :  This module defines the utility functions for the AT
+|             command interpreter.
++----------------------------------------------------------------------------- 
+*/ 
+
+
+
+#ifndef ACI_UTIL_C
+#define ACI_UTIL_C
+#endif
+
+#include "aci_all.h"
+
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+
+#include "aci_cmd.h"
+
+#ifdef FAX_AND_DATA
+#include "aci_fd.h"
+#endif    /* of #ifdef FAX_AND_DATA */
+
+#include "psa.h"
+#include "psa_sms.h"
+#include "phb.h"
+#include "cmh.h"
+#include "cmh_sms.h"
+
+#if defined (FF_ATI) || defined (FF_BAT)
+#include "aci_mem.h"
+#include "aci_lst.h"
+#include "aci_io.h"
+#include "ksd.h"
+#include "cmh_ss.h"
+#include "psa_ss.h"
+#endif
+#ifdef FF_ATI
+#include "ati_int.h"
+#endif
+#ifdef FF_BAT
+#include "aci_bat_cb.h"
+#endif
+
+
+
+#ifdef GPRS
+#include "gaci_cmh.h"
+#endif /* GPRS */
+
+/*==== CONSTANTS ==================================================*/
+
+#define CSCS_CHSET_Chars  256
+
+/*==== TYPES ======================================================*/
+
+/*==== EXPORT =====================================================*/
+/* This fucntion cuts the pathname from the file
+   used by ACI_ASSERT makro*/
+GLOBAL char * getFileName(char * file)
+{
+  char *cursor = file;
+  do {
+    #ifdef _SIMULATION_
+    if(*cursor EQ '\\') { file = cursor+1;}
+    #else
+    if(*cursor EQ '/') { file = cursor+1;}
+    #endif
+    cursor++;
+  } while(*cursor NEQ '\0');
+  return file;
+}
+
+
+LOCAL USHORT utl_ucs2FromGsm ( UBYTE*           in,
+                              USHORT           inLen,
+                              UBYTE*           out,
+                              USHORT           maxOutLen,
+                              USHORT*          outLen,
+                              T_ACI_GSM_ALPHA  gsm,
+                              T_ACI_CSCS_ALPHA alphabet );
+
+/*==== VARIABLES ==================================================*/
+
+GLOBAL const UBYTE chset [CSCS_CHSET_Tables][CSCS_CHSET_Chars] =
+{
+/*
+ *-------------------------------------------------------------------
+ * Conversion table: IRA -> internal GSM
+ *-------------------------------------------------------------------
+ */
+/* 0x00 */  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x08 */    0x00, 0x00, 0x8A, 0x00, 0x00, 0x8D, 0x00, 0x00,
+/* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x18 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x20 */    0xA0, 0xA1, 0xA2, 0xA3, 0x82, 0xA5, 0xA6, 0xA7,
+/* 0x28 */    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+/* 0x30 */    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+/* 0x38 */    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+/* 0x40 */    0x80, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+/* 0x48 */    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+/* 0x50 */    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+/* 0x58 */    0xD8, 0xD9, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x91/*00*/,
+/* 0x60 */    0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+/* 0x68 */    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+/* 0x70 */    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+/* 0x78 */    0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x80 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x88 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x90 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x98 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xA0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xA8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xE0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xE8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+
+/*
+ *-------------------------------------------------------------------
+ * Conversion table: PC Danish/Norwegian -> internal GSM
+ *-------------------------------------------------------------------
+ */
+/* 0x00 */  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x08 */    0x00, 0x00, 0x8A, 0x00, 0x00, 0x8D, 0x00, 0x00,
+/* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00,
+/* 0x18 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x20 */    0xA0, 0xA1, 0xA2, 0xA3, 0x82, 0xA5, 0xA6, 0xA7,
+/* 0x28 */    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+/* 0x30 */    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+/* 0x38 */    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+/* 0x40 */    0x80, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+/* 0x48 */    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+/* 0x50 */    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+/* 0x58 */    0xD8, 0xD9, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x91/*00*/,
+/* 0x60 */    0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+/* 0x68 */    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+/* 0x70 */    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+/* 0x78 */    0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x80 */    0x89, 0xFE, 0x85, 0xE1, 0xFB, 0xFF, 0x8F, 0x89,
+/* 0x88 */    0xE5, 0xE5, 0x84, 0xE9, 0xE9, 0x87, 0xDB, 0x8E,
+/* 0x90 */    0x9F/*C5*/, 0x9D, 0x9C, 0xEF, 0xFC, 0x88, 0xF5/*E5*/, 0x86,
+/* 0x98 */    0xF9/*E9*/, 0xDC, 0xDE, 0x8C, 0x81, 0x8B, 0x00, 0x00,
+/* 0xA0 */    0xE1, 0xE9, 0xEF, 0xF5, 0xFD, 0xDD, 0x00, 0x00,
+/* 0xA8 */    0xE0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
+/* 0xB0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xE0 */    0x00, 0x9E, 0x93, 0x00, 0x98, 0x00, 0x00, 0x00,
+/* 0xE8 */    0x92, 0x99, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+
+/*
+ *-------------------------------------------------------------------
+ * Conversion table: ISO 8859 Latin 1 -> internal GSM
+ *-------------------------------------------------------------------
+ */
+/* 0x00 */  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x08 */    0x00, 0x00, 0x8A, 0x00, 0x00, 0x8D, 0x00, 0x00,
+/* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x18 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x20 */    0xA0, 0xA1, 0xA2, 0xA3, 0x82, 0xA5, 0xA6, 0xA7,
+/* 0x28 */    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+/* 0x30 */    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+/* 0x38 */    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+/* 0x40 */    0x80, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+/* 0x48 */    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+/* 0x50 */    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+/* 0x58 */    0xD8, 0xD9, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x91/*00*/,
+/* 0x60 */    0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+/* 0x68 */    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+/* 0x70 */    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+/* 0x78 */    0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x80 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x88 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x90 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x98 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xA0 */    0x00, 0xC0, 0x00, 0x81, 0xA4, 0x83, 0x00, 0xDF,
+/* 0xA8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
+/* 0xC0 */    0xC1, 0xC1, 0xC1, 0xC1, 0xDB, 0x8E, 0x9C, 0x89,
+/* 0xC8 */    0xC5, 0x9F/*C5*/, 0xC5, 0xC5, 0xC9, 0xC9, 0xC9, 0xC9,
+/* 0xD0 */    0x00, 0xDD, 0xCF, 0xCF, 0xCF, 0xCF, 0xDC, 0x00,
+/* 0xD8 */    0x8B, 0xD5, 0xD5, 0xD5, 0xDE, 0xD9, 0x00, 0x9E,
+/* 0xE0 */    0xFF, 0xE1, 0xE1, 0xE1, 0xFB, 0x8F, 0x9D, 0x89,
+/* 0xE8 */    0x84, 0x85, 0xE5, 0xE5, 0x87, 0xE9, 0xE9, 0xE9,
+/* 0xF0 */    0x00, 0xFD, 0x88, 0xEF, 0xEF, 0xEF, 0xFC, 0x00,
+/* 0xF8 */    0x8C, 0x86, 0xF5, 0xF5, 0xFE, 0xF9, 0x00, 0xF9 },
+
+/*
+ *-------------------------------------------------------------------
+ * Conversion table: PC Code Page 437 -> internal GSM
+ *-------------------------------------------------------------------
+ */
+/* 0x00 */  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x08 */    0x00, 0x00, 0x8A, 0x00, 0x00, 0x8D, 0x00, 0x00,
+/* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00,
+/* 0x18 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x20 */    0xA0, 0xA1, 0xA2, 0xA3, 0x82, 0xA5, 0xA6, 0xA7,
+/* 0x28 */    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+/* 0x30 */    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+/* 0x38 */    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+/* 0x40 */    0x80, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+/* 0x48 */    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+/* 0x50 */    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+/* 0x58 */    0xD8, 0xD9, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x91/*00*/,
+/* 0x60 */    0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+/* 0x68 */    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+/* 0x70 */    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+/* 0x78 */    0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x80 */    0x89, 0xFE, 0x85, 0xE1, 0xFB, 0xFF, 0x8F, 0x89,
+/* 0x88 */    0xE5, 0xE5, 0x84, 0xE9, 0xE9, 0x87, 0xDB, 0x8E,
+/* 0x90 */    0x9F/*C5*/, 0x9D, 0x9C, 0xEF, 0xFC, 0x88, 0xF5/*E5*/, 0x86,
+/* 0x98 */    0xF9/*E9*/, 0xDC, 0xDE, 0x00, 0x81, 0x83, 0x00, 0x00,
+/* 0xA0 */    0xE1, 0xE9, 0xEF, 0xF5, 0xFD, 0xDD, 0x00, 0x00,
+/* 0xA8 */    0xE0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00,
+/* 0xB0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xE0 */    0x00, 0x9E, 0x93, 0x00, 0x98, 0x00, 0x00, 0x00,
+/* 0xE8 */    0x92, 0x99, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+
+/*
+ *-------------------------------------------------------------------
+ * Conversion table: GSM -> internal GSM
+ *-------------------------------------------------------------------
+ */
+/* 0x00 */  { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+/* 0x08 */    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+/* 0x10 */    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+/* 0x18 */    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+/* 0x20 */    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+/* 0x28 */    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+/* 0x30 */    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+/* 0x38 */    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+/* 0x40 */    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+/* 0x48 */    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+/* 0x50 */    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+/* 0x58 */    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+/* 0x60 */    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+/* 0x68 */    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+/* 0x70 */    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+/* 0x78 */    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
+/* 0x80 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x88 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x90 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0x98 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xA0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xA8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xB8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xC8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xD8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xE0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xE8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF0 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0xF8 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+
+/*
+ *-------------------------------------------------------------------
+ * Conversion table: ASCII <-> internal GSM
+ * ( needed for the conversion of UCS2 <-> internal GSM )
+ *-------------------------------------------------------------------
+ */
+/* GSM alphabet characters unknown in the ASCII table have been 
+   replaced by <SP> characters */
+LOCAL const UBYTE gsmToAsciiTable[128] =
+{   
+    /*n =     0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
+/* 0x0n */   64,163, 36,165,232,233,249,236,242,199, 10,216,248, 13,197,229,
+/* 0x1n */  128, 95,129,130,131,132,133,134,135,136,137, 32,198,230,223,201,
+/* 0x2n */   32, 33, 34, 35,164, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+/* 0x3n */   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+/* 0x4n */  161, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+/* 0x5n */   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,196,214,209,220,167,
+/* 0x6n */  191, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
+/* 0x7n */  112,113,114,115,116,117,118,119,120,121,122,228,246,241,252,224
+};
+
+LOCAL const UBYTE  hexVal[] = {"0123456789ABCDEF"};
+
+/*
+static const unsigned char
+gsm_2_ascii_table[128] = 
+{
+  0x40, 0x9C, 0x24, 0x9D, 0x8A, 0x82, 0x97, 0x8D, 0x95, 0x80, 0x0A, 0x02, 0x07, 0x0D, 0x8F, 0x86,
+  0x04, 0x5F, 0xE8, 0xE2, 0xEF, 0xEA, 0xE3, 0x05, 0xE6, 0xE9, 0xF0, 0x20, 0x92, 0x91, 0xE1, 0x90, 
+  0x20, 0x21, 0x22, 0x23, 0x01, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+  0xAD, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x8E, 0x99, 0xA5, 0x9A, 0x06,
+  0xA8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x84, 0x94, 0xA4, 0x81, 0x85
+};
+*/
+
+/*==== FUNCTIONS ==================================================*/
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : strupper                     |
++-------------------------------------------------------------------+
+
+  PURPOSE : Converts all characters from 'a' to 'z' to capital
+            characters from 'A' to 'Z'.
+*/
+GLOBAL char* strupper ( char* s )
+{
+  USHORT i = 0;
+
+  while ( s NEQ 0 AND s[i] NEQ '\0')
+  {
+    if ( s[i] >= 0x61 AND s[i] <= 0x7a )
+
+      s[i] = s[i] - 0x20;
+
+    i++;
+  }
+
+  return s;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_chsetToGsm               |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the character set used within the AT command interpreter
+            to the SIM GSM character set.
+*/
+GLOBAL void utl_chsetToSim ( UBYTE*          in,
+                             USHORT          inLen,
+                             UBYTE*          out,
+                             USHORT*         outLen,
+                             T_ACI_GSM_ALPHA gsm )
+{
+  UBYTE  cvtdVal;
+  USHORT outIdx   = 0;
+  USHORT inIdx;
+  UBYTE  corr     = ( gsm EQ GSM_ALPHA_Int ? 0xFF : 0x7F );
+  T_ACI_CSCS_CHSET cscsChset;
+  UBYTE  srcId = srcId_cb;
+
+  cscsChset = ati_user_output_cfg[srcId].cscsChset;
+  
+  if ( cscsChset EQ CSCS_CHSET_Hex )
+  {
+    utl_hexToGsm ( in, inLen, out, outLen, gsm, CSCS_ALPHA_8_Bit );
+  }
+  else if ( cscsChset EQ CSCS_CHSET_Ucs2 )
+  {
+    /* If the user chooses UCS2, then the best mode of coding should be 
+     * used to store the characters in the SIM */
+    utl_ucs2ToSim(in, inLen, out, outLen, gsm, CSCS_ALPHA_8_Bit);
+  }
+  else
+  {
+    for ( inIdx = 0; inIdx < inLen; inIdx++ )
+    {
+      cvtdVal = chset[cscsChset][( UBYTE ) in[inIdx]];
+
+      if ( cvtdVal NEQ 0x00 )
+      {
+        out[outIdx] = ( CHAR ) cvtdVal & corr;
+        outIdx++;
+      }
+    }
+
+    if ( gsm EQ GSM_ALPHA_Int )
+      out[outIdx] = '\0';
+
+    *outLen = outIdx;
+  }
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_codeUcs2                 |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function finds optimal coding format to store the 
+            UCS2 character string in the phone book.
+*/
+GLOBAL void utl_ucs2ToSim( UBYTE*          in,
+                           USHORT          inLen,
+                           UBYTE*          out,
+                           USHORT*         outLen,
+                           T_ACI_GSM_ALPHA gsm,
+                           T_ACI_CSCS_ALPHA alphabet)
+{
+  int    i;
+  BOOL   flag = TRUE;
+  USHORT ucs2_len = inLen/4;
+  UBYTE  hexOut[MAX_ALPHA_LEN * 4];
+  USHORT hexOutLen = 0;
+
+  /* Convert the hex character string to actual hex values */
+  hexOutLen = utl_HexStrToBin(in, inLen, hexOut, (MAX_ALPHA_LEN * 4));
+
+  /* Initial check is done for GSM or ASCII only characters */
+  for(i = 0; i < (hexOutLen/2); i++)
+  {
+    if(( hexOut[i*2] NEQ 0x00 ))
+    {
+      flag = FALSE;
+      break;
+    }
+  }
+  if (flag EQ TRUE)
+  {
+    utl_ConvUcs2ToGSM(hexOut, hexOutLen, out, outLen, gsm, alphabet);
+    if (*outLen)
+      return;
+  }
+
+  /* If possible UCS2 character string is coded in 0x81 format which
+     uses a one byte base pointer */
+  utl_Ucs2InFormat1 (hexOut, hexOutLen, out, outLen);
+  if (*outLen)
+    return;
+
+  /* If possible UCS2 character string is coded in 0x82 format which
+     uses two byte base pointer */
+  utl_Ucs2InFormat2 (hexOut, hexOutLen, out, outLen);
+  if (*outLen)
+    return;
+
+  /* If none of the above work, UCS2 character string is coded in 0x80 */
+  *out = 0x80;
+  utl_hexToGsm ( in, inLen, out + 1, outLen, gsm, CSCS_ALPHA_8_Bit );
+  (*outLen)++;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_ConvUcs2ToGSM            |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts UCS2 charecter string consisting of 
+            only ASCII charecters to default GSM values.
+*/
+GLOBAL void utl_ConvUcs2ToGSM ( UBYTE*           in,
+                                USHORT           inLen,
+                                UBYTE*           out,
+                                USHORT*          outLen,
+                                T_ACI_GSM_ALPHA  gsm,
+                                T_ACI_CSCS_ALPHA alphabet )
+{
+  int i, j;
+  BOOL   flag;
+  UBYTE  val = 0x00;
+  USHORT len;
+  UBYTE  tmpOut;
+  USHORT outIdx = 0;
+
+  len = inLen/2;
+  for (i = 0;i < len; i++)
+  {
+    tmpOut = in[(i*2) + 1];    
+    /* convert the hexadecimal ASCII value to GSM, if the value is
+     * not convertible then we exit */
+    if ( tmpOut EQ ( gsmToAsciiTable[tmpOut])) /* ASCII and GSM are identical */
+    {
+      val = tmpOut;
+    }
+    else /* find match in the table and copy index of match */
+    {
+      flag = FALSE;
+      for (j=0; j<128; j++)
+      {
+        if (tmpOut EQ gsmToAsciiTable[j])
+        {
+          val = (UBYTE)j;
+          flag = TRUE;
+          break;
+        }
+      }
+      if (!flag)
+      {
+        *outLen = 0;
+        return;
+      }
+    }      
+    
+    /* if necessary, cut the GSM value to 7bit */
+    if ( alphabet EQ CSCS_ALPHA_7_Bit AND !( val & 0x80 ) )
+    {
+      if ( gsm EQ GSM_ALPHA_Int )
+      {
+        out[outIdx++] = val | 0x80; 
+      }
+      else
+      {
+        out[outIdx++] = val;
+      }
+    }
+    else
+    {
+      out[outIdx++] = val;
+    }
+  }
+      
+  if ( gsm EQ GSM_ALPHA_Int )
+  {
+    out[outIdx] = '\0';
+  }
+
+  /* set the outlength */
+  *outLen = outIdx;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_Ucs2InFormat1            |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the UCS2 character string in the 
+            0x81 coding scheme for UCS2.
+            Octet 1: 0x81
+            Octet 2: Num of Characters
+            Octet 3: Bits 15 to 8 of Base pointer
+            Octet 4 onwards: Characters
+*/
+GLOBAL void utl_Ucs2InFormat1( UBYTE*           in,
+                               USHORT           inLen,
+                               UBYTE*           out,
+                               USHORT*          outLen)
+{
+  int i, j;
+  UBYTE  base_ptr = 0x00;
+  UBYTE  temp_ptr;
+  USHORT len = inLen/2;
+  USHORT tmp_base;
+  USHORT tmp;
+  USHORT outIdx = 0;
+  
+
+  /* We first check if the UCS2 string can be coded 
+   * using a single base pointer */
+  for (i = 0; i < len; i++)
+  {
+    if (in[i*2])
+    {
+      if ((in[i*2] & 0x80))
+      {
+        *outLen = 0;
+        return;
+      }
+      temp_ptr = in[i*2] & 0x7f;
+      temp_ptr <<= 1;
+      temp_ptr |= ((in[(i*2)+1] & 0x80) >> 7);
+      
+      if (base_ptr)
+      {
+        if (temp_ptr NEQ base_ptr)
+        {
+          *outLen = 0;
+          return;           
+        }
+      } else
+      {
+        base_ptr = temp_ptr;
+      }
+    }
+  }
+
+
+  /* Characters are coded using the base pointer below */
+  /* For details, see GSM 11.11 Annex B (normative) */
+  out[0] = 0x81;
+  if (len < PHB_MAX_TAG_LEN - 3)
+  {
+    out[1] = (UBYTE)len;
+  } else
+  {
+    out[1] = PHB_MAX_TAG_LEN - 3;
+  }
+  out[2]   = base_ptr;
+  tmp_base = 0;
+  tmp_base = base_ptr << 7;
+  outIdx   = 3;
+
+  len = out[1];
+  for (i = 0; i < len; i++)
+  {
+    if (in[i*2])
+    {
+      tmp  = 0;
+      tmp  = in[i*2] << 8;
+      tmp |= in[(i*2)+1];
+      out[outIdx++] = (tmp - tmp_base) | 0x80;
+    } else 
+    {
+      for (j=0; j<128; j++)
+      {
+        if (in[(i*2)+1] EQ gsmToAsciiTable[j])
+        {
+          out[outIdx++] = (UBYTE)j;
+          break;
+        }
+      }
+
+   /* If the charecter cannot be found in ASCII table exit */
+   if (j EQ 128)
+   {
+     *outLen = 0;
+     return ;
+   }
+
+    }
+  }
+
+  *outLen = outIdx;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_Ucs2InFormat2            |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the UCS2 character string in the 
+            0x82 coding scheme for UCS2.
+            Octet 1: 0x82
+            Octet 2: Number of characters
+            Octet 3 and Octet 4: 2 byte base pointer
+            Octet 5 onwards: Characters 
+            
+*/
+GLOBAL void utl_Ucs2InFormat2( UBYTE*           in,
+                               USHORT           inLen,
+                               UBYTE*           out,
+                               USHORT*          outLen)
+{
+  int i, j;
+  USHORT len = inLen/2;
+  USHORT lowest_ch  = 0;
+  USHORT highest_ch = 0;
+  USHORT tmp;
+  USHORT outIdx = 0;
+  
+
+  /* We first check if the UCS2 string can be coded 
+   * using a smallest char as the base pointer */
+  for (i = 0; i < len; i++)
+  {
+    if (in[i*2])
+    {
+      tmp  = 0;
+      tmp  = in[i*2] << 8;
+      tmp |= in[(i*2)+1];
+
+      if (lowest_ch EQ 0 OR tmp < lowest_ch)
+        lowest_ch = tmp;
+
+      if (tmp > highest_ch)
+        highest_ch = tmp;
+    }
+  }
+
+  /* To use lowest char can be used as the base pointer, the distance
+   * between the lowest and highest char must not be more then 128 */
+  if ((highest_ch - lowest_ch) > 0x80)
+  {
+    *outLen = 0;
+    return;
+  }
+
+  /* Characters are coded using the base pointer below */
+  /* For details, see GSM 11.11 Annex B (normative) */
+  out[0] = 0x82;
+  if (len < PHB_MAX_TAG_LEN - 4)
+  {
+    out[1] = (UBYTE)len;
+  } else
+  {
+    out[1] = PHB_MAX_TAG_LEN - 4;
+  }
+  out[2] = (lowest_ch & 0xff00) >> 8;
+  out[3] = (lowest_ch & 0x00ff);  
+  outIdx   = 4;
+
+  len = out[1];
+  for (i = 0; i < len; i++)
+  {
+    if (in[i*2])
+    {
+      tmp  = 0;
+      tmp  = in[i*2] << 8;
+      tmp |= in[(i*2)+1];
+      out[outIdx++] = (tmp - lowest_ch) | 0x80;
+    } else 
+    {
+      for (j=0; j<128; j++)
+      {
+        if (in[(i*2)+1] EQ gsmToAsciiTable[j])
+        {
+          out[outIdx++] = (UBYTE)j;
+          break;
+        }
+      }
+
+    /* If the charecter cannot be found in ASCII table exit */
+     if (j EQ 128)
+     {
+      *outLen = 0;
+      return ;
+     }
+    }
+  }
+
+  *outLen = outIdx;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_chsetToGsm               |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the character set used within the AT command interpreter
+            to the ACI internal GSM character set.
+*/
+GLOBAL void utl_chsetToGsm ( UBYTE*          in,
+                             USHORT          inLen,
+                             UBYTE*          out,
+                             USHORT*         outLen,
+                             T_ACI_GSM_ALPHA gsm )
+{
+  UBYTE  cvtdVal;
+  USHORT outIdx   = 0;
+  USHORT inIdx;
+  UBYTE  corr     = ( gsm EQ GSM_ALPHA_Int ? 0xFF : 0x7F );
+  T_ACI_CSCS_CHSET cscsChset;
+  UBYTE  srcId = srcId_cb;
+
+  cscsChset = ati_user_output_cfg[srcId].cscsChset;
+
+  if ( ati_user_output_cfg[srcId].cscsChset EQ CSCS_CHSET_Hex )
+  {
+    utl_hexToGsm ( in, inLen, out, outLen, gsm, CSCS_ALPHA_8_Bit );
+  }
+  else if ( cscsChset EQ CSCS_CHSET_Ucs2 )
+  {
+    utl_ucs2ToGsm ( in, inLen, out, outLen, gsm, CSCS_ALPHA_8_Bit );
+  }
+  else
+  {
+    for ( inIdx = 0; inIdx < inLen; inIdx++ )
+    {
+      cvtdVal = chset[cscsChset][( UBYTE ) in[inIdx]];
+
+      if ( cvtdVal NEQ 0x00 )
+      {
+        out[outIdx] = ( CHAR ) cvtdVal & corr;
+        outIdx++;
+      }
+    }
+
+    if ( gsm EQ GSM_ALPHA_Int )
+      out[outIdx] = '\0';
+
+    *outLen = outIdx;
+  }
+}
+#endif
+
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_hexFromAlpha             |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the SIM with UCS2 form 0x81 or 0x82 to 16 Bit hex values.
+            see GSM 11.11 Annex B Coding of Alpha fields in the SIM for UCS2
+            UCS2 form 0x81:
+             - octet 1 = 0x81
+             - octet 2 = length
+             - octet 3 = Bits 15 to 8 of the base pointer to a half page in the UCS2 code space
+                         0hhh hhhh h000 0000 , with h = bits of the half page base pointer
+                        16... .... .... ...1
+
+            UCS2 form 0x82:
+             - octet 1 = 0x81
+             - octet 2 = length
+             - octet 3 = upper 8 Bit of 16 Bit base pointer to a half page in the UCS2 code space
+             - octet 4 = lower 8 Bit of 16 Bit base pointer to a half page in the UCS2 code space           
+*/
+GLOBAL void utl_hexFromUCS2  ( UBYTE  *in, 
+                              UBYTE  *out, 
+                              USHORT  maxOutlen, 
+                              USHORT *outlen)
+{
+  USHORT outIdx = 0;
+  USHORT base_pointer;
+  USHORT length = in[1];
+  USHORT tmp;
+
+  if (*in EQ 0x81)
+  {
+    base_pointer = in[2] << 7;
+    in += 3;
+  }
+  else /* if (*in EQ 0x82) */
+  {
+    base_pointer = in[2]<<8 | in[3];
+    in += 4;
+  }
+  
+  while ( length-- AND outIdx < maxOutlen-2)
+  {  
+    if (*in & 0x80)
+    {
+      tmp  = base_pointer + (*in & 0x7F); 
+    }
+    else
+    {
+      tmp  = 0x0000 + gsmToAsciiTable[*in];
+    }
+    out[outIdx++] = hexVal[(tmp >> 12) & 0x0F ];
+    out[outIdx++] = hexVal[(tmp >>  8) & 0x0F ];
+    out[outIdx++] = hexVal[(tmp >>  4) & 0x0F ];
+    out[outIdx++] = hexVal[(tmp      ) & 0x0F ];
+
+    in++;
+  }
+
+  out[outIdx] = '\0';
+  *outlen = outIdx;
+}
+#endif
+
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_chsetFromGsm             |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the SIM format to the character set
+            used within the AT command interpreter.
+*/
+GLOBAL void utl_chsetFromSim ( UBYTE*          in,
+                               USHORT          inLen,
+                               UBYTE*          out,
+                               USHORT          maxOutLen,
+                               USHORT*         outLen,
+                               T_ACI_GSM_ALPHA gsm )
+{
+  T_ACI_CSCS_CHSET cscsChset;
+  UBYTE srcId = srcId_cb;
+
+  cscsChset = ati_user_output_cfg[srcId].cscsChset;
+
+  if ( cscsChset EQ CSCS_CHSET_Ucs2 AND
+        (( *in EQ 0x80 ) OR ( *in EQ 0x81 ) OR ( *in EQ 0x82 )) )
+  {
+    /* UCS2 with form 0x81 or 0x82 as HEX string */
+    if (( *in EQ 0x81 ) OR ( *in EQ 0x82 ))
+    {
+      utl_hexFromUCS2 ( in, out, maxOutLen, outLen);
+      return;
+    }
+    
+    /* UCS2 form 0x80 as HEX string */
+    utl_hexFromGsm ( in + 1, (USHORT)( inLen - 1 ), out, maxOutLen, outLen,
+                     gsm, CSCS_ALPHA_8_Bit );
+  } 
+  else 
+  {
+    utl_chsetFromGsm ( in, inLen, out, maxOutLen, outLen, gsm );
+  }
+}
+#endif /* #ifdef FF_ATI */
+
+#if defined(FF_ATI) || defined(FF_BAT)
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_chsetFromGsm             |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the ACI internal GSM character set to the character set
+            used within the AT command interpreter.
+*/
+
+GLOBAL USHORT utl_chsetFromGsm(
+  UBYTE*            in,
+  USHORT            inLen,
+  UBYTE*            out,
+  USHORT            maxOutLen,
+  USHORT*           outLen,
+  T_ACI_GSM_ALPHA   gsm)
+{
+  USHORT outIdx = 0;
+  USHORT inIdx  = 0;
+  USHORT actLen = ( gsm EQ GSM_ALPHA_Int ?
+                        ( USHORT ) strlen ( ( CHAR* ) in ) : inLen );
+  UBYTE  corr   = ( gsm EQ GSM_ALPHA_Int ? 0x00 : 0x80 );
+  T_ACI_CSCS_CHSET cscsChset;
+  UBYTE  srcId = srcId_cb;
+  USHORT tblIdx;
+
+  cscsChset = ati_user_output_cfg[srcId].cscsChset;
+
+  if ( cscsChset EQ CSCS_CHSET_Hex )
+  {
+    return utl_hexFromGsm ( in, inLen, out, maxOutLen, outLen, gsm, CSCS_ALPHA_8_Bit );
+  }
+  else if ( cscsChset EQ CSCS_CHSET_Ucs2 )
+  {
+    return utl_ucs2FromGsm ( in, inLen, out, maxOutLen, outLen, gsm, CSCS_ALPHA_8_Bit );
+  }
+  else
+  {
+    while ( inIdx < actLen AND outIdx < maxOutLen - 1 )
+    {
+      tblIdx = 0;
+
+      while ( tblIdx <= 0xFF                                      AND
+              chset[cscsChset][tblIdx] NEQ (( UBYTE )in[inIdx] | corr ))
+        tblIdx++;
+
+      if ( tblIdx <= 0xFF )
+      {
+        out[outIdx] = ( UBYTE )tblIdx;
+        outIdx++;
+      }
+
+      inIdx++;
+    }
+
+    out[outIdx] = '\0';
+    *outLen     = outIdx;
+
+    return inIdx;
+  }
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_sprints                  |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function writes a not null terminated string to a
+            buffer.
+*/
+GLOBAL USHORT sprints ( CHAR* buf, CHAR* arg, USHORT len )
+{
+  buf[0] = '\"';
+
+  memcpy ( &buf[1], arg, len );
+
+  buf[len + 1] = '\"';
+  buf[len + 2] = '\0';
+
+  return (len + 2);
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_sprintq                  |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function writes a not null terminated string to a
+            buffer.
+*/
+GLOBAL USHORT sprintq ( CHAR* buf, CHAR* arg, USHORT len )
+{
+  memcpy ( &buf[0], arg, len );
+
+  buf[len] = '\0';
+
+  return (len);
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_hexToIntGsm              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the "HEX" character set to the ACI internal GSM
+            character set.
+*/
+GLOBAL void utl_hexToGsm ( UBYTE*           in,
+                           USHORT           inLen,
+                           UBYTE*           out,
+                           USHORT*          outLen,
+                           T_ACI_GSM_ALPHA  gsm,
+                           T_ACI_CSCS_ALPHA alphabet )
+{
+  SHORT  val    = 0;
+  UBYTE  digit;
+  USHORT inIdx  = 0;
+  USHORT outIdx = 0;
+  SHORT  base   = 0x10;
+
+  while ( inIdx < inLen )
+  {
+    if ( in[inIdx] >= 0x30 AND in[inIdx] <= 0x39 )        /* '0' ... '9' */
+    {
+      digit = in[inIdx] - 0x30;                           /* ->0 ... 9  */
+    }
+    else if ( in[inIdx] >= 0x61 AND in[inIdx] <= 0x66 )   /* 'a' ... 'f' */
+    {
+      digit = in[inIdx] - 0x61 + 0x0A;                    /* ->0x0a...0x0f */
+    }
+    else if ( in[inIdx] >= 0x41 AND in[inIdx] <= 0x46 )   /* 'A' ... 'F' */
+    {
+      digit = in[inIdx] - 0x41 + 0x0A;                    /* ->0x0a...0x0f */
+    }
+    else
+    {
+      digit = 0xFF;
+    }
+
+    if ( digit NEQ 0xFF )  /* skip invalid digit */
+    {
+      if ( base EQ 0x10 )
+      {
+        val = digit << 4;
+      }
+      else
+      {
+        val |= digit;
+
+        if ( alphabet EQ CSCS_ALPHA_7_Bit AND !( val & 0x80 ) )
+        {
+          if ( gsm EQ GSM_ALPHA_Int )
+          {
+            out[outIdx++] = ( CHAR ) val | 0x80;
+          }
+          else
+          {
+            out[outIdx++] = ( CHAR ) val;
+          }
+        }
+        else if ( alphabet NEQ CSCS_ALPHA_7_Bit )
+        {
+          out[outIdx++] = ( CHAR ) val;
+        }
+      }
+
+      base ^= 0x10;
+    }
+
+    inIdx++;
+  }
+
+  if ( gsm EQ GSM_ALPHA_Int )
+    out[outIdx] = '\0';
+
+  *outLen = outIdx;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_ucs2ToGsm              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the "UCS2" character set to the ACI internal GSM
+            character set.
+*/
+GLOBAL void utl_ucs2ToGsm ( UBYTE*           in,
+                           USHORT           inLen,
+                           UBYTE*           out,
+                           USHORT*          outLen,
+                           T_ACI_GSM_ALPHA  gsm,
+                           T_ACI_CSCS_ALPHA alphabet )
+{
+  int i, j;
+  UBYTE val;
+  USHORT len;
+  UBYTE tmpIn[2];  /* store temporary two chars (HEX conversion) */
+  UBYTE tmpInIdx;  /* holds a temporary index for two chars (HEX conversion)*/
+  UBYTE digit;     /* holds a digit (HEX conversion) */
+  SHORT tmpVal;    /* hold a temporary value (HEX conversion) */
+  UBYTE tmpOut; /* the HEX output (HEX conversion) */ 
+  SHORT  base   = 0x10;
+  USHORT outIdx = 0;
+  UBYTE tmpInLen = 2; 
+  
+  /* TRACE_FUNCTION(" utl_ucs2ToGsm() "); */
+  
+  len = inLen/4;
+  
+  for (i=0;i<len;i++)
+  {
+    /* check if this is a UCS2 character in 00xy format */
+    if ( ( in[i*4] EQ '0' ) AND ( in[i*4+1] EQ '0' )  ) 
+    {
+      /* convert the next two character to HEX */
+      tmpIn[0] = in[i*4+2];
+      tmpIn[1] = in[i*4+3];
+
+      tmpVal = tmpOut = val = 0;
+      
+      /* convert the two characters into the real hexadecimal ASCII value */
+      for( tmpInIdx=0; tmpInIdx<2; tmpInIdx++ )
+      {
+        if ( tmpIn[tmpInIdx] >= '0' AND tmpIn[tmpInIdx] <= '9' )
+        {
+          digit = tmpIn[tmpInIdx] - '0';
+        }
+        else if ( tmpIn[tmpInIdx] >= 'a' AND tmpIn[tmpInIdx] <= 'f' )
+        {
+          digit = tmpIn[tmpInIdx] - 'a' + 0x0A;
+        }
+        else if ( tmpIn[tmpInIdx] >= 'A' AND tmpIn[tmpInIdx] <= 'F' )
+        {
+          digit = tmpIn[tmpInIdx] - 'A' + 0x0A;
+        }
+        else
+        {
+          digit = 0xFF;
+        }
+        
+        if ( digit NEQ 0xFF )
+        {
+          if ( base EQ 0x10 )
+          {
+            tmpVal = digit * 0x10;
+          }
+          else
+          {
+            tmpVal += digit;
+            tmpOut = (UBYTE) tmpVal;
+          }
+          
+          base ^= 0x10;
+        }
+      }      
+      
+      /* convert the hexadecimal ASCII value to GSM */
+      if (!(tmpOut & 0x80))  
+      {
+        if ( tmpOut EQ ( gsmToAsciiTable[tmpOut])) /* ASCII and GSM are identical */
+        {
+          val = tmpOut;
+        }
+        else /* find match in the table and copy index of match */
+        {
+          for (j=0; j<128; j++)
+          {
+            if (tmpOut EQ gsmToAsciiTable[j])
+            {
+              val = (UBYTE)j;
+              break;
+            }
+          }
+        }      
+      }
+      else /* find match in the table and copy index of match */
+      {
+        for (j=0; j<128; j++)
+        {
+          if (tmpOut EQ gsmToAsciiTable[j])
+          {
+            val = (UBYTE)j;
+            break;
+          }
+        }
+      }
+      
+      /* if necessary, cut the GSM value to 7bit */
+      if ( alphabet EQ CSCS_ALPHA_7_Bit AND !( val & 0x80 ) )
+      {
+        if ( gsm EQ GSM_ALPHA_Int )
+        {
+          out[outIdx++] = val | 0x80; 
+        }
+        else
+        {
+          out[outIdx++] = val;
+        }
+      }
+      else
+      {
+        out[outIdx++] = val;
+      }
+    }
+    
+    else  /* unknown char, skip it */
+    {
+      /* TRACE_EVENT("UCS2 MISMATCH: Unknown UCS2 entry, character skipped!"); */
+      /* out[outIdx++] = '?'; */
+    }
+  }
+  
+  if ( gsm EQ GSM_ALPHA_Int )
+  {
+    out[outIdx] = '\0';
+  }
+  
+  /* set the outlength */
+  *outLen = outIdx;
+  
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_hexFromGsm               |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the ACI internal GSM character set to the "HEX"
+            character set.
+*/
+GLOBAL USHORT utl_hexFromGsm ( UBYTE*           in,
+                             USHORT           inLen,
+                             UBYTE*           out,
+                             USHORT           maxOutLen,
+                             USHORT*          outLen,
+                             T_ACI_GSM_ALPHA  gsm,
+                             T_ACI_CSCS_ALPHA alphabet )
+{
+  USHORT inIdx  = 0;
+  USHORT outIdx = 0;
+
+  while ( inIdx < inLen AND outIdx < maxOutLen - 2 )
+  {
+      if ( alphabet NEQ CSCS_ALPHA_7_Bit OR
+         ( gsm EQ GSM_ALPHA_Def AND !( in[inIdx] & 0x80 ) )  OR
+         ( gsm EQ GSM_ALPHA_Int AND  ( in[inIdx] & 0x80 ) ) )
+    {
+      out[outIdx++] = hexVal[ in[inIdx] >> 4    ];
+      out[outIdx++] = hexVal[ in[inIdx] &  0x0F ];
+    }
+
+    inIdx++;
+  }
+
+  out[outIdx] = '\0';
+  *outLen     = outIdx;
+  
+  return inIdx;
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_ucs2FromGsm              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the ACI internal GSM character set to the "UCS2"
+            character set.
+*/
+LOCAL USHORT utl_ucs2FromGsm (UBYTE*           in,
+                              USHORT           inLen,
+                              UBYTE*           out,
+                              USHORT           maxOutLen,
+                              USHORT*          outLen,
+                              T_ACI_GSM_ALPHA  gsm,
+                              T_ACI_CSCS_ALPHA alphabet )
+{
+  USHORT inIdx  = 0;
+  USHORT outIdx = 0;
+
+  while ( inIdx < inLen AND outIdx < maxOutLen - 4 )
+  {
+    if ( alphabet NEQ CSCS_ALPHA_7_Bit OR
+       ( gsm EQ GSM_ALPHA_Def AND !( in[inIdx] & 0x80 ) )     OR
+       ( gsm EQ GSM_ALPHA_Int AND  ( in[inIdx] & 0x80 ) ) )
+    {
+      /* Insert two leading Os, convert GSM to ASCII and print out as HEX  */
+      out[outIdx++] = '0';
+      out[outIdx++] = '0';
+      out[outIdx++] = hexVal[ gsmToAsciiTable[in[inIdx]] >> 4    ];
+      out[outIdx++] = hexVal[ gsmToAsciiTable[in[inIdx]] &  0x0F ];
+    }
+
+    inIdx++;
+  }
+
+  out[outIdx] = '\0';
+  *outLen     = outIdx;
+  
+  return inIdx;
+
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_smDtaToTe                |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the SM data in the format
+            specified in Rec. GSM 07.05, message data parameter
+            <data>, to the format used by the AT Command Interface.
+*/
+GLOBAL void utl_smDtaToTe ( UBYTE*  in,
+                            USHORT  inLen,
+                            UBYTE*  out,
+                            USHORT  maxOutLen,
+                            USHORT* outLen,
+                            UBYTE   fo,
+                            UBYTE   dcs )
+{
+  UBYTE alphabet = cmhSMS_getAlphabetPp ( dcs );
+
+  if ( alphabet EQ CSCS_ALPHA_7_Bit AND
+       (fo & TP_UDHI_MASK) EQ TP_UDHI_WITHOUT_HEADER )
+  {
+    utl_chsetFromGsm ( in, inLen, out, maxOutLen, outLen, GSM_ALPHA_Def );
+  }
+  else if ( alphabet NEQ CSCS_ALPHA_7_Bit OR
+            (fo & TP_UDHI_MASK) EQ TP_UDHI_WITH_HEADER )
+  {
+    utl_hexFromGsm ( in, inLen, out, maxOutLen, outLen, GSM_ALPHA_Def, 
+                     CSCS_ALPHA_8_Bit );
+  }
+  else
+  {
+    *outLen = MINIMUM ( inLen, maxOutLen - 1 );
+    memcpy ( out, in,  *outLen );
+    out[*outLen] = '\0';
+  }
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_smDtaFromTe              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the SM data in the format used
+            by the AT Command Interface to the format specified in
+            Rec. GSM 07.05, message data parameter <data>.
+*/
+GLOBAL void utl_smDtaFromTe ( UBYTE*  in,
+                              USHORT  inLen,
+                              UBYTE*  out,
+                              USHORT* outLen,
+                              UBYTE   fo,
+                              UBYTE   dcs )
+{
+  UBYTE alphabet = cmhSMS_getAlphabetPp ( dcs );
+
+  if ( alphabet EQ CSCS_ALPHA_7_Bit                AND
+       ( fo & TP_UDHI_MASK ) EQ TP_UDHI_WITHOUT_HEADER )
+  {
+    utl_chsetToGsm ( in, inLen, out, outLen, GSM_ALPHA_Def );
+  }
+  else if ( alphabet NEQ CSCS_ALPHA_7_Bit             OR
+            ( fo & TP_UDHI_MASK ) EQ TP_UDHI_WITH_HEADER )
+  {
+    utl_hexToGsm ( in, inLen, out, outLen, GSM_ALPHA_Def, alphabet );
+  }
+  else
+  {
+    memcpy ( out, in, inLen );
+    *outLen = inLen;
+  }
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_ussdDtaFromTe            |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the USSD data in the format used
+            by the AT Command Interface to the format specified in
+            Rec. GSM 07.07.
+*/
+GLOBAL void utl_ussdDtaFromTe ( UBYTE*  in,
+                                USHORT  inLen,
+                                UBYTE*  out,
+                                USHORT* outLen,
+                                UBYTE   dcs )
+{
+  UBYTE alphabet = cmhSMS_getAlphabetCb ( dcs );
+
+  if ( alphabet EQ CSCS_ALPHA_7_Bit )
+  {
+    utl_chsetToGsm ( in, inLen, out, outLen, GSM_ALPHA_Def );
+  }
+  else
+  {
+    utl_hexToGsm ( in, inLen, out, outLen, GSM_ALPHA_Def, alphabet );
+  }
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_ussdDtaToTe              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the USSD data in the format
+            specified in Rec. GSM 07.07 to the format used
+            by the AT Command Interface.
+*/
+
+GLOBAL USHORT utl_ussdDtaToTe ( UBYTE*  in,
+                              USHORT  inLen,
+                              UBYTE*  out,
+                              USHORT  maxOutLen,
+                              USHORT* outLen,
+                              UBYTE   dcs )
+{
+  UBYTE alphabet = cmhSMS_getAlphabetCb ( dcs );
+
+  if ( alphabet EQ CSCS_ALPHA_7_Bit )
+  {
+    return utl_chsetFromGsm ( in, inLen, out, maxOutLen, outLen, GSM_ALPHA_Def );
+  }
+  else
+  {
+    return utl_hexFromGsm ( in, inLen, out, maxOutLen, outLen, GSM_ALPHA_Def, alphabet );
+  }
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_cbmDtaToTe               |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the CBM data in the format
+            specified in Rec. GSM 07.05, message data parameter
+            <data>, to the format used by the AT Command Interface.
+*/
+GLOBAL void utl_cbmDtaToTe ( UBYTE*  in,
+                             USHORT  inLen,
+                             UBYTE*  out,
+                             USHORT  maxOutLen,
+                             USHORT* outLen,
+                             UBYTE   fo,
+                             UBYTE   dcs )
+{
+  UBYTE alphabet = cmhSMS_getAlphabetCb ( dcs );
+
+  if ( alphabet EQ CSCS_ALPHA_7_Bit                AND
+       ( fo & TP_UDHI_MASK ) EQ TP_UDHI_WITHOUT_HEADER )
+  {
+    utl_chsetFromGsm ( in, inLen, out, maxOutLen, outLen, GSM_ALPHA_Def );
+  }
+  else if ( alphabet NEQ CSCS_ALPHA_7_Bit             OR
+            ( fo & TP_UDHI_MASK ) EQ TP_UDHI_WITH_HEADER )
+  {
+    utl_hexFromGsm ( in, inLen, out, maxOutLen, outLen, GSM_ALPHA_Def, alphabet );
+  }
+  else
+  {
+    *outLen = MINIMUM ( inLen, maxOutLen );
+    memcpy ( out, in, *outLen );
+  }
+}
+#endif
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_cvtGsmIra                |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts the characters of a string from
+            the ACI internal GSM character set to the IRA character
+            set or vice versa.
+*/
+GLOBAL BOOL utl_cvtGsmIra ( UBYTE*         in,
+                            USHORT         inLen,
+                            UBYTE*         out,
+                            USHORT         outLen,
+                            T_ACI_CSCS_DIR dir )
+{
+  USHORT inIdx  = 0;
+  USHORT outIdx = 0;
+  USHORT tblIdx;
+  UBYTE  cvtdVal;
+
+  TRACE_FUNCTION("utl_cvtGsmIra()");
+
+
+  if ( inLen > outLen )
+  {
+    return ( FALSE );
+  }
+
+  if ( dir EQ CSCS_DIR_GsmToIra )
+  {
+    while ( inIdx < inLen )
+    {
+      tblIdx = 0;
+
+      while ( tblIdx <= 0xFF                                             AND
+              chset[CSCS_CHSET_Ira][tblIdx] NEQ (( UBYTE )in[inIdx] | 0x80 ))
+        tblIdx++;
+
+      if ( tblIdx <= 0xFF )
+      {
+        out[outIdx] = ( UBYTE )tblIdx;
+        outIdx++;
+      }
+      else
+      {
+        return ( FALSE );
+      }
+
+      inIdx++;
+    }
+  }
+  else if ( dir EQ CSCS_DIR_IraToGsm )
+  {
+    for ( inIdx = 0; inIdx < inLen; inIdx++ )
+    {
+      cvtdVal = chset[CSCS_CHSET_Ira][( UBYTE ) in[inIdx]];
+
+      if ( cvtdVal NEQ 0x00 )
+      {
+        out[outIdx] = ( CHAR ) cvtdVal & 0x7F;
+        outIdx++;
+      }
+      else
+      {
+        return ( FALSE );
+      }
+    }
+
+  }
+  else
+  {
+    return ( FALSE );
+  }
+
+  return ( TRUE );
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_binToHex                 |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts a binary string of bytes with a
+            given length into an null terminated ASCII string
+            representation.
+*/
+GLOBAL void utl_binToHex (UBYTE*         in,
+                          SHORT          inLen,
+                          CHAR*          out )
+{
+  SHORT idx = 0;
+  UBYTE hNib;
+  UBYTE lNib;
+
+  while( idx < inLen )
+  {
+    hNib = (in[idx]&0xF0)>>4;
+
+    if( hNib > 9 ) *out = (hNib-10)+0x41;
+    else           *out = hNib + 0x30;
+
+    out++;
+
+    lNib = in[idx]&0x0F;
+
+    if( lNib > 9 ) *out = (lNib-10)+0x41;
+    else           *out = lNib + 0x30;
+
+    out++;
+    idx++;
+  }
+  *out = 0x0;
+}
+
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM              MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : utl_HexStrToBin              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function converts a null terminated string of HEX
+            values in a binary buffer.
+            RETURN: byte count.
+*/
+GLOBAL USHORT utl_HexStrToBin (UBYTE         *in,
+                               USHORT         inLen,
+                               UBYTE         *out,
+                               USHORT         outLen)
+{
+  USHORT inIdx = 0;
+  USHORT outIdx = 0;
+  UBYTE value;
+  BOOL  hNib = TRUE;
+
+  while ((inIdx < inLen) AND (outIdx < outLen))
+  {
+    if ((in[inIdx] >= 0x30) AND (in[inIdx] <= 0x39))
+    {
+      value = in[inIdx] - 0x30;
+    }
+    else if ((in[inIdx] >= 0x61) AND (in[inIdx] <= 0x66))
+    {
+      value = in[inIdx] - 0x61 + 0x0A;
+    }
+    else if ((in[inIdx] >= 0x41) AND (in[inIdx] <= 0x46))
+    {
+      value = in[inIdx] - 0x41 + 0x0A;
+    }
+    else
+    {
+      return (0);
+    }
+
+    if (hNib)
+    {
+      out[outIdx] = (value << 0x04) & 0xF0;
+      hNib = FALSE;
+    }
+    else
+    {
+      out[outIdx] |= value & 0x0F;
+      hNib = TRUE;
+      outIdx++;
+    }
+    inIdx++;
+  }
+
+  return (outIdx);
+}
+#endif
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : trace_cmd_line               |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function trace the command line and check
+            this string for % character
+*/
+
+GLOBAL void trace_cmd_line (char *prefix, char *output, UBYTE srcId, USHORT output_len)
+{
+  char trcBuf[80];
+  int dst_i;
+
+  dst_i = sprintf (trcBuf, "%s(Src %d)[lth %d]", (prefix) ? prefix : "", srcId, output_len);
+
+  strncpy(&trcBuf[dst_i], output, 79-dst_i);
+  trcBuf[79] = '\0';
+
+  if (trcBuf[76])
+  {
+    trcBuf[76] = trcBuf[77] = trcBuf[78] = '.';  /* add trailing "..." if string is >=76 */
+  }
+
+  /* Send the trace if either EVENT or CLASS8 is turned on */
+  TRACE_USER_CLASS_P1(TC_EVENT|TC_USER8, "%s",trcBuf);
+}
+#endif
+
+
+#ifdef FF_ATI
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : ACI_UTIL                     |
+| STATE   : code             ROUTINE : trace_cmd_state              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function trace the command line state
+*/
+
+GLOBAL void trace_cmd_state (UBYTE            srcId, 
+                             T_ATI_CMD_STATE  old_state, 
+                             T_ATI_CMD_STATE  new_state)
+{
+  char trcBuf[50];
+
+  if (old_state EQ new_state)
+  {
+    return;
+  }
+
+  sprintf (trcBuf, "(Src %d) cmd_state: ", srcId );
+
+  switch (old_state)
+  {
+    case (CMD_IDLE):
+      strcat (trcBuf, "CMD_IDLE -> ");
+      break;
+    case (CMD_TYPING):
+      strcat (trcBuf, "CMD_TYPING -> ");
+      break;
+    case (CMD_RUNNING):
+      strcat (trcBuf, "CMD_RUNNING -> ");
+      break;
+    default:
+      strcat (trcBuf, "CMD_UNKNOWN ! ");
+  }
+  
+  switch (new_state)
+  {
+    case (CMD_IDLE):
+      strcat (trcBuf, "CMD_IDLE");
+      break;
+    case (CMD_TYPING):
+      strcat (trcBuf, "CMD_TYPING");
+      break;
+    case (CMD_RUNNING):
+      strcat (trcBuf, "CMD_RUNNING");
+      break;
+    default:
+      strcat (trcBuf, "CMD_UNKNOWN !");
+  }
+
+  TRACE_EVENT_P1("%s",trcBuf);
+}
+#endif
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_CMD            |
+| STATE   : code                        ROUTINE : toa_merge          |
++--------------------------------------------------------------------+
+
+  PURPOSE : builds type of address octet from TOA structure
+
+*/
+
+GLOBAL UBYTE toa_merge (T_ACI_TOA type)
+{
+
+return   ((type.ton << 4) & 0xF0) 
+       | ( type.npi       & 0x0F)
+       | 0x80;
+}
+
+
+
+#ifdef GPRS
+/*
+  +-----------------------------------------------------------------------------
+  | Function    : utl_create_pco
+  +-----------------------------------------------------------------------------
+  | Description : The function create_pco() creates protocol configuration
+  |               options needed to activate a PDPcontext.
+  |
+  | Parameters  : buffer      - buffer to write the PCOs
+  |               length      - on call: buffer size; on return: written bytes
+  |               content     - mask to specify the PCO content
+  |               config_prot - used configuration protocol (currently PPP)
+  |               auth_prot   - authentication protocol (currently PAP)
+  |               user_name   - string with the user name
+  |               password    - string with the password
+  |               dns1        - requested primary DNS address
+  |               dns2        - requested secondary DNS address
+  |
+  | Return      :  0 - operation successful
+  |               -1 - operation fails
+  |
+  +-----------------------------------------------------------------------------
+*/
+GLOBAL int utl_create_pco (UBYTE*  buffer,
+                           USHORT* length,
+                           ULONG   content,
+                           UBYTE   config_prot,
+                           USHORT  auth_prot,
+                           UBYTE*  user_name,
+                           UBYTE*  password,
+                           ULONG   dns1,
+                           ULONG   dns2)
+{
+  USHORT  size;
+  USHORT  temp_len;
+  USHORT  len_user;
+  USHORT  len_pwd;
+  USHORT  written;
+  UBYTE*  pos;
+  UBYTE*  len_pos1;
+  UBYTE*  len_pos2;
+
+  TRACE_FUNCTION( "create_pco" );
+
+  /*
+   * store buffer size
+   */
+  size = *length;
+  /*
+   * initialize values
+   */
+  *length = 0;
+  written = 0;
+  pos     = buffer;
+  /*
+   * calculate if requested content is writeable
+   */
+  temp_len = 1;
+  if(content & ACI_PCO_CONTENTMASK_AUTH)
+  {
+    len_user = strlen((char*)user_name);
+    len_pwd  = strlen((char*)password);
+    temp_len+= ACI_PCO_PAP_OVERHEAD + len_user + len_pwd;
+  }
+  if((content & ACI_PCO_CONTENTMASK_DNS1) ||
+     (content & ACI_PCO_CONTENTMASK_DNS2))
+  {
+    temp_len+= ACI_PCO_IPCP_OVERHEAD;
+    if(content & ACI_PCO_CONTENTMASK_DNS1)
+      temp_len+= ACI_PCO_IPCP_LENGTH_DNS1;
+    if(content & ACI_PCO_CONTENTMASK_DNS2)
+      temp_len+= ACI_PCO_IPCP_LENGTH_DNS2;
+  }
+  TRACE_EVENT_P2("temp_len=%d size=%d", temp_len, size);
+  if(temp_len > size)
+  {
+    /*
+     * content is to long
+     */
+    return -1;
+  }
+  /*
+   * set configuration protocol identifier
+   */
+  *pos = 0x80 | config_prot;
+  pos++;
+  written++;
+
+  /*
+   * authentication
+   */
+  if(content & ACI_PCO_CONTENTMASK_AUTH)
+  {
+    /*
+     * set authentication protocol
+     */
+    *pos = (UBYTE)((auth_prot >> 8) & 0x00ff);
+    pos++;
+    written++;
+    *pos = (UBYTE)(auth_prot        & 0x00ff);
+    pos++;
+    written++;
+    /*
+     * store first length position
+     */
+    len_pos1 = pos;
+    pos++;
+    written++;
+    /*
+     * Code field
+     */
+    *pos = ACI_PCO_PAP_AUTH_REQ;
+    pos++;
+    written++;
+    /*
+     * Identifier field (just some value)
+     */
+    *pos = 0x01;
+    pos++;
+    written++;
+    /*
+     * Length field (store length position)
+     */
+    *pos = 0x00;
+    pos++;
+    written++;
+    len_pos2 = pos;
+    pos++;
+    written++;
+    /*
+     * User Name Length field
+     */
+    *pos = (UBYTE)(/*lint -e(644) */len_user & 0x00ff);
+    pos++;
+    written++;
+    /*
+     * User Name field
+     */
+    memcpy(pos, user_name, len_user);
+    pos    += len_user;
+    written+= len_user;
+    /*
+     * Password Length field
+     */
+    *pos = (UBYTE)(/*lint -e(644) */len_pwd & 0x00ff);  
+    pos++;
+    written++;
+    /*
+     * Password field
+     */
+    memcpy(pos, password, len_pwd);
+    pos    += len_pwd;
+    written+= len_pwd;
+    /*
+     * fill length fields
+     */
+    *len_pos1 = (UBYTE)(pos - len_pos1 - 1);
+    *len_pos2 = *len_pos1;
+  }
+  /*
+   * DNS addresses
+   */
+  if((content & ACI_PCO_CONTENTMASK_DNS1) ||
+     (content & ACI_PCO_CONTENTMASK_DNS2))
+  {
+    /*
+     * set IPCP protocol
+     */
+    *pos = ACI_PCO_IPCP_PROT_MSB;
+    pos++;
+    written++;
+    *pos = ACI_PCO_IPCP_PROT_LSB;
+    pos++;
+    written++;
+    /*
+     * store first length position
+     */
+    len_pos1 = pos;
+    pos++;
+    written++;
+    /*
+     * Code field
+     */
+    *pos = ACI_PCO_IPCP_CONF_REQ;
+    pos++;
+    written++;
+    /*
+     * Identifier field (just some value)
+     */
+    *pos = 0x01;
+    pos++;
+    written++;
+    /*
+     * Length field (store length position)
+     */
+    *pos = 0x00;
+    pos++;
+    written++;
+    len_pos2 = pos;
+    pos++;
+    written++;
+    /*
+     * primary DNS address
+     */
+    if(content & ACI_PCO_CONTENTMASK_DNS1)
+    {
+      /*
+       * Type field
+       */
+      *pos = ACI_PCO_IPCP_TYPE_DNS1;
+      pos++;
+      written++;
+      /*
+       * Length field
+       */
+      *pos = ACI_PCO_IPCP_LENGTH_DNS1;
+      pos++;
+      written++;
+      /*
+       * primary DNS address
+       */
+      *pos = (UBYTE)((dns1 >> 24) & 0x000000ff);
+      pos++;
+      written++;
+      *pos = (UBYTE)((dns1 >> 16) & 0x000000ff);
+      pos++;
+      written++;
+      *pos = (UBYTE)((dns1 >>  8) & 0x000000ff);
+      pos++;
+      written++;
+      *pos = (UBYTE)(dns1         & 0x000000ff);
+      pos++;
+      written++;
+    }
+    /*
+     * secondary DNS address
+     */
+    if(content & ACI_PCO_CONTENTMASK_DNS2)
+    {
+      /*
+       * Type field
+       */
+      *pos = ACI_PCO_IPCP_TYPE_DNS2;
+      pos++;
+      written++;
+      /*
+       * Length field
+       */
+      *pos = ACI_PCO_IPCP_LENGTH_DNS2;
+      pos++;
+      written++;
+      /*
+       * primary DNS address
+       */
+      *pos = (UBYTE)((dns2 >> 24) & 0x000000ff);
+      pos++;
+      written++;
+      *pos = (UBYTE)((dns2 >> 16) & 0x000000ff);
+      pos++;
+      written++;
+      *pos = (UBYTE)((dns2 >>  8) & 0x000000ff);
+      pos++;
+      written++;
+      *pos = (UBYTE)(dns2         & 0x000000ff);
+      pos++;
+      written++;
+    }
+    /*
+     * fill length fields
+     */
+    *len_pos1 = (UBYTE)(pos - len_pos1 - 1);
+    *len_pos2 = *len_pos1;
+  }
+  /*
+   * pass written bytes to caller
+   */
+  *length = written;
+  /*
+   * return result
+   */
+  return 0;
+} /* utl_create_pco() */
+
+
+
+/*
+  +-----------------------------------------------------------------------------
+  | Function    : utl_analyze_pco
+  +-----------------------------------------------------------------------------
+  | Description : The function analyze_pco() analyzes the response protocol
+  |               configuration from the network
+  |
+  | Parameters  : buffer  - buffer with the response PCOs
+  |               length  - length of PCOs
+  |               dns1    - returns primary DNS address
+  |               dns2    - returns secondary DNS address
+  |               gateway - returns Gateway address
+  |
+  | Return      :  0 - operation successful
+  |               -1 - operation fails
+  |
+  +-----------------------------------------------------------------------------
+*/
+GLOBAL int utl_analyze_pco (UBYTE* buffer,
+                            USHORT length,
+                            ULONG* dns1,
+                            ULONG* dns2,
+                            ULONG* gateway)
+{
+  UBYTE*  pos;
+  USHORT  pos_len;
+  USHORT  packet_len;
+  USHORT  start_pos;
+  USHORT  dist_to_next;
+  UBYTE   type_len;
+
+  TRACE_FUNCTION( "utl_analyze_pco" );
+
+  /*
+   * initialize values
+   */
+  pos      = buffer;
+  pos_len  = 0;
+  *dns1    = 0;
+  *dns2    = 0;
+  *gateway = 0;
+  /*
+   * check configuration protocol
+   */
+  if( (length <= pos_len) ||
+      !(*pos & 0x80) )
+  {
+    return -1;
+  }
+
+#if 0
+  /* Table 10.5.154/3GPP TS 24.008 states:
+       "All other values are interpreded as PPP in this version of the protocol.
+     so the next check should not be performed
+   */
+  if((*pos & 0x07) NEQ ACI_PCO_CONFIG_PROT_PPP)
+  {
+    /*
+     * configuration protocol is not PPP
+     */
+    return 0;
+  }
+#endif
+
+  pos++;
+  pos_len++;
+  
+  /*
+   * search for IPCP packet
+   */
+  while(length > (pos_len + ACI_PCO_IPCP_OVERHEAD))
+  {
+    /*
+     * initialize distance to next packet
+     */
+    dist_to_next = *(pos + 2) + 3;
+    /*
+     * check for IPCP packet
+     */
+    if((*pos       EQ ACI_PCO_IPCP_PROT_MSB) &&
+       (*(pos + 1) EQ ACI_PCO_IPCP_PROT_LSB))
+    {
+      /*
+       * check for correct length field
+       */
+      pos         += 2;
+      pos_len     += 2;
+      dist_to_next-= 2;
+      packet_len   = *(pos + 3);
+      packet_len   = packet_len << 8;
+      packet_len  += *(pos + 4);
+      if((packet_len EQ *pos) &&
+         (length > (pos_len + packet_len)))
+      {
+        pos++;
+        pos_len++;
+        dist_to_next--;
+        /*
+         * check of code field
+         */
+        start_pos = pos_len;
+        switch(*pos)
+        {
+          case ACI_PCO_IPCP_CONF_REQ:
+            /*
+             * search for Gateway address
+             */
+            pos    += 4;
+            pos_len+= 4;
+            while((pos_len + 1 - start_pos) < packet_len)
+            {
+              type_len = *(pos + 1);
+              if((*pos     EQ ACI_PCO_IPCP_TYPE_IP) &&
+                 (type_len EQ ACI_PCO_IPCP_LENGTH_IP) &&
+                 ((pos_len +
+                   ACI_PCO_IPCP_LENGTH_IP -
+                   start_pos) <= packet_len))
+              {
+                *gateway = *(pos + 2);
+                *gateway = ((*gateway) << 8);
+                *gateway+= *(pos + 3);
+                *gateway = ((*gateway) << 8);
+                *gateway+= *(pos + 4);
+                *gateway = ((*gateway) << 8);
+                *gateway+= *(pos + 5);
+              }
+              pos    += type_len;
+              pos_len+= type_len;
+            }
+            if((pos_len - start_pos) <= packet_len)
+            {
+              dist_to_next = packet_len + start_pos - pos_len;
+            }
+            else
+            {
+              dist_to_next = 0;
+              pos         -= (pos_len - start_pos - packet_len);
+              pos_len     -= (pos_len - start_pos - packet_len);
+            }
+            break;
+
+          case ACI_PCO_IPCP_CONF_ACK:
+          case ACI_PCO_IPCP_CONF_NAK:
+            /*
+             * search for DNS addresses
+             */
+            pos    += 4;
+            pos_len+= 4;
+            while((pos_len + 1 - start_pos) < packet_len)
+            {
+              type_len = *(pos + 1);
+              if((*pos     EQ ACI_PCO_IPCP_TYPE_DNS1) &&
+                 (type_len EQ ACI_PCO_IPCP_LENGTH_DNS1) &&
+                 ((pos_len +
+                   ACI_PCO_IPCP_LENGTH_DNS1 -
+                   start_pos) <= packet_len))
+              {
+                *dns1 = *(pos + 2);
+                *dns1 = ((*dns1) << 8);
+                *dns1+= *(pos + 3);
+                *dns1 = ((*dns1) << 8);
+                *dns1+= *(pos + 4);
+                *dns1 = ((*dns1) << 8);
+                *dns1+= *(pos + 5);
+              }
+              else if((*pos     EQ ACI_PCO_IPCP_TYPE_DNS2) &&
+                      (type_len EQ ACI_PCO_IPCP_LENGTH_DNS2) &&
+                      ((pos_len +
+                        ACI_PCO_IPCP_LENGTH_DNS2 -
+                        start_pos) <= packet_len))
+              {
+                *dns2 = *(pos + 2);
+                *dns2 = ((*dns2) << 8);
+                *dns2+= *(pos + 3);
+                *dns2 = ((*dns2) << 8);
+                *dns2+= *(pos + 4);
+                *dns2 = ((*dns2) << 8);
+                *dns2+= *(pos + 5);
+              }
+              pos    += type_len;
+              pos_len+= type_len;
+            }
+            if((pos_len - start_pos) <= packet_len)
+            {
+              dist_to_next = packet_len + start_pos - pos_len;
+            }
+            else
+            {
+              dist_to_next = 0;
+              pos         -= (pos_len - start_pos - packet_len);
+              pos_len     -= (pos_len - start_pos - packet_len);
+            }
+            break;
+        }
+      }
+    }
+    /*
+     * go to next packet
+     */
+    pos_len+= dist_to_next;
+    pos    += dist_to_next;
+  }
+  /*
+   * return
+   */
+  return 0;
+} /* utl_analyze_pco() */
+
+
+
+
+GLOBAL int utl_strcasecmp (const char *s1, const char *s2)
+{
+  char c1, c2;
+  int i;
+
+  int len1 = (s1 == NULL) ? 0 : strlen(s1);
+  int len2 = (s2 == NULL) ? 0 : strlen(s2);
+
+  if (len1 > len2) 
+  {
+    return (1);
+  }
+  if(len1 < len2) 
+  {
+    return (-1);
+  }
+  for (i = 0; i < len1; i++)
+  {
+    c1 = s1[i];
+    c2 = s2[i];
+    if (c1 == c2)
+    {
+      continue ;
+    }
+    if (c1 >= 'a' AND c1 <= 'z')
+    {
+      c1 = c1 - ('a'-'A');
+    }
+    if (c2 >= 'a' AND c2 <= 'z')
+    {
+      c2 = c2 - ('a'-'A');
+    }
+    if (c1 != c2)
+    {
+      return (1);
+    }
+  }
+  return (0);
+}
+
+
+#endif /* GPRS */
+
+
+
+#if defined (FF_ATI) || defined (FF_BAT)
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : ACI_UTIL                 |
+| STATE   : code                  ROUTINE : rci_display_USSD         |
++--------------------------------------------------------------------+
+
+  PURPOSE : used by rCI_PlusCUSD and utl_cb_percentKSIR
+*/
+GLOBAL void rci_display_USSD (UBYTE            srcId,
+                              T_ACI_CUSD_MOD   mode,
+                              UBYTE            *ussd_str,
+                              UBYTE            ussd_len,
+                              BOOL             cvtStr,
+                              SHORT            dcs )
+{
+  SHORT  pos = 0;
+  USHORT chunksize;
+  USHORT lenCvtdStr;
+  CHAR sa[80];
+
+
+  TRACE_FUNCTION("rci_display_USSD()");
+
+  pos = sprintf(sa,"+CUSD: ");
+
+  if (mode NEQ CUSD_MOD_NotPresent)
+  {
+    pos += sprintf(sa+pos,"%d,",mode);
+  }
+  else
+    pos += sprintf(sa+pos,",");
+
+  if(ussd_str NEQ NULL)
+  {
+    pos += sprintf(sa+pos,"\"");    /* beginning double quote */
+    while (ussd_len)
+    {
+      if( cvtStr EQ CONVERT_STRING )
+      {
+        chunksize = utl_ussdDtaToTe( ussd_str,
+                         (USHORT)ussd_len,
+                         (UBYTE*)(sa + pos),
+                         sizeof(sa)-pos,
+                         &lenCvtdStr,
+                         (UBYTE)dcs );
+
+        pos += lenCvtdStr;
+      }
+      else
+      {
+        /*
+        *   How much space do we have left in the output array?
+        */
+        chunksize=(sizeof(sa)-pos)-1;
+
+        if (ussd_len<chunksize)
+        {
+          /*
+          *   Remaining data fits within the output array.
+          */
+          chunksize=ussd_len;
+        }
+        else if (chunksize>3)
+        {
+          /*
+          *   If the remaining data will not fit in the output
+          *   array, and we have more than 3 bytes available (which
+          *   we will), make sure that the amount of data output
+          *   divides by 4. This is so we don't split UCS2 characters
+          *   between two lines of output.
+          */
+          chunksize &= ~0x3;
+        }
+
+        memcpy(sa+pos,ussd_str,chunksize);
+        
+        pos += chunksize;
+
+        sa[pos]=0;
+      }
+      ussd_len-=chunksize;
+      ussd_str+=chunksize;
+
+      if (ussd_len OR (sizeof(sa)-pos) < 10)
+      {
+#ifdef _SIMULATION_
+        io_sendMessage(srcId, sa, ATI_NORMAL_OUTPUT);   /* append CR+LF only for testcase */
+#else
+        io_sendMessage(srcId, sa, ATI_ECHO_OUTPUT);     /* normal output a chunk */
+#endif
+        pos=0;
+        memset(sa, 0, 80);
+      }
+    }
+
+    pos+=sprintf(sa+pos,"\",");   /* ending double quote */
+
+    if (dcs EQ ACI_NumParmNotPresent)
+    {
+      /* see 07.07: default is 0 */
+      dcs = 0;
+    }
+
+    pos+=sprintf(sa+pos,"%d",dcs);
+  }
+  
+  ci_remTrailCom(sa, pos);
+  io_sendMessage(srcId, sa, ATI_NORMAL_OUTPUT);
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL void utl_cvtCLIRStat ( UBYTE clirOpt,
+                             UBYTE ssSt,
+                             T_ACI_CLIR_STAT *clirStat )
+{
+  if ( clirOpt EQ KSD_CO_NOT_VALID )
+  {
+    /* SS Status of class - T_ACI_KSD_ST */
+    if ( ssSt EQ KSD_ST_NOT_VALID )
+      *clirStat = CLIR_STAT_Unknown;
+    else if ( ssSt & SSS_P )
+      *clirStat = CLIR_STAT_Permanent;
+    else
+      *clirStat = CLIR_STAT_NotProv;
+  }
+  else
+  {
+    switch ( clirOpt )
+    {
+      case( CLIR_OPT_PERMANENT ):
+        *clirStat = CLIR_STAT_Permanent;
+        break;
+
+      case( CLIR_OPT_TEMPORARY ):
+        *clirStat = CLIR_STAT_RestrictTemp;
+        break;
+
+      case( CLIR_OPT_ALLOWED ):
+        *clirStat = CLIR_STAT_AllowTemp;
+        break;
+
+      default:
+        *clirStat = CLIR_STAT_Unknown;
+        break;
+    }
+  }
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL  void utl_cb_ccbs( UBYTE srcId, T_ACI_KSIR * ksStat )
+{
+  T_ACI_CCBS_SET *CCBS_Setting = NULL;
+
+  T_ACI_CCBS_STAT status;
+  T_basicService basicServ;
+  int i;
+  T_CC_FEAT *ccbs_features;
+
+  TRACE_FUNCTION("utl_cb_ccbs()");
+
+  /* SS Status of CCBS */
+  if (ksStat->ir.rKSCC.ssSt EQ KSD_ST_NOT_VALID)
+    status = CCBS_STAT_NotPresent;
+  else if (!(ksStat->ir.rKSCC.ssSt & SSS_P))
+    status = CCBS_STAT_NotProvisioned;
+  else if (ksStat->ir.rKSCC.ssSt & SSS_A)
+    status = CCBS_STAT_Active;
+  else
+    status = CCBS_STAT_Provisioned;
+
+  ACI_MALLOC(CCBS_Setting, sizeof(T_ACI_CCBS_SET));
+
+  /* CCBS_Setting infos */
+  if (!ksStat->ir.rKSCC.c_ccFeatLst)
+  {
+    TRACE_EVENT("KSD_CMD_CCBS: no feature list");
+
+    if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+    {
+      rCI_PercentCCBS(CCBS_IND_IrgtResult,
+                      status,
+                      CCBS_Setting,
+                      TRUE);
+    }
+#ifdef FF_BAT
+    else /* CMD_MODE_BAT */
+    {
+      rBAT_PercentCCBS(CCBS_IND_IrgtResult,
+                       status,
+                       CCBS_Setting,
+                       TRUE);
+   }
+#endif
+    return;
+  }
+
+  for (i=0; i<ksStat->ir.rKSCC.c_ccFeatLst; i++)
+  {
+    ccbs_features = ksStat->ir.rKSCC.ccFeatLst + i;
+
+    memcpy( CCBS_Setting->number, ccbs_features->num, MAX_B_SUBSCR_NUM_LEN);
+    memcpy( CCBS_Setting->subaddr, ccbs_features->sub, MAX_SUBADDR_LEN);
+
+    CCBS_Setting->type.npi   = ccbs_features->npi NEQ 0xFF 
+                               ? (T_ACI_TOA_NPI)ccbs_features->npi 
+                               : NPI_NotPresent;
+    CCBS_Setting->type.ton   = ccbs_features->ton NEQ 0xFF 
+                               ? (T_ACI_TOA_TON)ccbs_features->ton 
+                               : TON_NotPresent;
+    CCBS_Setting->satype.tos = ccbs_features->tos NEQ 0xFF 
+                               ? (T_ACI_TOS_TOS)ccbs_features->tos 
+                               : TOS_NotPresent;
+    CCBS_Setting->satype.oe  = ccbs_features->oe NEQ 0xFF 
+                               ? (T_ACI_TOS_OE)ccbs_features->oe 
+                               : OE_NotPresent;
+
+    if( ccbs_features->bsTp EQ BS_TELE_SRV )
+    {
+      basicServ.v_teleservice = TRUE;
+      basicServ.v_bearerService = FALSE;
+      basicServ.teleservice = ccbs_features->bsCd;
+    }
+    else /* if( p_servType EQ BS_BEAR_SRV ) */
+    {
+      basicServ.v_bearerService = TRUE;
+      basicServ.v_teleservice = FALSE;
+      basicServ.bearerService = ccbs_features->bsCd;
+    }
+    
+    CCBS_Setting->class_type = cmhSS_GetClass( &basicServ );
+
+    CCBS_Setting->idx = ccbs_features->idx NEQ 0xFF 
+                        ? ccbs_features->idx 
+                        : ACI_NumParmNotPresent;
+    
+    CCBS_Setting->alrtPtn = ALPT_NotPresent;
+    
+    if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+    {
+      rCI_PercentCCBS(CCBS_IND_IrgtResult,
+                      status,
+                      CCBS_Setting,
+                      TRUE);
+    }
+#ifdef FF_BAT
+    else /* CMD_MODE_BAT */
+    {
+      rBAT_PercentCCBS(CCBS_IND_IrgtResult,
+                      status,
+                      CCBS_Setting,
+                      TRUE);
+    }
+#endif
+  }
+
+  ACI_MFREE( CCBS_Setting );
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL void utl_cb_callwaiting( UBYTE srcId, T_ACI_KSIR *ksStat )
+{
+  T_ACI_CLSSTAT   classStat;
+  UBYTE           idx;
+  T_ACI_TOA       type;
+
+  TRACE_FUNCTION("utl_cb_callwaiting()");
+
+  if ( ksStat->ir.rKSCW.opCd NEQ KSD_OP_IRGT )
+    return;
+
+  /* SS Status of class - T_ACI_KSD_ST */
+  if ( ksStat->ir.rKSCW.ssSt EQ KSD_ST_NOT_VALID )
+  {
+    classStat.status = STATUS_NotPresent;
+  }
+  else if ( ksStat->ir.rKSCW.ssSt & KSD_ST_A )
+  {
+    classStat.status = STATUS_Active;
+  }
+  else
+  {
+    classStat.status = STATUS_NotActive;
+  }
+
+  /* init parameter type: */
+  type.npi = NPI_NotPresent;
+  type.ton = TON_NotPresent;
+
+  for( idx = 0; idx < ksStat->ir.rKSCW.c_cwBSGLst; idx++ )
+  {
+    /* type of class */
+    classStat.class_type = cmhSS_GetClassType(ksStat->ir.rKSCW.cwBSGLst[idx].bsTp,
+                                              ksStat->ir.rKSCW.cwBSGLst[idx].bsCd);
+    if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+    {
+    }
+    else /* CMD_MODE_BAT */
+    {
+    }
+    
+    rCI_PlusCCWA(&classStat,"\0", &type, PRES_NOT_PRES, CLASS_NotPresent, NULL);
+  }
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL  void utl_cb_lineidentification( UBYTE srcId, T_ACI_KSIR * ksStat )
+{
+  T_ACI_CLIP_STAT clipStat;
+  T_ACI_CLIR_MOD  clirMode;
+  T_ACI_CLIR_STAT clirStat;
+  T_ACI_COLP_STAT colpStat;
+  T_ACI_COLR_STAT colrStat;
+
+  TRACE_FUNCTION("utl_cb_lineidentification()");
+
+  if ( ksStat->ir.rKSCL.opCd NEQ KSD_OP_IRGT )
+    return;
+
+  switch ( ksStat->ir.rKSCL.ssCd )
+  {
+    case KSD_SS_CLIP:
+     {
+      /* SS Status of class - T_ACI_KSD_ST */
+      if ( ksStat->ir.rKSCL.ssSt EQ KSD_ST_NOT_VALID )
+        clipStat = CLIP_STAT_Unknown;
+      else if ( ksStat->ir.rKSCL.ssSt & SSS_P )
+        clipStat = CLIP_STAT_Prov;
+      else
+        clipStat = CLIP_STAT_NotProv;
+
+      if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+      {
+        rCI_PlusCLIP ( clipStat, NULL, NULL, PRES_NOT_PRES, NULL, NULL, NULL );
+      }
+#ifdef FF_BAT
+      else /* CMD_MODE_BAT */
+      {
+        rBAT_PlusCLIP ( clipStat, NULL, NULL, PRES_NOT_PRES, NULL, NULL, NULL );
+      }
+#endif
+      break;
+    }
+    case KSD_SS_CLIR:
+    {
+      clirMode = ksStat->ir.rKSCL.mode;
+      utl_cvtCLIRStat(ksStat->ir.rKSCL.clirOpt,
+                      ksStat->ir.rKSCL.ssSt,
+                      &clirStat);
+      if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+      {
+        rCI_PlusCLIR (clirMode, clirStat);
+      }
+#ifdef FF_BAT
+      else /* CMD_MODE_BAT */
+      {
+        rBAT_PlusCLIR (clirMode, clirStat);
+      }
+#endif
+      break;
+    } 
+    case KSD_SS_COLP:
+    {
+      /* SS Status of class - T_ACI_KSD_ST */
+      if ( ksStat->ir.rKSCL.ssSt EQ KSD_ST_NOT_VALID )
+        colpStat = COLP_STAT_Unknown;
+      else if ( ksStat->ir.rKSCL.ssSt & SSS_P )
+        colpStat = COLP_STAT_Prov;
+      else
+        colpStat = COLP_STAT_NotProv;
+
+      if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+      {
+        rCI_PlusCOLP ( colpStat, NULL, NULL, NULL, NULL, NULL );
+      }
+#ifdef FF_BAT
+      else /* CMD_MODE_BAT */
+      {
+        rBAT_PlusCOLP ( colpStat, NULL, NULL, NULL, NULL, NULL );
+      }
+#endif
+      break;
+    } 
+    case KSD_SS_COLR:
+    {
+      /* SS Status of class - T_ACI_KSD_ST */
+      if ( ksStat->ir.rKSCL.ssSt EQ KSD_ST_NOT_VALID )
+        colrStat = COLR_STAT_Unknown;
+      else if ( ksStat->ir.rKSCL.ssSt & SSS_P )
+        colrStat = COLR_STAT_Prov;
+      else
+        colrStat = COLR_STAT_NotProv;
+      
+      if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+      {
+        rCI_PercentCOLR(colrStat);
+      }
+#ifdef FF_BAT
+      else /* CMD_MODE_BAT */
+      {
+        rBAT_PercentCOLR(colrStat);
+      } 
+#endif
+      break;
+    }
+  }
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL  void utl_cb_callforwarding( UBYTE srcId, T_ACI_KSIR * ksStat )
+{
+  T_ACI_CCFC_SET  ccfcSetting;
+  UBYTE           idx;
+
+  TRACE_FUNCTION("utl_cb_callforwarding()");
+
+  if ( ksStat->ir.rKSCF.opCd NEQ KSD_OP_IRGT )
+    return;
+
+  for( idx = 0; idx < ksStat->ir.rKSCF.c_cfFeatLst; idx++ )
+  {
+    /* SS Status of class - T_ACI_KSD_ST */
+    if ( ksStat->ir.rKSCF.cfFeatLst[idx].ssSt EQ KSD_ST_NOT_VALID )
+      ccfcSetting.clsstat.status = STATUS_NotPresent;
+    else if ( ksStat->ir.rKSCF.cfFeatLst[idx].ssSt & SSS_A )
+      ccfcSetting.clsstat.status = STATUS_Active;
+    else
+      ccfcSetting.clsstat.status = STATUS_NotActive;
+    /* type of class */
+    if ( ksStat->ir.rKSCF.cfFeatLst[idx].bsTp EQ KSD_BS_TP_None
+     AND ksStat->ir.rKSCF.cfFeatLst[idx].bsCd EQ KSD_BS_TeleBearerUnknown)
+    {
+      if (ccfcSetting.clsstat.status EQ STATUS_NotPresent)
+        ccfcSetting.clsstat.class_type = CLASS_None;
+      else
+        ccfcSetting.clsstat.class_type = CLASS_VceDatFax;
+    }
+    else
+      ccfcSetting.clsstat.class_type = cmhSS_GetClassType(ksStat->ir.rKSCF.cfFeatLst[idx].bsTp,
+                                                           ksStat->ir.rKSCF.cfFeatLst[idx].bsCd);
+    /* number */
+    strcpy(ccfcSetting.number, (char *)ksStat->ir.rKSCF.cfFeatLst[idx].num);
+    if ( !strlen ( ccfcSetting.number ))
+    {
+      ccfcSetting.type.npi   = NPI_NotPresent;
+      ccfcSetting.type.ton   = TON_NotPresent;
+      ccfcSetting.subaddr[0] = 0x0;
+      ccfcSetting.satype.tos = TOS_NotPresent;
+      ccfcSetting.satype.oe  = OE_NotPresent;
+      ccfcSetting.time       = ACI_NumParmNotPresent;
+    }
+    else
+    {
+      T_CF_FEAT *cfFeat = &ksStat->ir.rKSCF.cfFeatLst[idx];
+      /* toa */
+      ccfcSetting.type.ton = cfFeat->ton NEQ 0xFF 
+                             ? (T_ACI_TOA_TON)cfFeat->ton 
+                             : TON_NotPresent;
+      ccfcSetting.type.npi = cfFeat->npi NEQ 0xFF 
+                             ? (T_ACI_TOA_NPI)cfFeat->npi 
+                             : NPI_NotPresent;
+      /* subaddr */
+      strcpy(ccfcSetting.subaddr, (char *)ksStat->ir.rKSCF.cfFeatLst[idx].sub);
+      /* tos */
+      ccfcSetting.satype.tos = cfFeat->tos NEQ 0xFF
+                               ? (T_ACI_TOS_TOS)cfFeat->tos
+                               : TOS_NotPresent;
+      ccfcSetting.satype.oe  = cfFeat->oe NEQ 0xFF 
+                               ? (T_ACI_TOS_OE)cfFeat->oe 
+                               : OE_NotPresent;
+      /* time */
+      ccfcSetting.time       = cfFeat->time NEQ 0xFF 
+                               ? cfFeat->time 
+                               : ACI_NumParmNotPresent;
+    }
+    if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+    {
+      rCI_PlusCCFC (&ccfcSetting);
+    }
+#ifdef FF_BAT
+    else
+    {
+      rBAT_PlusCCFC (&ccfcSetting);
+    }
+#endif
+  }
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL  void utl_cb_callbarring( UBYTE srcId, T_ACI_KSIR * ksStat )
+{
+  T_ACI_CLSSTAT   classStat;
+  UBYTE           idx;
+
+  TRACE_FUNCTION("utl_cb_callbarring()");
+
+  if (ksStat->ir.rKSCB.opCd NEQ KSD_OP_IRGT)
+  {
+    return;
+  }
+  for (idx = 0; idx < ksStat->ir.rKSCB.c_cbInfoLst; idx++)
+  {
+    /* type of class */
+    classStat.class_type = cmhSS_GetCbClassType(ksStat->ir.rKSCB.cbInfoLst[idx].bsTp,
+                                                 ksStat->ir.rKSCB.cbInfoLst[idx].bsCd);
+
+    /* SS Status of class */
+    if (classStat.class_type EQ CLASS_VceDatFaxSms 
+     OR classStat.class_type EQ CLASS_None)
+    {
+      classStat.status = STATUS_NotActive;
+    }
+    else
+    {
+      classStat.status = STATUS_Active;
+    }
+    if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+    {
+      rCI_PlusCLCK(&classStat);
+    }
+#ifdef FF_BAT
+    else /* CMD_MODE_BAT */
+    {
+      rBAT_PlusCLCK(&classStat);
+    }
+#endif
+  }
+}
+
+/*
+ ****************************************************************
+ */
+LOCAL  void utl_cb_imei( UBYTE srcId, T_ACI_KSIR * ksStat )
+{
+  TRACE_FUNCTION("utl_cb_imei()");
+
+  sprintf ( g_sa,
+            "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
+            (ksStat->ir.rKSIMEI.tac1 >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.tac1 & 0x0F,
+
+            (ksStat->ir.rKSIMEI.tac2 >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.tac2 & 0x0F,
+
+            (ksStat->ir.rKSIMEI.tac3 >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.tac3 & 0x0F,
+
+            (ksStat->ir.rKSIMEI.fac  >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.fac  & 0x0F,
+
+            (ksStat->ir.rKSIMEI.snr1 >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.snr1 & 0x0F,
+
+            (ksStat->ir.rKSIMEI.snr2 >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.snr2 & 0x0F,
+
+            (ksStat->ir.rKSIMEI.snr3 >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.snr3 & 0x0F,
+
+             ksStat->ir.rKSIMEI.cd,
+            (ksStat->ir.rKSIMEI.svn  >> 4) & 0x0F,
+             ksStat->ir.rKSIMEI.svn  & 0x0F );
+
+  io_sendMessage ( srcId, g_sa, ATI_NORMAL_OUTPUT );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-F&D (8411)              MODULE  : ACI_UTIL           |
+| STATE   : code                        ROUTINE :                    |
++--------------------------------------------------------------------+
+
+  PURPOSE : handles PercentKSIR call back
+
+*/
+GLOBAL void utl_cb_percentKSIR (U8 srcId, T_ACI_KSIR *ksStat)
+{
+  T_ACI_USSD_DATA  ussd;
+
+  TRACE_FUNCTION("utl_cb_percentKSIR()");
+  
+  switch (ksStat->ksdCmd)
+  {
+    case (KSD_CMD_IMEI):
+      if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+      {
+        utl_cb_imei(srcId, ksStat);
+      }
+#ifdef FF_BAT
+      else /* CMD_MODE_BAT */
+      {
+        rBAT_PercentIMEI(&(ksStat->ir.rKSIMEI));
+      }
+#endif
+      break;
+
+    case (KSD_CMD_CB):
+      utl_cb_callbarring(srcId, ksStat);
+      break;
+
+    case (KSD_CMD_CF):
+      utl_cb_callforwarding(srcId, ksStat);
+      break;
+
+    case (KSD_CMD_CL):
+      utl_cb_lineidentification(srcId, ksStat);
+      break;
+
+    case (KSD_CMD_CW):
+      utl_cb_callwaiting(srcId, ksStat);
+      break;
+
+    case (KSD_CMD_PWD):
+      /* no specific answer to +CPWD which is the corresponding AT cmd */
+      break;
+
+    case (KSD_CMD_UBLK):
+      /* no specific answer to +CPIN which is the corresponding AT cmd */
+      break;
+
+    case (KSD_CMD_USSD):
+      if (aci_cmd_src_mode_get(srcId) EQ CMD_MODE_ATI)
+      {
+        rci_display_USSD(srcId,
+                         ksStat->ir.rKSUS.mode,
+                         (UBYTE *)ksStat->ir.rKSUS.ussd,
+                         ksStat->ir.rKSUS.len,
+                         FALSE, /* means DO NOT CONVERT STRING */
+                         ksStat->ir.rKSUS.dcs);
+      }
+#ifdef FF_BAT
+      else /* CMD_MODE_BAT */
+      {
+        ussd.len = ksStat->ir.rKSUS.len;
+        memcpy (ussd.data, (UBYTE *)ksStat->ir.rKSUS.ussd, ussd.len);
+        rBAT_PlusCUSD(ksStat->ir.rKSUS.mode, &ussd, ksStat->ir.rKSUS.dcs);
+      }
+#endif
+      break;
+
+    case (KSD_CMD_CCBS):
+      utl_cb_ccbs(srcId, ksStat);
+      break;
+  }
+
+}
+#endif /* defined (FF_ATI) || defined (FF_BAT) */