FreeCalypso > hg > fc-magnetite
view src/aci2/aci/aci_util.c @ 591:205a3ec39d89
SE J100 APCOFF setting turns out to be different from C1xx
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 16 Mar 2019 06:24:06 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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) */