FreeCalypso > hg > fc-magnetite
view src/aci2/aci/aci_util.c @ 662:8cd8fd15a095
SIM speed enhancement re-enabled and made configurable
TI's original code supported SIM speed enhancement, but Openmoko had it
disabled, and OM's disabling of speed enhancement somehow caused certain
SIM cards to start working which didn't work before (OM's bug #666).
Because our FC community is much smaller in year 2020 than OM's community
was in their day, we are not able to find one of those #666-affected SIMs,
thus the real issue they had encountered remains elusive. Thus our
solution is to re-enable SIM speed enhancement and simply wait for if
and when someone runs into a #666-affected SIM once again. We provide
a SIM_allow_speed_enhancement global variable that allows SIM speed
enhancement to be enabled or disabled per session, and an /etc/SIM_spenh
file in FFS that allows it to enabled or disabled on a non-volatile
basis. SIM speed enhancement is now enabled by default.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 24 May 2020 05:02:28 +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) */