FreeCalypso > hg > leo2moko-debug
diff g23m/condat/ms/src/aci/cmh_smsf.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/g23m/condat/ms/src/aci/cmh_smsf.c Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,4147 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-PS (6147) +| Modul : CMH_SMSF ++----------------------------------------------------------------------------- +| 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 functions used by the command +| handler for the short message service. ++----------------------------------------------------------------------------- +*/ + +#ifndef CMH_SMSF_C +#define CMH_SMSF_C +#endif + +#include "aci_all.h" +/*==== INCLUDES ===================================================*/ +#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 "aci.h" +#include "aci_lst.h" +#include "aci_mem.h" +#include "psa.h" +#include "psa_cc.h" +#ifdef SIM_TOOLKIT +#include "psa_sat.h" +#endif +#include "psa_sms.h" +#include "psa_sim.h" +#include "psa_mmi.h" +#include "psa_util.h" +#include "phb.h" +#include "cmh.h" +#include "cmh_sms.h" +#include "pcm.h" + +#include "aci_lst.h" + +#if (defined (MFW) AND !defined (FF_MMI_RIV)) OR defined (_CONC_TESTING_) +#include "conc_sms.h" +#endif /* ##if (defined (MFW) AND !defined (FF_MMI_RIV)) OR defined (_CONC_TESTING_)*/ + + +#ifdef UART +#include "dti_conn_mng.h" +#endif + +#include "cmh_sim.h" +#ifndef _SIMULATION_ + +/* temporary solution to get ffs.h included without GPRS to be set ! */ +#ifdef GPRS +#include "ffs/ffs.h" +#else +#include "ffs/ffs.h" +#undef GPRS +#endif /* GPRS */ + +#include "ffs_coat.h" + +#endif /* !_SIMULATION_ */ + +#ifdef FF_CPHS +#include "cphs.h" +#endif /* FF_CPHS */ + +/*==== CONSTANTS ==================================================*/ + +#define SMS_CMH_YEAR_MAX (99) /* maximum value for year in */ + /* absolute validity period */ +#define SMS_CMH_YEAR_MIN (0) /* minimum value for year in */ + /* absolute validity period */ +#define SMS_CMH_MONTH_MAX (12) /* maximum value for month in */ + /* absolute validity period */ +#define SMS_CMH_MONTH_MIN (1) /* minimum value for month in */ + /* absolute validity period */ +#define SMS_CMH_DAY_MAX (31) /* maximum value for day in */ + /* absolute validity period */ +#define SMS_CMH_DAY_MIN (1) /* minimum value for day in */ + /* absolute validity period */ +#define SMS_CMH_HOUR_MAX (23) /* maximum value for hour in */ + /* absolute validity period */ +#define SMS_CMH_HOUR_MIN (0) /* minimum value for hour in */ + /* absolute validity period */ +#define SMS_CMH_MINUTE_MAX (59) /* maximum value for minute in */ + /* absolute validity period */ +#define SMS_CMH_MINUTE_MIN (0) /* minimum value for minute in */ + /* absolute validity period */ +#define SMS_CMH_SECOND_MAX (59) /* maximum value for second in */ + /* absolute validity period */ +#define SMS_CMH_SECOND_MIN (0) /* minimum value for second in */ + /* absolute validity period */ + +#define SMS_CMH_TZ_MAX (47) /* maximum value for a time */ + /* zone in absolute validity */ + /* period */ +#define SMS_CMH_TZ_MIN (-47) /* minimum value for a time */ + /* zone in absolute validity */ + /* period */ + + +/* macro for converting a two digit BCD into an UBYTE */ +#define BCD2UBYTE(bcd) (UBYTE)(10 * bcd[0] + bcd[1]) + +/* macro for testing whether any digit of a two digit */ +/* BCD lies outside of a predefined value range */ +#define NOTBCD(bcd) (bcd[0] > 9 OR\ + bcd[1] > 9 ) + + +#define L_MAX_UD 140 +#define L_MAX_UD_CONC 134 + +/*==== TYPES ======================================================*/ + +/*==== EXPORT =====================================================*/ +EXTERN T_ACI_LIST *set_prm_list; + +/*==== VARIABLES ==================================================*/ + +const char * const ffs_smsprfl_fname[] = { FFS_SMSPRFL_FNAME01, + FFS_SMSPRFL_FNAME02, + FFS_SMSPRFL_FNAME03, + FFS_SMSPRFL_FNAME04 }; + +/*==== FUNCTIONS ==================================================*/ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : ACI_CMD | +| STATE : code ROUTINE : aci_encodeVpenh | ++--------------------------------------------------------------------+ + + PURPOSE : This function encodes a given T_ACI_VP_ENH type to a + string. +*/ +GLOBAL void aci_encodeVpenh ( CHAR* vpenh_str, + T_ACI_VP_ENH* vpenh ) +{ + UBYTE pos; + + /* functionality indicator */ + utl_binToHex (&vpenh->func_ind, 1, vpenh_str); + pos = 2; + + /* extension octet */ + if (vpenh->func_ind & TP_VPF_ENH_EXT_BIT_MASK) + { + utl_binToHex (&vpenh->ext_oct, 1, vpenh_str+pos); + pos += 2; + } + + /* process validity period values */ + if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_REL) + { + utl_binToHex (&vpenh->val.vpenh_relative, 1, vpenh_str+pos ); + pos += 2; + } + else if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_SEC) + { + utl_binToHex (&vpenh->val.vpenh_seconds, 1, vpenh_str+pos ); + pos += 2; + } + else if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_HRS) + { + vpenh_str[pos++] = vpenh->val.vpenh_hours.hour[1] + '0'; + vpenh_str[pos++] = vpenh->val.vpenh_hours.hour[0] + '0'; + + vpenh_str[pos++] = vpenh->val.vpenh_hours.minute[1] + '0'; + vpenh_str[pos++] = vpenh->val.vpenh_hours.minute[0] + '0'; + + vpenh_str[pos++] = vpenh->val.vpenh_hours.second[1] + '0'; + vpenh_str[pos++] = vpenh->val.vpenh_hours.second[0] + '0'; + } + + /* fill the rest with zeros */ + while (pos < 14) + { + vpenh_str[pos++] = '0'; + } + + /* string terminator */ + vpenh_str[pos] = '\0'; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getNType | ++-------------------------------------------------------------------+ + + PURPOSE : This function calculates the 'numbering type' out of the + current 'type of numbering'. +*/ +GLOBAL UBYTE cmhSMS_getNType ( T_ACI_TOA_TON ton ) +{ + switch( ton ) + { + case( TON_International ): + case( TON_National ): + case( TON_NetSpecific ): + case( TON_DedAccess ): + case( TON_Alphanumeric ): + case( TON_Abbreviated ): return (UBYTE)ton; + default: return SMS_TON_UNKNOWN; + } +} + + +GLOBAL BOOL cmhSMS_findPrflId ( UBYTE critrerium, void* elem ) +{ + T_SMS_SET_PRM *compared = (T_SMS_SET_PRM*)elem; + if ( compared->prflId == critrerium ) + return TRUE; + else + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getTon | ++-------------------------------------------------------------------+ + + PURPOSE : This function calculates the 'type of numbering' out of + the current 'numbering type'. +*/ +GLOBAL T_ACI_TOA_TON cmhSMS_getTon ( UBYTE ntype ) +{ + switch( ntype ) + { + case( SMS_TON_UNKNOWN ): + case( SMS_TON_INTERNATIONAL ): + case( SMS_TON_NATIONAL ): + case( SMS_TON_NETWORK_SPEC ): + case( SMS_TON_SUBSCRIBER ): + case( SMS_TON_ALPHANUMERIC ): + case( SMS_TON_ABBREVIATED ): return (T_ACI_TOA_TON)ntype; + default: return TON_NotPresent; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getNPlan | ++-------------------------------------------------------------------+ + + PURPOSE : This function calculates the 'numbering plan' out of the + current 'numbering plan identification'. +*/ +GLOBAL UBYTE cmhSMS_getNPlan ( T_ACI_TOA_NPI npi ) +{ + switch( npi ) + { + case( NPI_IsdnTelephony ): + case( NPI_Data ): + case( NPI_Telex ): + case( NPI_National ): + case( NPI_Private ): return (UBYTE)npi; + default: return NPI_Unknown; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getNpi | ++-------------------------------------------------------------------+ + + PURPOSE : This function calculates the 'numbering plan + identification' out of the current 'numbering plan'. +*/ +GLOBAL T_ACI_TOA_NPI cmhSMS_getNpi ( UBYTE nplan ) +{ + switch( nplan ) + { + case( SMS_TON_UNKNOWN ): + case( SMS_NPI_ISDN ): + case( SMS_NPI_X121 ): + case( SMS_NPI_F69 ): + case( SMS_NPI_NATIONAL ): + case( SMS_NPI_PRIVATE ): return (T_ACI_TOA_NPI)nplan; + default: return NPI_NotPresent; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getStatCmh | ++-------------------------------------------------------------------+ + + PURPOSE : This function converts the message status from + PSA type to CMH type. +*/ +GLOBAL void cmhSMS_getStatCmh ( UBYTE inStat, + T_ACI_SMS_STAT* outStat ) +{ + switch( inStat & STAT_MASK ) + { + case( REC_UNREAD ): *outStat = SMS_STAT_RecUnread; break; + case( REC_READ ): *outStat = SMS_STAT_RecRead; break; + case( STO_UNSENT ): *outStat = SMS_STAT_StoUnsent; break; + case( STO_SENT ): *outStat = SMS_STAT_StoSent; break; + default: *outStat = SMS_STAT_NotPresent; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getStatPsa | ++-------------------------------------------------------------------+ + + PURPOSE : This function converts the message status from + CMH type to PSA type. +*/ +GLOBAL BOOL cmhSMS_getStatPsa ( T_ACI_SMS_STAT inStat, + UBYTE* outStat ) +{ + switch( inStat ) + { + case( SMS_STAT_RecUnread ): *outStat = REC_UNREAD; break; + case( SMS_STAT_RecRead ): *outStat = REC_READ; break; + case( SMS_STAT_StoUnsent ): *outStat = STO_UNSENT; break; + case( SMS_STAT_StoSent ): *outStat = STO_SENT; break; + default : return (FALSE); + } + + return ( TRUE ); +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_isVpabsVld | ++-------------------------------------------------------------------+ + + PURPOSE : This function is used to process whether the given + absolute validity period is valid. + + Note: This function checks whether every individual + time value is within a valid range. It does not + check whether the whole expression is valid. +*/ +GLOBAL BOOL cmhSMS_isVpabsVld ( T_ACI_VP_ABS* vpabs ) +{ + if ( BCD2UBYTE ( vpabs -> year ) > SMS_CMH_YEAR_MAX OR + BCD2UBYTE ( vpabs -> month ) < SMS_CMH_MONTH_MIN OR + BCD2UBYTE ( vpabs -> month ) > SMS_CMH_MONTH_MAX OR + BCD2UBYTE ( vpabs -> day ) < SMS_CMH_DAY_MIN OR + BCD2UBYTE ( vpabs -> day ) > SMS_CMH_DAY_MAX OR + BCD2UBYTE ( vpabs -> hour ) > SMS_CMH_HOUR_MAX OR + BCD2UBYTE ( vpabs -> minute ) > SMS_CMH_MINUTE_MAX OR + BCD2UBYTE ( vpabs -> second ) > SMS_CMH_SECOND_MAX OR + vpabs -> timezone < SMS_CMH_TZ_MIN OR + vpabs -> timezone > SMS_CMH_TZ_MAX OR + NOTBCD ( vpabs -> year ) OR + NOTBCD ( vpabs -> month ) OR + NOTBCD ( vpabs -> day ) OR + NOTBCD ( vpabs -> hour ) OR + NOTBCD ( vpabs -> minute ) OR + NOTBCD ( vpabs -> second ) ) + + return ( FALSE ); + + return ( TRUE ); +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_isVpenhVld | ++-------------------------------------------------------------------+ + + PURPOSE : This function is used to process whether the given + enhanced validity period is valid. + + Note: This function checks whether every individual + time value is within a valid range. It does not + check whether the whole expression is valid. +*/ +GLOBAL BOOL cmhSMS_isVpenhVld ( T_ACI_VP_ENH* vpenh ) +{ + if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) > TP_VPF_ENH_HRS) + { + return FALSE; + } + + if ((vpenh->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_HRS) + { + if ( BCD2UBYTE ( vpenh->val.vpenh_hours.minute ) > SMS_CMH_MINUTE_MAX OR + BCD2UBYTE ( vpenh->val.vpenh_hours.second ) > SMS_CMH_SECOND_MAX OR + NOTBCD ( vpenh->val.vpenh_hours.hour ) OR + NOTBCD ( vpenh->val.vpenh_hours.minute ) OR + NOTBCD ( vpenh->val.vpenh_hours.second ) ) + { + return ( FALSE ); + } + } + + return ( TRUE ); +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setVpabsPsa | ++-------------------------------------------------------------------+ + + PURPOSE : This function is used to copy the elements of the + absolute validity period structure of the ACI to the + corresponding structure of the PSA. + + Note: Copying of the structure elements might be + dangerous when array size of time elements differ + from MAX_VP_ABS_DIGIT due to changes in PSA + declaration. +*/ +GLOBAL void cmhSMS_setVpabsPsa ( T_tp_vp_abs* psaVp, + T_ACI_VP_ABS* cmhVp ) +{ + USHORT i; /* used for counting */ + BOOL isNegative = ( cmhVp->timezone & 0x8000 ); + SHORT tz = ( UBYTE ) cmhVp->timezone; + + for (i = 0; i < MAX_VP_ABS_DIGITS; i++) + { + psaVp -> year [i] = cmhVp -> year [i]; + psaVp -> month [i] = cmhVp -> month [i]; + psaVp -> day [i] = cmhVp -> day [i]; + psaVp -> hour [i] = cmhVp -> hour [i]; + psaVp -> minute[i] = cmhVp -> minute[i]; + psaVp -> second[i] = cmhVp -> second[i]; + } + + if ( isNegative ) + { + tz = -tz; + psaVp -> tz_sign = 1; + } + else + { + psaVp -> tz_sign = 0; + } + + psaVp -> tz_lsb = tz & 0x000F; + psaVp -> tz_msb = tz & 0x00F0; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setVpenhPsa | ++-------------------------------------------------------------------+ + + PURPOSE : This function is used to copy the elements of the + enhanced validity period structure of the ACI to the + corresponding structure of the PSA. +*/ +GLOBAL void cmhSMS_setVpenhPsa ( T_tp_vp_enh* psaVp, + T_ACI_VP_ENH* cmhVp ) +{ + memset(psaVp, 0, sizeof(T_tp_vp_enh)); + + if (cmhVp->func_ind & TP_VPF_ENH_EXT_BIT_MASK) + { + psaVp->tp_ext = SMS_EXT_INCLUDED; + psaVp->v_tp_rsrvd = 1; + psaVp->tp_rsrvd = cmhVp->ext_oct; + } + + if (cmhVp->func_ind & TP_VPF_ENH_SINGLE_SHOT_MASK) + { + psaVp->tp_ss = SMS_SS_SET; + } + + if ((cmhVp->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_NOT_PRESENT) + { + psaVp->tvpf = SMS_TVPF_NOT_PRESENT; + } + else if ((cmhVp->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_REL) + { + psaVp->tvpf = SMS_TVPF_RELATIVE; + psaVp->v_tp_vp_rel = 1; + psaVp->tp_vp_rel = cmhVp->val.vpenh_relative; + } + else if ((cmhVp->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_SEC) + { + psaVp->tvpf = SMS_TVPF_SECONDS; + psaVp->v_tp_vp_sec = 1; + psaVp->tp_vp_sec = cmhVp->val.vpenh_seconds; + } + else if ((cmhVp->func_ind & TP_VPF_ENH_FORMAT_MASK) EQ TP_VPF_ENH_HRS) + { + psaVp->tvpf = SMS_TVPF_HOURS; + psaVp->v_hour = 1; + psaVp->hour[0] = cmhVp->val.vpenh_hours.hour[0]; + psaVp->hour[1] = cmhVp->val.vpenh_hours.hour[1]; + psaVp->v_minute = 1; + psaVp->minute[0] = cmhVp->val.vpenh_hours.minute[0]; + psaVp->minute[1] = cmhVp->val.vpenh_hours.minute[1]; + psaVp->v_second = 1; + psaVp->second[0] = cmhVp->val.vpenh_hours.second[0]; + psaVp->second[1] = cmhVp->val.vpenh_hours.second[1]; + } + else + { + TRACE_EVENT("[ERR] cmhSMS_setVpenhPsa: wrong type of validity period format"); + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setVpabsCmh | ++-------------------------------------------------------------------+ + + PURPOSE : This function is used to copy the elements of the + absolute validity period structure of the PSA to the + corresponding structure of the ACI. + + Note: Copying of the structure elements might be + dangerous when array size of time elements differ + from MAX_VP_ABS_DIGIT due to changes in PSA + declaration. +*/ +GLOBAL void cmhSMS_setVpabsCmh ( T_ACI_VP_ABS* cmhVp, + T_tp_vp_abs* psaVp ) +{ + USHORT i; /* used for counting */ + SHORT tz; + + for (i = 0; i < MAX_VP_ABS_DIGITS; i++) + { + cmhVp -> year [i] = psaVp -> year [i]; + cmhVp -> month [i] = psaVp -> month [i]; + cmhVp -> day [i] = psaVp -> day [i]; + cmhVp -> hour [i] = psaVp -> hour [i]; + cmhVp -> minute[i] = psaVp -> minute[i]; + cmhVp -> second[i] = psaVp -> second[i]; + } + + tz = ((psaVp->tz_msb & 0x07) * 10) + psaVp->tz_lsb; /* BCD */ + + if (psaVp->tz_sign) + cmhVp -> timezone = -tz; + else + cmhVp -> timezone = tz; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setVpenhCmh | ++-------------------------------------------------------------------+ + + PURPOSE : This function is used to copy the elements of the + enhanced validity period structure of the PSA to the + corresponding structure of the ACI. + +*/ +GLOBAL void cmhSMS_setVpenhCmh ( T_ACI_VP_ENH* cmhVp, + T_tp_vp_enh* psaVp ) +{ + memset(cmhVp, 0, sizeof(T_ACI_VP_ENH)); + + cmhVp->func_ind = psaVp->tvpf; + + if ((psaVp->tp_ext EQ SMS_EXT_INCLUDED) AND (psaVp->v_tp_rsrvd)) + { + cmhVp->func_ind |= TP_VPF_ENH_EXT_BIT_MASK; + cmhVp->ext_oct = psaVp->tp_rsrvd; + } + + if (psaVp->tp_ss EQ SMS_SS_SET) + { + cmhVp->func_ind |= TP_VPF_ENH_SINGLE_SHOT_MASK; + } + + if (psaVp->tvpf EQ SMS_TVPF_NOT_PRESENT) + { + /* do nothing */ + } + else if ((psaVp->tvpf EQ SMS_TVPF_RELATIVE) AND (psaVp->v_tp_vp_rel)) + { + cmhVp->val.vpenh_relative = psaVp->tp_vp_rel; + } + else if ((psaVp->tvpf EQ SMS_TVPF_SECONDS) AND (psaVp->v_tp_vp_sec)) + { + cmhVp->val.vpenh_seconds = psaVp->tp_vp_sec; + } + else if (psaVp->tvpf EQ SMS_TVPF_HOURS) + { + if (psaVp->v_hour) + { + cmhVp->val.vpenh_hours.hour[0] = psaVp->hour[0]; + cmhVp->val.vpenh_hours.hour[1] = psaVp->hour[1]; + } + if (psaVp->v_minute) + { + cmhVp->val.vpenh_hours.minute[0] = psaVp->minute[0]; + cmhVp->val.vpenh_hours.minute[1] = psaVp->minute[1]; + } + if (psaVp->v_second) + { + cmhVp->val.vpenh_hours.second[0] = psaVp->second[0]; + cmhVp->val.vpenh_hours.second[1] = psaVp->second[1]; + } + } + else + { + TRACE_EVENT("[ERR] cmhSMS_setVpenhCmh: wrong type of validity period format"); + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getAdrStr | ++--------------------------------------------------------------------+ + + PURPOSE : This function is used to convert the service center + address in BCD to the service center address as a string. +*/ +GLOBAL UBYTE cmhSMS_getAdrStr ( CHAR* pStr, + UBYTE maxIdx, + UBYTE* pBcd, + UBYTE numDigits ) +{ + UBYTE bcdIdx; + UBYTE strIdx = 0; + + memset(pStr, 0x00, maxIdx); + + for(bcdIdx = 0; bcdIdx < numDigits AND strIdx < maxIdx; bcdIdx++) + { + switch (pBcd[bcdIdx]) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + pStr[strIdx++] = pBcd[bcdIdx] + '0'; + break; + + case BCD_ASTSK: + pStr[strIdx++] = '*'; + break; + + case BCD_PND: + pStr[strIdx++] = '#'; + break; + + case BCD_A: + pStr[strIdx++] = 'A'; + break; + + case BCD_B: + pStr[strIdx++] = 'B'; + break; + + case BCD_C: + pStr[strIdx++] = 'C'; + break; + } + } + + pStr[strIdx] = '\0'; + + return ( strIdx ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getAdrBcd | ++--------------------------------------------------------------------+ + + PURPOSE : This function is used to convert the service center + address as a string to the service center address in BCD. +*/ +GLOBAL void cmhSMS_getAdrBcd ( UBYTE* pBcd, + UBYTE* pNumDigits, + UBYTE maxDigits, + CHAR* pStr ) +{ + UBYTE bcdIdx = 0; + UBYTE strIdx; + + for(strIdx = 0; bcdIdx < maxDigits AND pStr[strIdx] NEQ '\0'; strIdx++) + { + switch (pStr[strIdx]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + pBcd[bcdIdx++] = pStr[strIdx] - '0'; + break; + + case '*': + pBcd[bcdIdx++] = BCD_ASTSK; + break; + + case '#': + pBcd[bcdIdx++] = BCD_PND; + break; + + case 'A': + pBcd[bcdIdx++] = BCD_A; + break; + + case 'B': + pBcd[bcdIdx++] = BCD_B; + break; + + case 'C': + pBcd[bcdIdx++] = BCD_C; + break; + } + } + + *pNumDigits = bcdIdx; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getMemCmh | ++-------------------------------------------------------------------+ + + PURPOSE : This function converts the preferred memory from + PSA type to CMH type. +*/ +GLOBAL void cmhSMS_getMemCmh ( UBYTE inMem, T_ACI_SMS_STOR* outMem ) +{ + switch( inMem ) + { + case( MEM_ME ): *outMem = SMS_STOR_Me; break; + case( MEM_SM ): *outMem = SMS_STOR_Sm; break; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getMemPsa | ++-------------------------------------------------------------------+ + + PURPOSE : This function converts the preferred memory from + CMH type to PSA type. + + returns: TRUE if conversion was successfull, + otherwise FALSE +*/ +GLOBAL BOOL cmhSMS_getMemPsa ( T_ACI_SMS_STOR inMem, UBYTE* outMem ) +{ + switch( inMem ) + { + case( SMS_STOR_Me ): *outMem = MEM_ME; break; + case( SMS_STOR_Sm ): *outMem = MEM_SM; break; + default : return ( FALSE ); + } + + return ( TRUE ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getAlphabetPp | ++--------------------------------------------------------------------+ + + PURPOSE : This function is used to extract the used alphabet out + of the data coding scheme for point-to-point SMS. +*/ +GLOBAL UBYTE cmhSMS_getAlphabetPp ( UBYTE dcs ) +{ + UBYTE alphabet = 0; /* means 7 bit default alphabet */ + + switch (dcs & 0xF0) + { + case( 0x30 ): + case( 0x20 ): + alphabet = 0x01; /* compressed, counts as 8 bit data */ + break; + case( 0x10 ): + case( 0x00 ): + alphabet = (dcs & 0x0C) >> 2; + if (alphabet EQ 3) + alphabet = 0; /* reserved coding */ + break; + case( 0xE0 ): + alphabet = 0x02; /* UCS2 */ + break; + case( 0xF0 ): + alphabet = (dcs & 0x04) >> 2; + break; + } + + return alphabet; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_expdSmsPp | ++-------------------------------------------------------------------+ + + PURPOSE : This function expands a point-to-point SMS from + 7 to 8 bit. +*/ +GLOBAL void cmhSMS_expdSmsPp ( UBYTE byte_offset, + UBYTE dcs, + UBYTE* source, + UBYTE source_len, + UBYTE* dest, + UBYTE* dest_len ) +{ + UBYTE alphabet; + UBYTE bit_offset = 0; + + TRACE_FUNCTION ("cmhSMS_expdSmsPp ()"); + + + alphabet = cmhSMS_getAlphabetPp ( dcs ); + + switch (alphabet) + { + case( 0 ): /* 7 bit alphabet */ + + if ( byte_offset % 7 NEQ 0 ) + { + bit_offset = 7 - ((byte_offset*8) % 7); + } + + *dest_len = source_len - ((byte_offset*8+6)/7); /* adjust byte_offset to septets */ + + /* In 7-Bit mode we get number of septets but we need octets */ + source_len = (source_len*7+7)/8; /* round up to next octet*/ + source_len -= byte_offset; + + utl_cvt7To8 ( source, source_len, dest, bit_offset); + + + break; + + default: /* 8 bit alphabet, UCS2, reserved */ + + *dest_len = source_len-byte_offset; + memcpy ( (CHAR*) dest, (CHAR*)source, *dest_len ); + break; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_rdcSmsPp | ++-------------------------------------------------------------------+ + + PURPOSE : This function reduces a point-to-point SMS from + 8 to 7 bit. +*/ +GLOBAL void cmhSMS_rdcSmsPp ( UBYTE byte_offset, + UBYTE dcs, + UBYTE* source, + UBYTE source_len, + UBYTE* dest, + UBYTE* dest_len ) +{ + UBYTE data_len; + UBYTE alphabet; + UBYTE bit_offset = 0; + + TRACE_FUNCTION ("cmhSMS_rdcSmsPp ()"); + + if (source_len EQ 0) + { + *dest_len = source_len; + return; + } + + alphabet = cmhSMS_getAlphabetPp ( dcs ); + + switch (alphabet) + { + case( 0 ): /* 7 bit alphabet */ + + if ( byte_offset % 7 NEQ 0 ) + { + bit_offset = 7 - ((byte_offset*8) % 7); + } + + data_len = MINIMUM (source_len, (SMS_MSG_LEN * 8) / 7); + + data_len = utl_cvt8To7 ( source, data_len, dest, bit_offset ); + break; + + default: /* 8 bit alphabet, UCS2, reserved */ + data_len = MINIMUM ( source_len, SMS_MSG_LEN ); + + memcpy ( ( CHAR * ) dest, ( CHAR * ) source, data_len ); + break; + } + + *dest_len = data_len; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMF_SMSF | +| STATE : code ROUTINE : cmhSMS_getAlphabetCb | ++--------------------------------------------------------------------+ + + PURPOSE : This function is used to extract the used alphabet out + of the data coding scheme for cell broadcast SMS. +*/ +GLOBAL UBYTE cmhSMS_getAlphabetCb ( UBYTE dcs ) +{ + UBYTE alphabet = 0; /* means 7 bit default alphabet */ + + switch (dcs & 0xF0) + { + case( 0x10 ): + if (dcs EQ 0x11) + alphabet = 2; + break; + + case( 0x70 ): + case( 0x60 ): + case( 0x50 ): + case( 0x40 ): + alphabet = (dcs & 0x0C) >> 2; + /* According to 03.38, "Any reserved codings shall be assumed + * to be the GSM 7 bit default alphabet by a receiving entity". + */ + if (alphabet EQ 3) + alphabet = 0; + break; + + case( 0xF0 ): + alphabet = (dcs & 0x04) >> 2; + break; + } + + return alphabet; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_expdSmsCb | ++--------------------------------------------------------------------+ + + PURPOSE : This function expands a cell broadcast SMS from + 7 to 8 bit. +*/ +GLOBAL void cmhSMS_expdSmsCb ( UBYTE dcs, + UBYTE *source, + UBYTE source_len, + UBYTE *dest, + UBYTE *dest_len ) +{ + UBYTE alphabet; + + TRACE_FUNCTION ("cmhSMS_expdSmsCb()"); + + alphabet = cmhSMS_getAlphabetCb ( dcs ); + + switch (alphabet) + { + case( 0 ): /* 7 bit alphabet */ +/* PATCH Add bit_offset parameter to function cvt7To8 */ +/* utl_cvt7To8 ( source, source_len, dest ); */ + utl_cvt7To8 ( source, source_len, dest, 0); +/* PATCH END */ + + *dest_len = ( source_len * 8 ) / 7; + break; + + default: /* 8 bit alphabet, UCS2, reserved */ + memcpy ( ( CHAR * ) dest, ( CHAR * ) source, source_len ); + + *dest_len = source_len; + break; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setToaDef | ++--------------------------------------------------------------------+ + + PURPOSE : This function sets the type of address to default values + (when the first character of address is '+' or the first + two characters are '0' default is 145 otherwise default + is 129) +*/ +GLOBAL CHAR* cmhSMS_setToaDef ( CHAR* number, + UBYTE* ntype, + UBYTE* nplan ) +{ + *nplan = SMS_NPI_ISDN; + + if ( *number EQ '+' ) + { + *ntype = SMS_TON_INTERNATIONAL; + return number+1; + } + else + { + *ntype = SMS_TON_UNKNOWN; + return number; + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setTimezone | ++--------------------------------------------------------------------+ + + PURPOSE : Codes the timezone format used in entity SMS. + +*/ +GLOBAL UBYTE cmhSMS_setTimezone (SHORT timezone) +{ + UBYTE local_tz = ( UBYTE ) timezone; + BOOL isNegative = ( local_tz & 0x80 ); + + if ( isNegative ) + local_tz = ~local_tz + 1; + + local_tz = ( local_tz / 10 ) + ( ( local_tz % 10 ) << 4 ); + + return ( ( isNegative ) ? local_tz | 0x08 : local_tz ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getTimezone | ++--------------------------------------------------------------------+ + + PURPOSE : Decodes the timezone format used in entity SMS. + +*/ +GLOBAL SHORT cmhSMS_getTimezone (UBYTE timezone) +{ + signed char local_tz; + + local_tz = ( timezone & 0x07 ) * 10 + ( ( timezone & 0xF0 ) >> 4 ); + + return ( SHORT ) (( timezone & 0x08 ) ? -local_tz : local_tz ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_setStorOcc | ++--------------------------------------------------------------------+ + + PURPOSE : Fills the T_ACI_SMS_STOR_OCC structure with data from the + shared parameter buffer. + +*/ +GLOBAL void cmhSMS_setStorOcc ( T_ACI_SMS_STOR_OCC* outMem, + UBYTE inMem ) +{ + cmhSMS_getMemCmh ( inMem, &outMem -> mem ); + + if ( outMem -> mem EQ SMS_STOR_Sm ) + { + outMem -> used = smsShrdPrm.aci_sms_parameter.simUsed; + outMem -> total = smsShrdPrm.aci_sms_parameter.simTotal; + } + else + { + outMem -> used = smsShrdPrm.aci_sms_parameter.meUsed; + outMem -> total = smsShrdPrm.aci_sms_parameter.meTotal; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| ROUTINE : cmhSMS_GetCmsFromSim | ++-------------------------------------------------------------------+ + + PURPOSE : Mapping of SIM error code to ACI error code. + +*/ +GLOBAL T_ACI_CMS_ERR cmhSMS_GetCmsFromSim ( USHORT errCode ) +{ + switch ( errCode ) + { + case SIM_NO_ERROR: + return CMS_ERR_NotPresent; + + case SIM_CAUSE_PIN1_EXPECT: + return CMS_ERR_SimPinReq; + + case SIM_CAUSE_PIN2_EXPECT: + return CMS_ERR_SimPin2Req; + + case SIM_CAUSE_PUK1_EXPECT: + case SIM_CAUSE_PIN1_BLOCKED: + return CMS_ERR_SimPukReq; + + case SIM_CAUSE_PUK2_EXPECT: + case SIM_CAUSE_PIN2_BLOCKED: + return CMS_ERR_SimPuk2Req; + + case SIM_CAUSE_PUK1_BLOCKED: + case SIM_CAUSE_PUK2_BLOCKED: + return CMS_ERR_SimWrong; + + case SIM_CAUSE_UNKN_FILE_ID: + case SIM_CAUSE_DNL_ERROR: + return CMS_ERR_UnknownErr; + + case SIM_CAUSE_EF_INVALID: + return CMS_ERR_OpNotSup; + + case SIM_CAUSE_ADDR_WRONG: + return CMS_ERR_InValMemIdx; + + case SIM_CAUSE_CMD_INCONSIST: + case SIM_CAUSE_MAX_INCREASE: + case SIM_CAUSE_CHV_NOTSET: + case SIM_CAUSE_CHV_VALIDATED: + case SIM_CAUSE_ACCESS_PROHIBIT: + return CMS_ERR_OpNotAllowed; + + case SIM_CAUSE_CARD_REMOVED: + case SIM_CAUSE_DRV_NOCARD: + return CMS_ERR_SimNotIns; + + case SIM_CAUSE_NO_SELECT: + case SIM_CAUSE_CLA_WRONG: + case SIM_CAUSE_INS_WRONG: + case SIM_CAUSE_P1P2_WRONG: + case SIM_CAUSE_P3_WRONG: + case SIM_CAUSE_PARAM_WRONG: + return CMS_ERR_MeFail; + + case SIM_CAUSE_SAT_BUSY: + return CMS_ERR_SimBsy; + + case SIM_CAUSE_DRV_TEMPFAIL: + return CMS_ERR_SimFail; + + default: + if (GET_CAUSE_DEFBY(errCode) EQ DEFBY_CONDAT AND + GET_CAUSE_ORIGSIDE(errCode) EQ ORIGSIDE_MS) + { + return CMS_ERR_UnknownErr; + } + return CMS_ERR_UnknownErr; + } +} + + + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| ROUTINE : cmhSMS_GetCmsFromSms | ++-------------------------------------------------------------------+ + + PURPOSE : Mapping of SMS causes (MNSMS.doc) to ACI error code. + +*/ +GLOBAL T_ACI_CMS_ERR cmhSMS_GetCmsFromSms ( USHORT errCode ) +{ + switch ( errCode ) + { + case SMS_NO_ERROR: /* No error */ + return CMS_ERR_NotPresent; + + case SMS_CAUSE_PARAM_WRONG: /* Wrong parameter in primitive */ + + case SMS_CAUSE_ENTITY_BUSY: /* Entity is busy */ + return CMS_ERR_SimBsy; + + case SMS_CAUSE_OPER_NOT_ALLW: /* Operation not allowed */ + return CMS_ERR_OpNotAllowed; + + case SMS_CAUSE_OPER_NOT_SUPP: /* Operation not supported */ + return CMS_ERR_OpNotSup; + + case SMS_CAUSE_SIM_BUSY: /* SIM busy */ + return CMS_ERR_SimBsy; + default: + break; + } + + /* + * The switch must be splitted because of a compiler bug + * - asm files can not compiled + * + * TMS470 ANSI C Compiler Version 1.22e + * + * brz, 2004.02.14 + */ + + switch(errCode) { + case SMS_CAUSE_MEM_FAIL: /* Memory failure */ + return CMS_ERR_MemFail; + + case SMS_CAUSE_INV_INDEX: /* Invalid memory index */ + return CMS_ERR_InValMemIdx; + + case SMS_CAUSE_MEM_FULL: /* Memory full */ + return CMS_ERR_MemFull; + + case SMS_CAUSE_NO_SERVICE: /* No network service */ + return CMS_ERR_NoNetServ; + + case SMS_CAUSE_NET_TIMEOUT: /* Network timeout */ + return CMS_ERR_NetTimeOut; + + case SMS_CAUSE_UNEXP_CNMA: /* No +CNMA acknowledgement expected */ + return CMS_ERR_NoCnmaAckExpect; + + case SMS_CAUSE_OTHER_ERROR: /* Any other error */ + return CMS_ERR_UnknownErr; + + default: + return ((T_ACI_CMS_ERR) (errCode & 0xFF)); /* cmdCmsError(errCode) will figure out other error values from the first byte of the error code */ + } +} + + + + + + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_ready | ++-------------------------------------------------------------------+ + + PURPOSE : This function notifies SMS_READY to all sources. +*/ +GLOBAL void cmhSMS_ready ( void ) +{ + int idx; + T_opl_field * ptr_opl; + + TRACE_FUNCTION ("cmhSMS_ready()"); + + smsShrdPrm.accessEnabled = TRUE; + ptr_opl = cmhSIM_GetOPL(); + ptr_opl->opl_status = FALSE; + + cmhSIM_UpdateOperatorName(NOT_PRESENT_16BIT); /* start EF_PNN and EF_OPL reading */ + + pb_start_build(FALSE); /* start phonebook reading, no guarantees */ + + percentCSTAT_indication(STATE_MSG_SMS, ENTITY_STATUS_Ready); + + for( idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT( RAT_SMS_READY, idx )(); + } + +} + + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_disableAccess | ++-------------------------------------------------------------------+ + + PURPOSE : This function disables access to all SMS functions. +*/ +GLOBAL void cmhSMS_disableAccess (void) +{ + smsShrdPrm.accessEnabled = FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_checkSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function checks if SMS is initialized. If not, the + SIM state is checked. AN error code dependent of the + SIM state is stored. +*/ +GLOBAL BOOL cmhSMS_checkSIM (void) +{ + if (smsShrdPrm.accessEnabled) + return TRUE; /* SMS is accessible*/ + /* + *----------------------------------------------------------------- + * check SIM status + *----------------------------------------------------------------- + */ + + switch (simShrdPrm.SIMStat) + { + case NO_VLD_SS: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimNotIns ); + break; + case SS_INV: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimFail ); + break; +/* case SS_BLKD: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimPukReq ); + break; */ + case SS_URCHB: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimWrong ); + break; + case SS_OK: + switch (simShrdPrm.PINStat) + { + case PS_PIN1: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimPinReq); + break; + + case PS_PIN2: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimPin2Req); + break; + + case PS_PUK1: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimPukReq); + break; + + case PS_PUK2: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimPuk2Req); + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimBsy ); + break; + } + break; + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_SimBsy ); + break; + } + return FALSE; +} +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_checkAccess | ++-------------------------------------------------------------------+ + + PURPOSE : This function checks if SMS is accessible. If an error + condition is found, then *ret is set to either AT_FAIL or + AT_BUSY, otherwise it remains unaffected. The error code + is stored. +*/ +GLOBAL BOOL cmhSMS_checkAccess (T_ACI_CMD_SRC srcId, + T_ACI_RETURN *ret) +{ + /* + *----------------------------------------------------------------- + * check command source + *----------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId) AND (srcId NEQ OWN_SAT)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + TRACE_ERROR ("[cmhSMS_checkAccess]: Cmd Src not valid"); + *ret = AT_FAIL; + return FALSE; + } + + /* + *----------------------------------------------------------------- + * check entity status + *----------------------------------------------------------------- + */ + if( smsShrdPrm.smsEntStat.curCmd NEQ AT_CMD_NONE ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Internal ); + TRACE_ERROR ("[cmhSMS_checkAccess]: Entity is busy"); + *ret = AT_BUSY; + return FALSE; + } + + /* + *----------------------------------------------------------------- + * check SMS access status + *----------------------------------------------------------------- + */ + if (cmhSMS_checkSIM ()) + return TRUE; + + TRACE_ERROR ("[cmhSMS_checkAccess]: Wrong SIM status"); + + *ret = AT_FAIL; + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getPrfRge | ++-------------------------------------------------------------------+ + + PURPOSE : This function gets the number of available profiles for + SMS related parameters. First, the SIM is checked. If + there is no space, then PCM ist checked. +*/ +GLOBAL SHORT cmhSMS_getPrfRge ( void ) +{ + /* TEMPORARY, ONLY FOR TEST PURPOSES: Pretend that the SIM has no SMSP !!! */ + /* smsShrdPrm.aci_sms_parameter.smsParamMaxRec = 0;*/ + + if (smsShrdPrm.aci_sms_parameter.smsParamMaxRec > 0) + { + return (SHORT)smsShrdPrm.aci_sms_parameter.smsParamMaxRec; + } + else + { + return (MAX_FFS_SMSPRFLS); + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_ReadPrmFFS | ++-------------------------------------------------------------------+ + + PURPOSE : This function reads one record of EF_SMSPRFL_ID from FFS. + The processed parameters are controlled by bits in + 'access'. +*/ +static T_ACI_RETURN cmhSMS_ReadPrmFFS (T_ACI_CMD_SRC srcId, + SHORT recNr, + int access) +{ + T_SMS_SET_PRM *pSMSSetPrm; /* points to SMS parameter set */ + int i; + T_SMS_SET_PRM *elem; + T_ACI_FFS_SMSPRFL smsPrfl; +#ifndef _SIMULATION_ + T_FFS_RET ffs_ret; + T_FFS_SIZE ffs_size; +#endif + + TRACE_FUNCTION ("cmhSMS_ReadPrmFFS()"); + +#ifdef _SIMULATION_ + smsPrfl.vldFlag = FFS_SMSPRFL_INVLD; /* trigger a failure since nothing can be read in simulation */ +#else + ffs_size = FFS_fread(ffs_smsprfl_fname[recNr-1], (void*)&smsPrfl, SIZE_FSS_SMSPRFL); + /* + Don't check FFS return for only specif ERRORS, as ACI will not know what + ERROR FFS may send. So, it's walyws better to check for ERROR OK + i.e EFFS_OK Considering this in mind the below condition is changes to + do the same. + */ + if ( ffs_size < EFFS_OK ) + { + TRACE_EVENT_P1("error when reading FFS object \"%s\"", ffs_smsprfl_fname[recNr-1]); + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_MemFail ); + return AT_FAIL; + } +#endif + + if ( smsPrfl.vldFlag EQ FFS_SMSPRFL_INVLD ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_OpNotAllowed ); + return AT_FAIL; + } + + if (access & ACI_PCM_ACCESS_SMSP) + { + if (srcId >= CMD_SRC_MAX) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_UnknownErr ); + return AT_FAIL; + } + else + { + if (set_prm_list EQ NULL) + { + set_prm_list = new_list(); + } + + elem = find_element(set_prm_list, (UBYTE)recNr, cmhSMS_findPrflId); + if (elem EQ NULL) + { + ACI_MALLOC(elem, sizeof(T_SMS_SET_PRM)); + memset(elem, 0, sizeof(T_SMS_SET_PRM)); + insert_list(set_prm_list, elem); + } + if (srcId <= CMD_SRC_NONE) + { + elem->numOfRefs = OWN_MAX; + for (i=0; i < OWN_MAX; i++) + { + smsShrdPrm.pSetPrm[i] = (T_SMS_SET_PRM*) elem; + } + } + else + { + smsShrdPrm.pSetPrm[srcId] = (T_SMS_SET_PRM*) elem; + (smsShrdPrm.pSetPrm[srcId])->numOfRefs++; + } + } + + pSMSSetPrm = (T_SMS_SET_PRM*) elem; + pSMSSetPrm->prflId = (UBYTE)recNr; + +#ifndef _SIMULATION_ + /* + *------------------------------------------------------------- + * restore the service center address + *------------------------------------------------------------- + */ + pSMSSetPrm->sca.c_num = MINIMUM (smsPrfl.CSCAlenSca, MAX_SMS_ADDR_DIG); + memcpy ( pSMSSetPrm->sca.num, smsPrfl.CSCAsca, pSMSSetPrm->sca.c_num); + pSMSSetPrm->sca.ton = smsPrfl.CSCAton; + pSMSSetPrm->sca.npi = smsPrfl.CSCAnpi; + pSMSSetPrm->sca.v_ton = TRUE; + pSMSSetPrm->sca.v_npi = TRUE; + + /* + *------------------------------------------------------------- + * restore the text mode parameters + *------------------------------------------------------------- + */ + pSMSSetPrm->vpRel = smsPrfl.CSMPvprel; + memcpy ( &pSMSSetPrm->vpAbs, smsPrfl.CSMPvpabs, SIZE_FFS_SMSPRFL_VPABS ); + memcpy ( &pSMSSetPrm->vpEnh, smsPrfl.CSMPvpenh, SIZE_FFS_SMSPRFL_VPENH ); + + pSMSSetPrm->msgType = smsPrfl.CSMPfo; + pSMSSetPrm->pid = smsPrfl.CSMPpid; + pSMSSetPrm->dcs = smsPrfl.CSMPdcs; +#endif + } + +#ifndef _SIMULATION_ + if (access & ACI_PCM_ACCESS_CBMP) + { + /* + *------------------------------------------------------------- + * restore the cell broadcast message types and data coding + * schemes + *------------------------------------------------------------- + */ + smsShrdPrm.cbmPrm.cbmMode = smsPrfl.CSCBmode; + + { /* default setting */ + memset (smsShrdPrm.cbmPrm.msgId, DEF_MID_RANGE, sizeof (smsShrdPrm.cbmPrm.msgId)); + memset (smsShrdPrm.cbmPrm.dcsId, DEF_DCS_RANGE, sizeof(smsShrdPrm.cbmPrm.dcsId)); + } + + for ( i = 0; i < MINIMUM(MAX_IDENTS,SIZE_FFS_SMSPRFL_MIDS/2); i++ ) + { + smsShrdPrm.cbmPrm.msgId[i] = ( USHORT )smsPrfl.CSCBmids[2*i] << 8; + smsShrdPrm.cbmPrm.msgId[i] |= ( USHORT )smsPrfl.CSCBmids[2*i+1]; + } + + memcpy ( smsShrdPrm.cbmPrm.dcsId, smsPrfl.CSCBdcss, + MINIMUM(MAX_IDENTS,SIZE_FFS_SMSPRFL_DCSS) ); + + memcpy (smsShrdPrm.cbmPrm.IMSI, smsPrfl.IMSI, MAX_IMSI); + } +#endif + return AT_CMPL; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_WritePrmFFS | ++-------------------------------------------------------------------+ + + PURPOSE : This function writes one record of EF_SMSPRFL_ID to FFS. + The processed parameters are controlled by bits in + 'access'. +*/ +static T_ACI_RETURN cmhSMS_WritePrmFFS (T_ACI_CMD_SRC srcId, + SHORT recNr, + int access) +{ + T_SMS_SET_PRM *pSMSSetPrm; /* points to SMS parameter set */ + T_ACI_FFS_SMSPRFL smsPrfl; + int i; +#ifndef _SIMULATION_ + T_FFS_RET ffs_ret; + T_FFS_SIZE ffs_size; +#endif + + TRACE_FUNCTION ("cmhSMS_WritePrmFFS()"); + + if (access & ACI_PCM_ACCESS_SMSP) + { + if (srcId > CMD_SRC_NONE AND srcId < CMD_SRC_MAX) + { + pSMSSetPrm = smsShrdPrm.pSetPrm[srcId]; + + /* + *------------------------------------------------------------- + * save the service center address + *------------------------------------------------------------- + */ + smsPrfl.CSCAlenSca = MINIMUM ( pSMSSetPrm->sca.c_num, SIZE_FFS_SMSPRFL_SCA ); + memcpy ( smsPrfl.CSCAsca, pSMSSetPrm->sca.num, smsPrfl.CSCAlenSca ); + + i = (int)smsPrfl.CSCAlenSca; + while ( i < SIZE_FFS_SMSPRFL_SCA ) + smsPrfl.CSCAsca[i++] = 0xFF; + + smsPrfl.CSCAton = pSMSSetPrm->sca.ton; + smsPrfl.CSCAnpi = pSMSSetPrm->sca.npi; + + /* + *------------------------------------------------------------- + * store the text mode parameters + *------------------------------------------------------------- + */ + smsPrfl.CSMPfo = pSMSSetPrm->msgType; + + smsPrfl.CSMPvprel = pSMSSetPrm->vpRel; + memcpy ( smsPrfl.CSMPvpabs, &pSMSSetPrm->vpAbs, SIZE_FFS_SMSPRFL_VPABS ); + memcpy ( smsPrfl.CSMPvpenh, &pSMSSetPrm->vpEnh, SIZE_FFS_SMSPRFL_VPENH ); + + smsPrfl.CSMPpid = pSMSSetPrm->pid; + smsPrfl.CSMPdcs = pSMSSetPrm->dcs; + + /* + *------------------------------------------------------------- + * set the valid flag + *------------------------------------------------------------- + */ + smsPrfl.vldFlag = FFS_SMSPRFL_VLD; + } + else + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_UnknownErr ); + return AT_FAIL; + } + } + if (access & ACI_PCM_ACCESS_CBMP) + { + /* + *------------------------------------------------------------- + * save the cell broadcast message types + *------------------------------------------------------------- + */ + smsPrfl.CSCBmode = smsShrdPrm.cbmPrm.cbmMode; + + { /* default setting */ + memset (smsPrfl.CSCBmids, 0xFF, sizeof(smsPrfl.CSCBmids)); + memset (smsPrfl.CSCBdcss, 0xFF, sizeof(smsPrfl.CSCBdcss)); + } + + for ( i = 0; i < MINIMUM(MAX_IDENTS*2,SIZE_FFS_SMSPRFL_MIDS)-1; i += 2 ) + { + smsPrfl.CSCBmids[i] = (UBYTE)(smsShrdPrm.cbmPrm.msgId[i/2] >> 8); + smsPrfl.CSCBmids[i+1] = (UBYTE)smsShrdPrm.cbmPrm.msgId[i/2]; + } + + memcpy ( smsPrfl.CSCBdcss, smsShrdPrm.cbmPrm.dcsId, + MINIMUM(MAX_IDENTS,SIZE_FFS_SMSPRFL_DCSS) ); + + /* + * Save IMSI also in FFS + */ + memcpy (smsPrfl.IMSI, simShrdPrm.imsi.field, simShrdPrm.imsi.c_field); + smsPrfl.vldFlag = FFS_SMSPRFL_VLD; + } + +#ifndef _SIMULATION_ + ffs_ret = FFS_mkdir(FFS_SMSPRFL_PATH); + if (ffs_ret EQ EFFS_OK) + { + TRACE_EVENT_P1("FFS directory \"%s\" successfully created", FFS_SMSPRFL_PATH); + } + else if (ffs_ret EQ EFFS_EXISTS) + { + TRACE_EVENT_P1("FFS directory \"%s\" already exists", FFS_SMSPRFL_PATH); + } + else + { + TRACE_EVENT_P1("error when creating FFS directory \"%s\"", FFS_SMSPRFL_PATH); + } + + ffs_ret = FFS_fwrite(ffs_smsprfl_fname[recNr-1], (void*)&smsPrfl, SIZE_FSS_SMSPRFL); + if (ffs_ret NEQ EFFS_OK) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_MemFail ); + TRACE_EVENT_P1("error when writing FFS object \"%s\"", ffs_smsprfl_fname[recNr-1]); + return AT_FAIL; + } +#endif + + return AT_CMPL; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_ReadParams | ++-------------------------------------------------------------------+ + + PURPOSE : This function reads parameters from SIM and/or PCM. + In case of AT command +CFUN the first record is read to + be informed about storage capability of SIM. +*/ +GLOBAL T_ACI_RETURN cmhSMS_ReadParams (T_ACI_CMD_SRC srcId, + T_ACI_AT_CMD cmd, + SHORT recNr) +{ + T_ACI_RETURN ret = AT_CMPL; + int access = 0; + + TRACE_FUNCTION ("cmhSMS_ReadParams()"); + + smsShrdPrm.smsEntStat.curCmd = cmd; + smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = srcId; + + + if (cmd EQ AT_CMD_CFUN) + { + /* initialization */ + + /* + * Always read CSCB params from FFS so that previously stored mode and dcss + * can also be restored from FFS + */ + access |= ACI_PCM_ACCESS_CBMP; + /*if (!psaSIM_ChkSIMSrvSup( SRV_SMS_Parms ))*/ + access |= ACI_PCM_ACCESS_SMSP; + if (access NEQ 0) + ret = cmhSMS_ReadPrmFFS (CMD_SRC_NONE, 1, access); + + if (psaSIM_ChkSIMSrvSup( SRV_SMS_Parms )) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_SMSP; + ret = cmhSIM_ReadRecordEF (CMD_SRC_NONE, cmd, + SIM_SMSP, 1, 255, + NULL, cmhSMS_InitSMSP); + } + else if (psaSIM_ChkSIMSrvSup( SRV_CBMIdRnge )) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMIR; + ret = cmhSIM_ReadTranspEF (CMD_SRC_NONE, cmd, + SIM_CBMIR, 0, 255, + NULL, cmhSMS_InitSMSP); + } + else if (psaSIM_ChkSIMSrvSup( SRV_CBM_Ident )) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMI; + ret = cmhSIM_ReadTranspEF (CMD_SRC_NONE, cmd, + SIM_CBMI, 0, 255, + NULL, cmhSMS_InitSMSP); + } +#ifdef SIM_TOOLKIT + else if ((psaSIM_ChkSIMSrvSup( SRV_DtaDownlCB )) AND + smsShrdPrm.owner EQ OWN_SAT ) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMID; + ret = cmhSIM_ReadTranspEF (CMD_SRC_NONE, cmd, + SIM_CBMID, 0, 255, + NULL, cmhSMS_InitSMSP); + } +#endif /* of SIM_TOOLKIT */ + } + else + { + + /* TEMPORARY, ONLY FOR TEST PURPOSES: Pretend that the SIM has no SMSP !!! */ + /* smsShrdPrm.aci_sms_parameter.smsParamMaxRec = 0; */ + + /* + * Always read CSCB params from FFS so that previously stored mode and dcss + * can also be restored from FFS + */ + /* normal operation */ + access |= ACI_PCM_ACCESS_CBMP; + /* if (smsShrdPrm.aci_sms_parameter.smsParamMaxRec EQ 0)*/ + access |= ACI_PCM_ACCESS_SMSP; + if (access NEQ 0) + ret = cmhSMS_ReadPrmFFS (srcId, recNr, access); + + if (smsShrdPrm.aci_sms_parameter.smsParamMaxRec > 0) + { + if (recNr <= 0 + OR recNr > (SHORT)smsShrdPrm.aci_sms_parameter.smsParamMaxRec) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_InValMemIdx ); + ret= AT_FAIL; + } + else + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_SMSP; + return cmhSIM_ReadRecordEF (CMD_SRC_NONE, cmd, SIM_SMSP, + (UBYTE)(recNr), + smsShrdPrm.aci_sms_parameter.smsParamRecLen, + NULL, cmhSMS_RdCnfCRES); + } + } + if (smsShrdPrm.cbmPrm.cbmSIMmaxIdRge > 0) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMIR; + return cmhSIM_ReadTranspEF (CMD_SRC_NONE, cmd, SIM_CBMIR, + 0, smsShrdPrm.cbmPrm.cbmSIMmaxIdRge, + NULL, cmhSMS_RdCnfCRES); + } + if (smsShrdPrm.cbmPrm.cbmSIMmaxId > 0) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMI; + return cmhSIM_ReadTranspEF (CMD_SRC_NONE, cmd, SIM_CBMI, + 0, smsShrdPrm.cbmPrm.cbmSIMmaxId, + NULL, cmhSMS_RdCnfCRES); + } + } + if (ret NEQ AT_EXCT) + { + smsShrdPrm.smsEntStat.curCmd = AT_CMD_NONE; + smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = OWN_NONE; + + smsShrdPrm.cbmPrm.cbchOwner = srcId; + psaMMI_Cbch(); + smsShrdPrm.cbmPrm.cbchOwner = OWN_NONE; + } + return ret; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_WriteParams | ++-------------------------------------------------------------------+ + + PURPOSE : This function reads parameters from SIM and/or PCM. + In case of AT command +CFUN the first record is read to + be informed about storage capability of SIM. +*/ +GLOBAL T_ACI_RETURN cmhSMS_WriteParams (T_ACI_CMD_SRC srcId, + T_ACI_AT_CMD cmd, + SHORT recNr) +{ + T_ACI_RETURN ret = AT_CMPL; + int access = 0; + UBYTE data[MAX_SIM_CMD]; + + TRACE_FUNCTION ("cmhSMS_WriteParams()"); + + smsShrdPrm.smsEntStat.curCmd = cmd; + smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = srcId; + + /* TEMPORARY, ONLY FOR TEST PURPOSES: Pretend that the SIM has no SMSP !!! */ + /* smsShrdPrm.aci_sms_parameter.smsParamMaxRec = 0; */ + + /* + * Always write CSCB params to FFS so that mode and dcss + * can later be restored from FFS + */ + access |= ACI_PCM_ACCESS_CBMP; + /*if (smsShrdPrm.aci_sms_parameter.smsParamMaxRec EQ 0)*/ + access |= ACI_PCM_ACCESS_SMSP; + if (access NEQ 0) + ret = cmhSMS_WritePrmFFS (srcId, recNr, access); + + if (smsShrdPrm.aci_sms_parameter.smsParamMaxRec > 0) + { + if (recNr <= 0 OR recNr > (SHORT)smsShrdPrm.aci_sms_parameter.smsParamMaxRec) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cms, CMS_ERR_InValMemIdx ); + ret= AT_FAIL; + } + else + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_SMSP; + cmhSMS_PutPrmSIM (srcId, data, + (int)smsShrdPrm.aci_sms_parameter.smsParamRecLen); + return cmhSIM_WriteRecordEF (CMD_SRC_NONE, cmd, SIM_SMSP, + (UBYTE)(recNr), + smsShrdPrm.aci_sms_parameter.smsParamRecLen, + data, cmhSMS_WrCnfCSAS); + } + } + if (smsShrdPrm.cbmPrm.cbmSIMmaxIdRge > 0) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMIR; + cmhSMS_PutCbmirSIM (srcId, data, + (int)smsShrdPrm.cbmPrm.cbmSIMmaxIdRge * 4); + + return cmhSIM_WriteTranspEF (CMD_SRC_NONE, cmd, SIM_CBMIR, + 0, (UBYTE)(smsShrdPrm.cbmPrm.cbmSIMmaxIdRge * 4), + data, cmhSMS_WrCnfCSAS); + } + if (smsShrdPrm.cbmPrm.cbmSIMmaxId > 0) + { + smsShrdPrm.prmRdSeq = SMS_READ_SIM_CBMI; + cmhSMS_PutCbmiSIM (srcId, data, + (int)smsShrdPrm.cbmPrm.cbmSIMmaxId * 2); + + return cmhSIM_WriteTranspEF (CMD_SRC_NONE, cmd, SIM_CBMI, + 0, (UBYTE)(smsShrdPrm.cbmPrm.cbmSIMmaxId * 2), + data, cmhSMS_WrCnfCSAS); + } + if (ret NEQ AT_EXCT) + { + smsShrdPrm.smsEntStat.curCmd = AT_CMD_NONE; + smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = OWN_NONE; + } + return ret; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_GetPrmSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function extracts the parameters of one record of + EF(SMSP) read from SIM. +*/ +GLOBAL BOOL cmhSMS_GetPrmSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int dataLen) +{ + T_SMS_SET_PRM *pSMSSetPrm; /* points to SMS parameter set */ + T_ACI_SMS_SIM_PARAMS *smsprm; + + TRACE_FUNCTION ("cmhSMS_GetPrmSIM ()"); + + if (data NEQ NULL) + { + pSMSSetPrm = smsShrdPrm.pSetPrm[srcId]; + + smsprm = (T_ACI_SMS_SIM_PARAMS *)&data[(dataLen <= MIN_SMS_PRM_LEN)? + 0: dataLen - MIN_SMS_PRM_LEN]; + + if (smsprm->par_ind EQ NOT_PRESENT_8BIT) + { + + /* ACI-SPR-16431: reset sca number */ + pSMSSetPrm->sca.c_num = 0; + memset(pSMSSetPrm->sca.num, 0xFF, sizeof(pSMSSetPrm->sca.num)); + /* end of ACI-SPR-16431: reset sca number */ + + return TRUE; /* record is empty */ + } + + if ((smsprm->par_ind & SIM_SMSP_V_SCA) EQ 0) + { + cmh_demergeTOA (smsprm->sca_ton_npi, &pSMSSetPrm->sca.ton, + &pSMSSetPrm->sca.npi); + pSMSSetPrm->sca.c_num = (UBYTE)cmh_unpackBCD (pSMSSetPrm->sca.num, + smsprm->sca_addr, + (USHORT)(smsprm->sca_length - 1)); + pSMSSetPrm->sca.v_ton = TRUE; + pSMSSetPrm->sca.v_npi = TRUE; + + } + if ((smsprm->par_ind & SIM_SMSP_V_PID) EQ 0) + pSMSSetPrm->pid = smsprm->pid; + + if ((smsprm->par_ind & SIM_SMSP_V_DCS) EQ 0) + pSMSSetPrm->dcs = smsprm->dcs; + + if ((smsprm->par_ind & SIM_SMSP_V_VPREL) EQ 0) + { + pSMSSetPrm->vpRel = smsprm->vp_rel; + pSMSSetPrm->msgType &= ~TP_VPF_MASK; + pSMSSetPrm->msgType |= TP_VPF_RELATIVE; + } + else if ((pSMSSetPrm->msgType & TP_VPF_MASK) EQ TP_VPF_RELATIVE) + pSMSSetPrm->msgType &= ~TP_VPF_MASK; + + return TRUE; + } + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_PutPrmSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function conbiness the parameters for one record of + EF(SMSP) to be written to SIM. +*/ +GLOBAL BOOL cmhSMS_PutPrmSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int maxDataLen) +{ + T_SMS_SET_PRM *pSMSSetPrm; /* points to SMS parameter set */ + T_ACI_SMS_SIM_PARAMS *smsprm; + size_t datalen; + + TRACE_FUNCTION ("cmhSMS_PutPrmSIM ()"); + + if (data NEQ NULL) + { + pSMSSetPrm = smsShrdPrm.pSetPrm[srcId]; + + if (maxDataLen < MIN_SMS_PRM_LEN) + { + datalen = MIN_SMS_PRM_LEN; + smsprm = (T_ACI_SMS_SIM_PARAMS *)data; + } + else + { + datalen = (size_t)maxDataLen; + smsprm = (T_ACI_SMS_SIM_PARAMS *)&data[datalen - MIN_SMS_PRM_LEN]; + } + memset (data, NOT_PRESENT_8BIT, datalen); + + /* + *------------------------------------------------------------- + * set the service center address + *------------------------------------------------------------- + */ + if (pSMSSetPrm->sca.c_num > 0) + { + smsprm->sca_ton_npi = cmh_mergeTOA (pSMSSetPrm->sca.ton, + pSMSSetPrm->sca.npi); + smsprm->sca_length = (UBYTE)cmh_packBCD (smsprm->sca_addr, + pSMSSetPrm->sca.num, + (USHORT)MINIMUM(pSMSSetPrm->sca.c_num, + MAX_SMS_ADDR_DIG)) + 1; + smsprm->par_ind &= ~SIM_SMSP_V_SCA; + } + + /* + *------------------------------------------------------------- + * set PID, DCS and VP-REL + *------------------------------------------------------------- + */ + + smsprm->pid = pSMSSetPrm->pid; + smsprm->par_ind &= ~SIM_SMSP_V_PID; + + smsprm->dcs = pSMSSetPrm->dcs; + smsprm->par_ind &= ~SIM_SMSP_V_DCS; + + if ((pSMSSetPrm->msgType & TP_VPF_MASK) EQ TP_VPF_RELATIVE) + { + smsprm->vp_rel = pSMSSetPrm->vpRel; + smsprm->par_ind &= ~SIM_SMSP_V_VPREL; + } + return TRUE; + } + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_GetCbmirSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function extracts the parameters of EF(CBMIR) + read from SIM. +*/ +GLOBAL BOOL cmhSMS_GetCbmirSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int dataLen) +{ + T_ACI_CBM_SIM_MID_RANGE *mid_range; + USHORT lower_mid, upper_mid; + int mid_entry; + + TRACE_FUNCTION ("cmhSMS_GetCbmirSIM ()"); + + if (data NEQ NULL) + { +/* Please be aware that to keep simulation test cases as less changed as + possible lets assume that IMSI and CBMs stored in the FFS and from SIM + card are the same, since we cannot access FFS under SIMULATION*/ +#ifndef _SIMULATION_ + /* + * The CSCB parameters read from FFS should be restored only if the same SIM + * is inserted ( check IMSI to ensure the same SIM), otherwise reset the CSCB + * parameters to default values + */ + if (memcmp (smsShrdPrm.cbmPrm.IMSI, simShrdPrm.imsi.field, simShrdPrm.imsi.c_field) NEQ 0) + { + smsShrdPrm.cbmPrm.cbmMode = CBCH_ACCEPT; + memset (smsShrdPrm.cbmPrm.msgId, DEF_MID_RANGE, + sizeof (smsShrdPrm.cbmPrm.msgId)); + memset (smsShrdPrm.cbmPrm.dcsId, DEF_DCS_RANGE, + sizeof(smsShrdPrm.cbmPrm.dcsId)); + return FALSE; + } +#endif + mid_range = (T_ACI_CBM_SIM_MID_RANGE *)data; + mid_entry = 0; + + while (smsShrdPrm.cbmPrm.cbmFoundIds < MAX_IDENTS/2 AND + mid_entry < dataLen) + { + lower_mid = (USHORT)mid_range->lowerLSB | + ((USHORT)mid_range->lowerMSB << 8); + upper_mid = (USHORT)mid_range->upperLSB | + ((USHORT)mid_range->upperMSB << 8); + mid_range++; + mid_entry += 4; + + if (lower_mid NEQ NOT_PRESENT_16BIT OR + upper_mid NEQ NOT_PRESENT_16BIT) + { +/* Please be aware that to keep simulation test cases as less changed as + possible lets assume that CBMs stored in the FFS and from SIM + card are the same, since we cannot access FFS under SIMULATION*/ +#ifndef _SIMULATION_ + + /* + * If the msg ids are same that in FFS and SIM, then restore else reset + * to default values + */ + if (smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2] EQ lower_mid + AND smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2 + 1] EQ upper_mid) + { + smsShrdPrm.cbmPrm.cbmFoundIds++; + } + else + { + smsShrdPrm.cbmPrm.cbmMode = CBCH_ACCEPT; + memset (smsShrdPrm.cbmPrm.msgId, DEF_MID_RANGE, + sizeof (smsShrdPrm.cbmPrm.msgId)); + memset (smsShrdPrm.cbmPrm.dcsId, DEF_DCS_RANGE, + sizeof(smsShrdPrm.cbmPrm.dcsId)); + + smsShrdPrm.cbmPrm.cbmFoundIds = 0; + return FALSE; + } +#else /* Just for simulation - copy data, received from SIM */ + smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2] = lower_mid; + smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2 + 1] = upper_mid; + smsShrdPrm.cbmPrm.cbmFoundIds++; +#endif + } + } + return TRUE; + } + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_PutCbmirSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function conbines the parameters of EF(CBMIR) + to be written to SIM. +*/ +GLOBAL BOOL cmhSMS_PutCbmirSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int maxDataLen) +{ + T_ACI_CBM_SIM_MID_RANGE *mid_range; + USHORT lower_mid, upper_mid; + int mid_entry; + + TRACE_FUNCTION ("cmhSMS_PutCbmirSIM ()"); + + if (data NEQ NULL) + { + memset (data, NOT_PRESENT_8BIT, maxDataLen); + + mid_range = (T_ACI_CBM_SIM_MID_RANGE *)data; + mid_entry = 0; + + while (smsShrdPrm.cbmPrm.cbmFoundIds < MAX_IDENTS/2 AND + mid_entry < maxDataLen) + { + lower_mid = smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2]; + upper_mid = smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2 + 1]; + smsShrdPrm.cbmPrm.cbmFoundIds++; + + if (lower_mid NEQ NOT_PRESENT_16BIT OR + upper_mid NEQ NOT_PRESENT_16BIT) + { + mid_range->lowerLSB = (UBYTE)lower_mid; + mid_range->lowerMSB = (UBYTE)(lower_mid >> 8); + mid_range->upperLSB = (UBYTE)upper_mid; + mid_range->upperMSB = (UBYTE)(upper_mid >> 8); + mid_range++; + mid_entry += 4; + } + } + return TRUE; + } + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_GetCbmiSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function extracts the parameters of one record of + EF(SMSP) read from SIM. +*/ +GLOBAL BOOL cmhSMS_GetCbmiSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int dataLen) +{ + T_ACI_CBM_SIM_MID_LIST **mid_list; + USHORT mid; + int mid_entry; + + TRACE_FUNCTION ("cmhSMS_GetCbmiSIM ()"); + + if (data NEQ NULL) + { + + /* Please be aware that to keep simulation test cases as less changed as + possible lets assume that IMSI and CBMs stored in the FFS and from SIM + card are the same, since we cannot access FFS under SIMULATION*/ +#ifndef _SIMULATION_ + /* + * The CSCB parameters read from FFS should be restored only if the same SIM + * is inserted ( check IMSI to ensure the same SIM), otherwise reset the CSCB + * parameters to default values + */ + if (memcmp (smsShrdPrm.cbmPrm.IMSI, simShrdPrm.imsi.field, simShrdPrm.imsi.c_field) + NEQ 0) + { + smsShrdPrm.cbmPrm.cbmMode = CBCH_ACCEPT; + memset (smsShrdPrm.cbmPrm.msgId, DEF_MID_RANGE, + sizeof (smsShrdPrm.cbmPrm.msgId)); + memset (smsShrdPrm.cbmPrm.dcsId, DEF_DCS_RANGE, + sizeof(smsShrdPrm.cbmPrm.dcsId)); + return FALSE; + } +#endif + mid_list = (T_ACI_CBM_SIM_MID_LIST **)&data; + mid_entry = 0; + + while (smsShrdPrm.cbmPrm.cbmFoundIds < MAX_IDENTS/2 AND + mid_entry < dataLen) + { + mid = (USHORT)(*mid_list)->LSB | + ((USHORT)(*mid_list)->MSB << 8); + data += 2; /* overcome TI alignment problem */ + mid_entry += 2; + + if (mid NEQ NOT_PRESENT_16BIT) + { +/* Please be aware that to keep simulation test cases as less changed as + possible lets assume that CBMs stored in the FFS and from SIM + card are the same, since we cannot access FFS under SIMULATION*/ +#ifndef _SIMULATION_ + /* + * If the msg ids are same that in FFS and SIM, then restore else reset + * to default values + */ + if (smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2] EQ mid + AND smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2 + 1] EQ mid) + { + smsShrdPrm.cbmPrm.cbmFoundIds++; + } + else + { + smsShrdPrm.cbmPrm.cbmMode = CBCH_ACCEPT; + memset (smsShrdPrm.cbmPrm.msgId, DEF_MID_RANGE, + sizeof (smsShrdPrm.cbmPrm.msgId)); + memset (smsShrdPrm.cbmPrm.dcsId, DEF_DCS_RANGE, + sizeof(smsShrdPrm.cbmPrm.dcsId)); + + smsShrdPrm.cbmPrm.cbmFoundIds = 0; + return FALSE; + } +#else /* Just for simulation - copy data, received from SIM */ + smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2] = + smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2 + 1] = mid; + smsShrdPrm.cbmPrm.cbmFoundIds++; +#endif + } + } + return TRUE; + } + return FALSE; +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_PutCbmiSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function conbines the parameters of EF(CBMI) + to be written to SIM. +*/ +GLOBAL BOOL cmhSMS_PutCbmiSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int maxDataLen) +{ + T_ACI_CBM_SIM_MID_LIST **mid_list; + USHORT lower_mid, upper_mid; + UBYTE mid_entry; + + TRACE_FUNCTION ("cmhSMS_PutCbmiSIM ()"); + + if (data NEQ NULL) + { + memset (data, NOT_PRESENT_8BIT, maxDataLen); + + mid_list = (T_ACI_CBM_SIM_MID_LIST **)&data; + mid_entry = 0; + + while (smsShrdPrm.cbmPrm.cbmFoundIds < MAX_IDENTS/2 AND + mid_entry < maxDataLen) + { + lower_mid = smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2]; + upper_mid = smsShrdPrm.cbmPrm.msgId[smsShrdPrm.cbmPrm.cbmFoundIds * 2 + 1]; + smsShrdPrm.cbmPrm.cbmFoundIds++; + + if (lower_mid NEQ NOT_PRESENT_16BIT OR + upper_mid NEQ NOT_PRESENT_16BIT) + { + while (lower_mid <= upper_mid AND mid_entry < maxDataLen) + { + (*mid_list)->LSB = (UBYTE)lower_mid; + (*mid_list)->MSB = (UBYTE)(lower_mid >> 8); + lower_mid++; + data += 2; /* overcome TI alignment problem */ + mid_entry += 2; + } + } + } + return TRUE; + } + return FALSE; +} + +#ifdef SIM_TOOLKIT + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_FileUpdate | ++-------------------------------------------------------------------+ + + PURPOSE : This function processes the primitive SIM_FILE_UPDATE_IND + to update the SMS parameters stored on the SIM. +*/ +GLOBAL BOOL cmhSMS_FileUpdate (int ref, T_SIM_FILE_UPDATE_IND *fu) +{ + BOOL found = FALSE; + int i; + + TRACE_FUNCTION ("cmhSMS_FileUpdate ()"); + + for (i = 0; i < (int)fu->val_nr; i++) + { + if (!found AND + (fu->file_id[i] EQ SIM_SMSP OR + fu->file_id[i] EQ SIM_CBMI OR + fu->file_id[i] EQ SIM_CBMIR OR + fu->file_id[i] EQ SIM_CBMID)) + { + found = TRUE; + } + if (fu->file_id[i] EQ SIM_SMS) + { + smsShrdPrm.aci_sms_parameter.simTotal = 0; + smsShrdPrm.aci_sms_parameter.simUsed = 0; + } + } + if (found) + { + smsShrdPrm.cbmPrm.cbmFoundIds = 0; /* new CBMI(R) */ + + if (cmhSMS_ReadParams (OWN_SAT, AT_CMD_CFUN, 1) EQ AT_EXCT) + { + smsShrdPrm.accessEnabled = FALSE; + + simShrdPrm.fuRef = ref; + return FALSE; /* reading files */ + } + else + return TRUE; /* nothing to do */ + } + else + { + simShrdPrm.fuRef = -1; /* nothing to do */ + return TRUE; + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_GetCbDtaDwnlSIM | ++-------------------------------------------------------------------+ + + PURPOSE : This function extracts the parameters of CBMID record of + EF(CBMID) read from SIM. +*/ +GLOBAL BOOL cmhSMS_GetCbDtaDwnlSIM (T_ACI_CMD_SRC srcId, + UBYTE *data, + int dataLen) +{ + T_ACI_CBM_SIM_MID_LIST **mid_list; + USHORT mid; + int mid_entry; + + TRACE_FUNCTION ("cmhSMS_GetCbDtaDwnlSIM ()"); + + if (data NEQ NULL) + { + smsShrdPrm.cbmPrm.CBDtaDwnlFoundIds = 0; + memset (smsShrdPrm.cbmPrm.CBDtaDwnlIdent, NOT_PRESENT_8BIT, + sizeof (smsShrdPrm.cbmPrm.CBDtaDwnlIdent)); + + mid_list = (T_ACI_CBM_SIM_MID_LIST **)&data; + mid_entry = 0; + + while (smsShrdPrm.cbmPrm.CBDtaDwnlFoundIds < MAX_IDENTS_SAT AND + mid_entry < dataLen) + { + mid = (USHORT)(*mid_list)->LSB | + ((USHORT)(*mid_list)->MSB << 8); + data += 2; /* overcome TI alignment problem */ + mid_entry += 2; + + if (mid NEQ NOT_PRESENT_16BIT) + { + smsShrdPrm.cbmPrm.CBDtaDwnlIdent[smsShrdPrm.cbmPrm.CBDtaDwnlFoundIds] = mid; + smsShrdPrm.cbmPrm.CBDtaDwnlFoundIds++; + } + } + return TRUE; + } + return FALSE; +} + +#endif /*of SIM_TOOLKIT */ + + + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_decodeMsg | ++--------------------------------------------------------------------+ + + PURPOSE : decodes a SM in two steps + +*/ +GLOBAL UBYTE* cmhSMS_decodeMsg (T_sms_sdu *sms_sdu, T_rp_addr* rp_addr, + UBYTE vt_mti) +{ + UBYTE ccdRet; + UBYTE direction; + UBYTE recover_from_error; + + BUF_tpdu sim_buf; /* source for the second decoding */ + + TRACE_FUNCTION("cmhSMS_decodeMsg ()"); + + if( sms_sdu->l_buf EQ 0) + { + TRACE_EVENT("empty SDU: no decoding"); + return(NULL); + } + + CCD_START; + { + + MCAST( sim_pdu, SIM_PDU ); /* sim_pdu points to _decodedMsg */ + /*memset( sim_pdu, 0, sizeof (T_SIM_PDU) ); */ + + /* decoding outer layer */ + ccdRet = ccd_decodeMsg ( CCDENT_SMS, + BOTH /* doesn't work with DOWNLINK!!! */, + (T_MSGBUF *) sms_sdu, + (UBYTE *) _decodedMsg, /* target */ + SMS_VT_SIM_PDU); + + if ( (ccdRet NEQ ccdOK) OR (!sim_pdu->v_tpdu) + OR (_decodedMsg[0] NEQ SMS_VT_SIM_PDU) ) + { + TRACE_EVENT_P1("CCD Decoding Error: %d", ccdRet); + CCD_END; + return NULL; + } + + memcpy(rp_addr, &sim_pdu->rp_addr, sizeof(T_rp_addr) ); + + memcpy(&sim_buf, &sim_pdu->tpdu, sizeof(BUF_tpdu) ); + + /*memset( _decodedMsg, 0, sizeof (T_TP_SUBMIT) ); */ + + if (vt_mti EQ SMS_VT_SUBMIT) + { + /* for decoding of SMS-SUBMIT (in response to +CMGR, +CMGL) */ + direction = UPLINK; + } + else + { + direction = DOWNLINK; + } + + /* decoding inner layer */ + ccdRet = ccd_decodeMsg ( CCDENT_SMS, + direction, + (T_MSGBUF *) &sim_buf, + (UBYTE *) _decodedMsg, /* target */ + vt_mti ); + + if (ccdRet EQ ccdWarning) + recover_from_error = TRUE; /* Try to recover if a ccdWarning occoured */ + else + recover_from_error = FALSE; + + if ((ccdRet EQ ccdError) OR (ccdRet EQ ccdWarning)) + { + UBYTE ccd_err; + USHORT parlist [6]; + + TRACE_EVENT_P1 ("ccd_decodeMsg(): %02x", ccdRet); + /* + * get the first error + */ + ccd_err = ccd_getFirstError (CCDENT_SMS, parlist); + + /* + * Error Handling + */ + do + { +#ifndef NTRACE /* save some ROM */ + char *errstr; + + switch (ccd_err) + { + case ERR_NO_MORE_ERROR: errstr= "the end of the error list is reached";break; + case ERR_INVALID_CALC: errstr= "calculation of the element repeat value failed";break; + case ERR_PATTERN_MISMATCH:errstr= "a bit pattern was not expected";break; + case ERR_COMPREH_REQUIRED:errstr= "check for comprehension required failed";break; + case ERR_IE_NOT_EXPECTED: errstr= "an information element was not expected";break; + case ERR_IE_SEQUENCE: errstr= "wrong sequence of information elements";break; + case ERR_MAX_IE_EXCEED: errstr= "maximum amount of repeatable information elements has exceeded";break; + case ERR_MAX_REPEAT: errstr= "a repeatable element occurs too often in the message";break; + case ERR_MAND_ELEM_MISS: errstr= "a mandatory information element is missing";break; + case ERR_INVALID_MID: errstr= "the message ID is not correct";break; + case ERR_INVALID_TYPE: errstr= "the information element is not a spare padding";break; + case ERR_EOC_TAG_MISSING: errstr= "indefinite length is specified for the ASN.1-BER but the end tag is missing";break; + case ERR_INTERNAL_ERROR: errstr= "an internal CCD error occured ";break; + default: errstr= "unknown error";break; + } + if (ccdRet EQ ccdError) + { + TRACE_EVENT_P2 ("ERR: %u %s", ccd_err, errstr); + } + else if (ccdRet EQ ccdWarning) + { + TRACE_EVENT_P2 ("WRN: %u %s", ccd_err, errstr); + } +#endif /* NTRACE */ + + if (ccdRet EQ ccdWarning) + { + switch (ccd_err) + { + case ERR_PATTERN_MISMATCH: /* recoverable warnings */ + case ERR_COMPREH_REQUIRED: + case ERR_INTERNAL_ERROR: + break; + default: + recover_from_error = FALSE; /* in all other cases reset the recover flag */ + } + } + + ccd_err = ccd_getNextError (CCDENT_SMS, parlist); + }while (ccd_err NEQ ERR_NO_MORE_ERROR); + } + + if ( (ccdRet EQ ccdError) OR + ((ccdRet EQ ccdWarning) AND (recover_from_error EQ FALSE)) OR /* not possible to recover */ + (_decodedMsg[0] NEQ vt_mti) ) + { + TRACE_EVENT_P1("CCD Decoding Error Stage 2: %d", ccdRet); + CCD_END; + return NULL; + } + else if ((ccdRet EQ ccdWarning) AND (recover_from_error EQ TRUE)) + { + TRACE_EVENT ("recovered from warning"); + } + } + CCD_END; + + return _decodedMsg; +} + + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_codeMsg | ++--------------------------------------------------------------------+ + + PURPOSE : encodes a SM in two steps + +*/ +GLOBAL void cmhSMS_codeMsg (T_sms_sdu *sms_sdu, UBYTE tp_vt_mti, + T_rp_addr* sc_addr, UBYTE tp_mti, + UBYTE* decoded_pdu ) +{ + BUF_tpdu sim_buf; /* target for first coding */ + UBYTE direction; + + TRACE_FUNCTION ("cmhSMS_codeMsg()"); + + + CCD_START; + { + UBYTE ccdRet; + + MCAST( sim_pdu, SIM_PDU ); + + /* source of outer encoding */ + memset( sim_pdu, 0, sizeof (T_SIM_PDU) ); + + /* target of outer encoding */ + /* memset( sms_sdu, 0, sizeof (T_sms_sdu) ); */ + sms_sdu->o_buf = 0; + sms_sdu->l_buf = SIM_PDU_LEN << 3; + + sim_pdu->tp_vt_mti = SMS_VT_SIM_PDU; + sim_pdu->tp_mti = tp_mti; + + /* service center address exists */ + if (sc_addr) + { + memcpy(&sim_pdu->rp_addr, sc_addr, sizeof(T_rp_addr)); + sim_pdu->rp_addr.v_ton = 1; + sim_pdu->rp_addr.v_npi = 1; + } + + /* pdu data exists */ + if (decoded_pdu) + { + /* target of inner encoding */ + /* memset(sim_buf, 0, sizeof(BUF_tpdu)); */ + sim_buf.o_tpdu = 0; + sim_buf.l_tpdu = (sizeof(BUF_tpdu)) << 3; + + if (tp_vt_mti EQ SMS_VT_DELIVER) + { + /* for encoding of SMS-DELIVER (only in +CMGW) */ + direction = DOWNLINK; + } + else + { + direction = UPLINK; + } + + /* encoding inner layer */ + ccdRet = ccd_codeMsg (CCDENT_SMS, + direction, + (T_MSGBUF *) &sim_buf, /* target */ + (UBYTE *) decoded_pdu, + tp_vt_mti); + + if ( ccdRet NEQ ccdOK ) + { + TRACE_EVENT_P1("CCD Coding Error: %d", ccdRet); + CCD_END; + return; + } + if (sim_buf.l_tpdu EQ 0) + { + TRACE_EVENT("Encoded length is zero"); + } + + memcpy(&sim_pdu->tpdu, &sim_buf, sizeof(BUF_tpdu)); + sim_pdu->v_tpdu = 1; /* set validy flag */ + } + + /* encoding outer layer */ + ccdRet = ccd_codeMsg (CCDENT_SMS, + UPLINK, + (T_MSGBUF *) sms_sdu, /* target */ + (UBYTE *) sim_pdu, + SMS_VT_SIM_PDU); + + if ( ccdRet NEQ ccdOK ) + { + TRACE_EVENT_P1("CCD Coding Error: %d", ccdRet); + CCD_END; + return; + } + if (sms_sdu->l_buf EQ 0) + { + TRACE_EVENT("Encoded length is zero"); + } + } + CCD_END; +} + + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_cpyDeliver | ++--------------------------------------------------------------------+ + + PURPOSE : converts a SMS-DELIVER message to the T_ACI_CMGL_SM + structure + +*/ +GLOBAL BOOL cmhSMS_cpyDeliver ( T_ACI_CMGL_SM * sm, T_sms_sdu * sms_sdu ) +{ + T_rp_addr rp_addr; + UBYTE* message; + T_TP_DELIVER *sms_deliver; + UBYTE alphabet; + + TRACE_FUNCTION("cmhSMS_cpyDeliver()"); + + message = cmhSMS_decodeMsg(sms_sdu, &rp_addr, SMS_VT_DELIVER); + + if (message EQ NULL) + { + sm->stat = SMS_STAT_Invalid; + return (FALSE); + } + + if ( message[0] NEQ SMS_VT_DELIVER) + { + TRACE_EVENT_P1("wrong VTI = %x", message[0]); + } + + sms_deliver = (T_TP_DELIVER*)message; + + /* + *----------------------------------------------------------------- + * process originator address + *----------------------------------------------------------------- + */ + if (sms_deliver->tp_oa.ton EQ SMS_TON_ALPHANUMERIC) + { + UBYTE i,j = 0; + UBYTE dest_len; + CHAR address_buf[MAX_SMS_ADDR_DIG/2]; + + for (i = 0 ; i < sms_deliver->tp_oa.digits ; i=i+2) + { + address_buf[j] = (UBYTE)(sms_deliver->tp_oa.num[i+1] << 4) + (UBYTE)(sms_deliver->tp_oa.num[i]); + j++; + } + + dest_len = utl_cvt7To8 ( (UBYTE*)address_buf, j, (UBYTE*)sm->adress, 0); + sm -> adress[dest_len] = '\0'; + } + else + cmhSMS_getAdrStr ( sm -> adress, + MAX_SMS_NUM_LEN - 1, + sms_deliver->tp_oa.num, + sms_deliver->tp_oa.digits ); + + sm -> toa.ton = cmhSMS_getTon ( sms_deliver->tp_oa.ton ); + sm -> toa.npi = cmhSMS_getNpi ( sms_deliver->tp_oa.npi ); + + /* + *----------------------------------------------------------------- + * process service center address + *----------------------------------------------------------------- + */ + cmhSMS_getAdrStr ( sm -> sca, + MAX_SMS_NUM_LEN - 1, + rp_addr.num, + rp_addr.c_num); + + sm -> tosca.ton = cmhSMS_getTon ( rp_addr.ton ); + sm -> tosca.npi = cmhSMS_getNpi ( rp_addr.npi ); + + + /* + *----------------------------------------------------------------- + * process alphanumerical phonebook entry + *----------------------------------------------------------------- + */ + psaCC_phbMfwSrchNumPlnTxt ( sm -> adress, &sm -> alpha ); + + /* + *----------------------------------------------------------------- + * process first octet + *----------------------------------------------------------------- + */ + sm -> fo = sms_sdu->buf[sms_sdu->buf[0] + 1]; + + /* + *----------------------------------------------------------------- + * process protocol identifier + *----------------------------------------------------------------- + */ + sm -> pid = sms_deliver->tp_pid; + + /* + *----------------------------------------------------------------- + * process data coding scheme + *----------------------------------------------------------------- + */ + sm -> dcs = sms_deliver->tp_dcs; + + + /* + *----------------------------------------------------------------- + * process short message data, expanding from 7 to 8 bit + *----------------------------------------------------------------- + */ + + if (sms_deliver->v_tp_ud) + { + /* user data */ + cmhSMS_expdSmsPp ( 0, + sms_deliver->tp_dcs, + sms_deliver->tp_ud.data, + sms_deliver->tp_ud.length, + sm -> data.data, + &sm->data.len ); + + sm->udh.len = 0; + } + else + { + alphabet = cmhSMS_getAlphabetPp ( sms_deliver->tp_dcs ); + + /* user data header */ + memcpy (sm->udh.data, sms_deliver->tp_udh_inc.tp_udh.data, + sms_deliver->tp_udh_inc.tp_udh.c_data); + sm->udh.len = sms_deliver->tp_udh_inc.tp_udh.c_data; + + /* user data (only user data can be 7bit data!!!) */ + cmhSMS_expdSmsPp ( (UBYTE)(sm->udh.len+1), + sms_deliver->tp_dcs, + sms_deliver->tp_udh_inc.data, + sms_deliver->tp_udh_inc.length, /* ACI-SPR-9440 */ + sm->data.data, + &sm->data.len ); + + /* 7-bit data */ + if (alphabet EQ 0x00) + { + sm->data.len = sms_deliver->tp_udh_inc.length - ((sm->udh.len+1)*8)/7; + + /* minus space for the fill bits */ + if (((sm->udh.len+1)*8)%7 NEQ 0) sm->data.len--; + } + /* 8-bit data */ + else + { + sm->data.len = sms_deliver->tp_udh_inc.length-(sm->udh.len+1); + } + } + + /* + *----------------------------------------------------------------- + * process service center time stamp + *----------------------------------------------------------------- + */ + sm -> vp_rel = 0; + memset ( &sm->vp_enh, 0, sizeof(T_ACI_VP_ENH) ); + + cmhSMS_setVpabsCmh ( &sm -> scts, + (T_tp_vp_abs*) &sms_deliver->tp_scts ); + + return (TRUE); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_cpySubmit | ++--------------------------------------------------------------------+ + + PURPOSE : converts a SMS-SUBMIT message to the T_ACI_CMGL_SM + structure + +*/ +GLOBAL BOOL cmhSMS_cpySubmit ( T_ACI_CMGL_SM * sm, T_sms_sdu * sms_sdu ) +{ + T_rp_addr rp_addr; + UBYTE* message; + T_TP_SUBMIT *sms_submit; + UBYTE alphabet; + + TRACE_FUNCTION("cmhSMS_cpySubmit()"); + + message = cmhSMS_decodeMsg(sms_sdu, &rp_addr, SMS_VT_SUBMIT); + + if (message EQ NULL) + { + sm->stat = SMS_STAT_Invalid; + return (FALSE); + } + + if ( message[0] NEQ SMS_VT_SUBMIT) + { + TRACE_EVENT_P1("wrong VTI = %x", message[0]); + } + + sms_submit = (T_TP_SUBMIT*)message; + + + /* + *----------------------------------------------------------------- + * process recepient address + *----------------------------------------------------------------- + */ + if (sms_submit->tp_da.ton EQ SMS_TON_ALPHANUMERIC) + { + UBYTE i,j = 0; + UBYTE dest_len; + CHAR address_buf[MAX_SMS_ADDR_DIG/2]; + + for (i = 0 ; i < sms_submit->tp_da.digits ; i=i+2) + { + address_buf[j] = (UBYTE)(sms_submit->tp_da.num[i+1] << 4) + (UBYTE)(sms_submit->tp_da.num[i]); + j++; + } + + dest_len = utl_cvt7To8 ( (UBYTE*)address_buf, j, (UBYTE*)sm->adress, 0); + sm -> adress[dest_len] = '\0'; + } + else + cmhSMS_getAdrStr ( sm -> adress, + MAX_SMS_NUM_LEN - 1, + sms_submit->tp_da.num, + sms_submit->tp_da.digits ); + + sm -> toa.ton = cmhSMS_getTon ( sms_submit->tp_da.ton ); + sm -> toa.npi = cmhSMS_getNpi ( sms_submit->tp_da.npi ); + + /* + *----------------------------------------------------------------- + * process service center address + *----------------------------------------------------------------- + */ + cmhSMS_getAdrStr ( sm -> sca, + MAX_SMS_NUM_LEN - 1, + rp_addr.num, + rp_addr.c_num); + + sm -> tosca.ton = cmhSMS_getTon ( rp_addr.ton ); + sm -> tosca.npi = cmhSMS_getNpi ( rp_addr.npi ); + + + /* + *----------------------------------------------------------------- + * process alphanumerical phonebook entry + *----------------------------------------------------------------- + */ + psaCC_phbMfwSrchNumPlnTxt ( sm -> adress, &sm -> alpha ); + + /* + *----------------------------------------------------------------- + * process first octet + *----------------------------------------------------------------- + */ + sm -> fo = sms_sdu->buf[sms_sdu->buf[0] + 1]; + + /* + *----------------------------------------------------------------- + * process protocol identifier + *----------------------------------------------------------------- + */ + sm -> pid = sms_submit->tp_pid; + + /* + *----------------------------------------------------------------- + * process data coding scheme + *----------------------------------------------------------------- + */ + sm -> dcs = sms_submit->tp_dcs; + + /* + *----------------------------------------------------------------- + * process short message data, expanding from 7 to 8 bit + *----------------------------------------------------------------- + */ + + if (sms_submit->v_tp_ud) + { + /* user data */ + cmhSMS_expdSmsPp ( 0, + sms_submit->tp_dcs, + sms_submit->tp_ud.data, + sms_submit->tp_ud.length, /* ACI-SPR-9440 */ + sm->data.data, + &sm->data.len ); + + sm->udh.len = 0; + } + else + { + alphabet = cmhSMS_getAlphabetPp ( sms_submit->tp_dcs ); + + /* user data header */ + memcpy (sm->udh.data, sms_submit->tp_udh_inc.tp_udh.data, + sms_submit->tp_udh_inc.tp_udh.c_data); + sm->udh.len = sms_submit->tp_udh_inc.tp_udh.c_data; + + /* user data (only user data can be 7bit data!!!) */ + cmhSMS_expdSmsPp ( (UBYTE)(sm->udh.len+1), + sms_submit->tp_dcs, + sms_submit->tp_udh_inc.data, + sms_submit->tp_udh_inc.length, /* ACI-SPR-9440 */ + sm->data.data, + &sm->data.len ); + + /* 7-bit data */ + if (alphabet EQ 0x00) + { + sm->data.len = sms_submit->tp_udh_inc.length - ((sm->udh.len+1)*8)/7; + + /* minus space for the fill bits */ + if (((sm->udh.len+1)*8)%7 NEQ 0) sm->data.len--; + } + /* 8-bit data */ + else + { + sm->data.len = sms_submit->tp_udh_inc.length-(sm->udh.len+1); + } + } + + /* + *----------------------------------------------------------------- + * process validity period + *----------------------------------------------------------------- + */ + if (sms_submit->v_tp_vp_abs) + { + cmhSMS_setVpabsCmh ( &sm->scts, &sms_submit->tp_vp_abs ); + sm -> vp_rel = 0; + memset ( &sm->vp_enh, 0, sizeof(T_ACI_VP_ENH) ); + } + else if (sms_submit->v_tp_vp_enh) + { + cmhSMS_setVpenhCmh ( &sm->vp_enh, &sms_submit->tp_vp_enh ); + sm -> vp_rel = 0; + memset ( &sm->scts, 0, sizeof(T_ACI_VP_ABS) ); + } + else + { + sm -> vp_rel = sms_submit->tp_vp_rel; + memset ( &sm -> scts, 0, sizeof(T_ACI_VP_ABS) ); + memset ( &sm -> vp_enh, 0, sizeof(T_ACI_VP_ENH) ); + } + return (TRUE); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_cpyMsgInd | ++--------------------------------------------------------------------+ + + PURPOSE : handles a message indication + +*/ +GLOBAL BOOL cmhSMS_cpyMsgInd ( T_ACI_CMGL_SM * sm, + T_MNSMS_MESSAGE_IND * mnsms_message_ind) +{ + BOOL ret = FALSE; + TRACE_FUNCTION("cmhSMS_cpyMsgInd()"); + + /* + *----------------------------------------------------------------- + * decode SMS-DELIVER or SMS-SUBMIT + *----------------------------------------------------------------- + */ + + /* + * ACI-SPR-17004: set RFU bits of status to 0 if present since these + * should be ignored in a GSM session (GSM 11.11 section 9.3) + */ + cmhSMS_removeStatusRFUBits( &mnsms_message_ind->status ); + + switch (mnsms_message_ind->status) + { + case SMS_RECORD_REC_UNREAD: + case SMS_RECORD_REC_READ: + ret = cmhSMS_cpyDeliver ( sm, &mnsms_message_ind->sms_sdu ); + break; + case SMS_RECORD_STO_UNSENT: + case SMS_RECORD_STO_SENT: + /* ACI-SPR-17003: Handle unsupported statuses */ + case SMS_RECORD_STAT_UNRCVD: + case SMS_RECORD_STAT_UNSTRD: + case SMS_RECORD_STAT_STRD: + ret = cmhSMS_cpySubmit ( sm, &mnsms_message_ind->sms_sdu ); + break; + /* 21.Mar.2003 currently not used by SMS entity */ + /* + * case SMS_RECORD_INVALID: + * ret = FALSE; + * break; + */ + default: + TRACE_EVENT("incorrect status"); + } + + /* + *----------------------------------------------------------------- + * process status (convert from PSA type to CMH type) + *----------------------------------------------------------------- + */ + if (sm->stat NEQ SMS_STAT_Invalid) + { + cmhSMS_getStatCmh ( mnsms_message_ind->status, &sm -> stat ); + } + + /* + *----------------------------------------------------------------- + * process message reference + *----------------------------------------------------------------- + */ + sm -> msg_ref = mnsms_message_ind->rec_num; + + /* + *----------------------------------------------------------------- + * process tp_status + *----------------------------------------------------------------- + */ + sm ->tp_status = -1; + + return (ret); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_cpyReadCnf | ++--------------------------------------------------------------------+ + + PURPOSE : handles a read confirmation + +*/ +GLOBAL BOOL cmhSMS_cpyReadCnf ( T_ACI_CMGL_SM * sm, T_MNSMS_READ_CNF * mnsms_read_cnf ) +{ + BOOL ret = FALSE; + TRACE_FUNCTION("cmhSMS_cpyReadCnf()"); + + /* + * ACI-SPR-17004: set RFU bits of status to 0 if present since these + * should be ignored in a GSM session (GSM 11.11 section 9.3) + */ + cmhSMS_removeStatusRFUBits( &mnsms_read_cnf->status ); + + switch (mnsms_read_cnf->status) + { + case SMS_RECORD_REC_UNREAD: + case SMS_RECORD_REC_READ: + ret = cmhSMS_cpyDeliver ( sm, &mnsms_read_cnf->sms_sdu ); + break; + case SMS_RECORD_STO_UNSENT: + case SMS_RECORD_STO_SENT: + /* ACI-SPR-17003: Handle unsupported statuses */ + case SMS_RECORD_STAT_UNRCVD: + case SMS_RECORD_STAT_UNSTRD: + case SMS_RECORD_STAT_STRD: + ret = cmhSMS_cpySubmit ( sm, &mnsms_read_cnf->sms_sdu ); + break; + /* 21.Mar.2003 currently not used by SMS entity */ + /* + * case SMS_RECORD_INVALID: + * ret = FALSE; + * break; + */ + default: + TRACE_EVENT("incorrect status"); + } + + /* + *----------------------------------------------------------------- + * process status (PSA format -> CMH format) + *----------------------------------------------------------------- + */ + if (sm->stat NEQ SMS_STAT_Invalid) + { + cmhSMS_getStatCmh ( mnsms_read_cnf->status, &sm -> stat ); + } + + /* + *----------------------------------------------------------------- + * process message reference + *----------------------------------------------------------------- + */ + sm -> msg_ref = mnsms_read_cnf->rec_num; + + /* + *----------------------------------------------------------------- + * process tp_status + *----------------------------------------------------------------- + */ + sm ->tp_status = -1; + + return (ret); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_cpyStatInd | ++--------------------------------------------------------------------+ + + PURPOSE : handles a status indication + +*/ +GLOBAL BOOL cmhSMS_cpyStatInd ( T_ACI_CDS_SM * sm, + T_MNSMS_STATUS_IND *mnsms_status_ind ) +{ + T_rp_addr rp_addr; + UBYTE* message; + T_TP_STATUS *sms_status; + + TRACE_FUNCTION("cmhSMS_cpyStatInd()"); + + message = cmhSMS_decodeMsg(&mnsms_status_ind->sms_sdu, &rp_addr, SMS_VT_STATUS); + + if (message EQ NULL) + { + return (FALSE); + } + + if ( message[0] NEQ SMS_VT_STATUS) + { + TRACE_EVENT_P1("wrong VTI = %x", message[0]); + } + + sms_status = (T_TP_STATUS*)message; + + + /* + *----------------------------------------------------------------- + * process message type + *----------------------------------------------------------------- + */ + sm -> fo = mnsms_status_ind->sms_sdu.buf[mnsms_status_ind->sms_sdu.buf[0]+1]; + + /* + *----------------------------------------------------------------- + * process message reference + *----------------------------------------------------------------- + */ + sm -> msg_ref = sms_status->tp_mr; + + /* + *----------------------------------------------------------------- + * process recipient address + *----------------------------------------------------------------- + */ + cmhSMS_getAdrStr ( sm->addr, + MAX_SMS_ADDR_DIG - 1, + sms_status->tp_ra.num, + sms_status->tp_ra.digits); + + sm->toa.ton = cmhSMS_getTon ( sms_status->tp_ra.ton ); + sm->toa.npi = cmhSMS_getNpi ( sms_status->tp_ra.npi ); + + /* + *----------------------------------------------------------------- + * process service center time stamp + *----------------------------------------------------------------- + */ + cmhSMS_setVpabsCmh ( &sm->vpabs_scts, (T_tp_vp_abs*) &sms_status->tp_scts ); + + /* + *----------------------------------------------------------------- + * process discharge time + *----------------------------------------------------------------- + */ + cmhSMS_setVpabsCmh ( &sm->vpabs_dt, (T_tp_vp_abs*) &sms_status->tp_dt ); + + /* + *----------------------------------------------------------------- + * process status + *----------------------------------------------------------------- + */ + sm -> tp_status = sms_status->tp_st; + + return (TRUE); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_getPhbEntry | ++--------------------------------------------------------------------+ + + PURPOSE : gets phone book entry from coded SM + +*/ +GLOBAL void cmhSMS_getPhbEntry( UBYTE *buf, + T_ACI_PB_TEXT *alpha, + T_ACI_SMS_STAT status ) +{ + UBYTE *p_data; + UBYTE sca_len; + UBYTE nplan; + UBYTE no_bcd; + UBYTE bcd[MAX_SMS_ADDR_DIG]; + CHAR addr[MAX_SMS_ADDR_DIG+1]; /* for '\0' */ + USHORT octets; + + alpha->len = 0; + + p_data = &buf[0]; + sca_len = buf[0]; + + switch (status) + { + case SMS_STAT_RecUnread: + case SMS_STAT_RecRead: + if ((*(p_data+sca_len+1) & TP_MTI_MASK) EQ TP_MTI_SMS_STATUS_REP) + { + p_data++; + } + p_data += (sca_len+1) + 1; /* sms-deliver */ + break; + case SMS_STAT_StoUnsent: + case SMS_STAT_StoSent: + p_data += (sca_len+1) + 2; /* sms-submit */ + break; + default: + return; + } + + /* process originator/destination address */ + no_bcd = *p_data++; + no_bcd = MINIMUM(no_bcd, MAX_SMS_ADDR_DIG); + + nplan = *p_data++ & 0x0F; /* npi */ + + octets = (no_bcd+1)/2; + + no_bcd = (UBYTE)cmh_unpackBCD (bcd, p_data, octets); + + if (nplan EQ 0x05) /* VO patch - if (patch) else ... */ + { + UBYTE i,j = 0; + for (i = 0 ; i < no_bcd; i=i+2) + { + addr[j] = (UBYTE)(bcd[i+1] << 4) + (UBYTE)(bcd[i]); + j++; + } + addr[j] = '\0'; + } + else + { + cmhSMS_getAdrStr ( addr, + MAX_SMS_ADDR_DIG, + bcd, + no_bcd ); + } + + /* + *----------------------------------------------------------------- + * process alphanumerical phonebook entry + *----------------------------------------------------------------- + */ + psaCC_phbMfwSrchNumPlnTxt ( addr, alpha ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_codeDelRep | ++--------------------------------------------------------------------+ + + PURPOSE : codes RP-ACK for SMS-DELIVER-REPORT (without PID, DCS, UD) + +*/ +GLOBAL void cmhSMS_codeDelRep(T_sms_sdu *sms_sdu, T_rp_addr *sc_addr) +{ + UBYTE sca_len; /* SCA len incl. length byte and toa */ + UBYTE sca_buf[MAX_SMS_ADDR_DIG/2 + 2]; + + sca_len = CodeRPAddress( sca_buf, + sc_addr->c_num, + sc_addr->ton, + sc_addr->npi, + sc_addr->num ); + + sms_sdu->l_buf = (sca_len+2)<<3; + sms_sdu->o_buf = 0; + + memcpy ( sms_sdu->buf, sca_buf, sca_len); + memset ( sms_sdu->buf+sca_len, 0, 2); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : CodeRPAddress | ++--------------------------------------------------------------------+ + + PURPOSE : converts address (in BCD format) to semi-octet representation + (including address-length, ton and npi), + for RP addresses (e.g SCA) + + returns number of octets including address-length, + ton and npi + +*/ +GLOBAL UBYTE CodeRPAddress( UBYTE *buf, UBYTE numDigits, UBYTE ton, + UBYTE npi, UBYTE *bcd ) +{ + UBYTE length; + + if (numDigits EQ 0) + { + length = 1; + *buf = 0x00; + } + else + { + *buf++ = (numDigits+1)/2 + 1; + *buf++ = (ton << 4) + npi + 0x80; + + length = (UBYTE)cmh_packBCD ( buf, bcd, numDigits ); + + /* add length of length field, ton and npi */ + length += 2; + } + + return length; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : CodeTPAddress | ++--------------------------------------------------------------------+ + + PURPOSE : converts address (in BCD format) to semi-octet representation + (including address-length, ton and npi), + for TP addresses (e.g OA or DA) + + returns number of octets including including address-length, + ton and npi + +*/ +GLOBAL UBYTE CodeTPAddress( UBYTE *buf, UBYTE numDigits, UBYTE ton, + UBYTE npi, UBYTE *bcd ) +{ + UBYTE length; + + *buf++ = numDigits; + *buf++ = (ton << 4) + npi + 0x80; + + length = (UBYTE)cmh_packBCD ( buf, bcd, numDigits ); + + /* add length of length field, to and npi */ + length += 2; + + return length; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : DecodeRPAddress | ++--------------------------------------------------------------------+ + + PURPOSE : converts RP address (SC address) from semi-octet + representation to address in BCD format (including + address-length, ton and npi) + + returns number of processed octets in buf + +*/ +GLOBAL UBYTE DecodeRPAddress(UBYTE *c_num, UBYTE *ton, + UBYTE *npi, UBYTE *bcd, UBYTE *buf) +{ + UBYTE sca_length; /* sca length is lenth in bytes plus TOA-octet */ + UBYTE processed_octets; + + sca_length = *buf++; + *ton = (*buf & 0x70)>>4; + *npi = *buf++ & 0x0F; + + *c_num = (UBYTE)cmh_unpackBCD (bcd, buf, (USHORT)(sca_length-1)); + + processed_octets = (*c_num+1)/2 + 2; + + return processed_octets; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-F&D (8411) MODULE : CMH_SMSF | +| STATE : code ROUTINE : DecodeTPAddress | ++--------------------------------------------------------------------+ + + PURPOSE : converts TP address (DA, OA)from semi-octet + representation to address in BCD format (including + address-length, ton and npi) + + returns number of processed octets in buf + +*/ +GLOBAL UBYTE DecodeTPAddress(UBYTE *c_num, UBYTE *ton, + UBYTE *npi, UBYTE *bcd, UBYTE *buf) +{ + UBYTE digits; + UBYTE processed_octets; + + digits = *buf++; + *ton = (*buf & 0x70)>>4; + *npi = *buf++ & 0x0F; + + *c_num = (UBYTE)cmh_unpackBCD (bcd, buf, (USHORT)((digits+1)/2)); + + processed_octets = (*c_num+1)/2 + 2; + + return processed_octets; +} + + + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_fillTpSubmit | ++--------------------------------------------------------------------+ + + PURPOSE : fills a T_TP_SUBMIT + +*/ +GLOBAL void cmhSMS_fillTpSubmit (T_TP_SUBMIT* tp_submit, + T_ACI_CMD_SRC srcId, + UBYTE msgType, + UBYTE mr, + T_tp_da* da_addr, + T_ACI_SM_DATA* data, + UBYTE septets, + T_ACI_UDH_DATA* udh ) +{ + T_SMS_SET_PRM * pSMSSetPrm; /* points to SMS parameter set */ + UBYTE alphabet; + + TRACE_FUNCTION ("cmhSMS_fillTpSubmit()"); + + pSMSSetPrm = smsShrdPrm.pSetPrm[srcId]; + + memset(tp_submit, 0, sizeof(T_TP_SUBMIT)); + + tp_submit->tp_vt_mti = SMS_VT_SUBMIT; + tp_submit->tp_rp = (msgType & TP_RP_MASK) ? 1 : 0; + tp_submit->tp_mti = SMS_SUBMIT; + tp_submit->tp_mr = mr; + tp_submit->tp_srr = (msgType & TP_SRR_MASK) ? 1 : 0; + + if (da_addr->digits NEQ 0x00) + memcpy(&tp_submit->tp_da, da_addr, sizeof(T_tp_da)); + + tp_submit->tp_pid = pSMSSetPrm -> pid; + tp_submit->tp_dcs = pSMSSetPrm -> dcs; + + switch (msgType & VPF_MASK) + { + + case VPF_RELATIVE: /* validity period relative */ + tp_submit->v_tp_vp_rel = 1; + tp_submit->tp_vpf = SMS_VPF_RELATIVE; + tp_submit->tp_vp_rel = pSMSSetPrm -> vpRel; + break; + + case VPF_ABSOLUTE: /* validity period absolute */ + tp_submit->v_tp_vp_abs = 1; + tp_submit->tp_vpf = SMS_VPF_ABSOLUTE; + memcpy(&tp_submit->tp_vp_abs, &pSMSSetPrm -> vpAbs, sizeof(T_tp_vp_abs)); + break; + + case VPF_ENHANCED: /* validity period enhanced */ + tp_submit->v_tp_vp_enh = 1; + tp_submit->tp_vpf = SMS_VPF_ENHANCED; + memcpy(&tp_submit->tp_vp_enh, &pSMSSetPrm -> vpEnh, sizeof(T_tp_vp_enh)); + break; + + default: /* validity period not present */ + break; + } + + + alphabet = cmhSMS_getAlphabetPp ( pSMSSetPrm -> dcs ); + + if ((udh) AND (udh->len)) + { + tp_submit->tp_udhi = 1; + tp_submit->v_tp_udh_inc = 1; + tp_submit->tp_udh_inc.tp_udh.c_data = udh->len; + memcpy(tp_submit->tp_udh_inc.tp_udh.data, udh->data, udh->len); + + /* copy user data */ + if ((data) AND (data->len)) + { + tp_submit->tp_udh_inc.c_data = data->len; + memcpy(tp_submit->tp_udh_inc.data, data->data, data->len); + } + + /* 7-bit data */ + if (alphabet EQ 0x00) + { + tp_submit->tp_udh_inc.length = septets + (((udh->len+1)*8)/7); + + /* space for the fill bits */ + if (((udh->len+1)*8)%7 NEQ 0) + { + tp_submit->tp_udh_inc.length++; + if ((data EQ NULL) OR (data->len EQ 0)) + { + tp_submit->tp_udh_inc.c_data = 1; + tp_submit->tp_udh_inc.data[0] = 0; /* redundant */ + } + } + } + /* 8-bit data */ + else + { + tp_submit->tp_udh_inc.length = tp_submit->tp_udh_inc.c_data+udh->len+1; /* UDH length should be also added */ + } + } + else + { + /* validity flag set for both normal SMS and empty SMS */ + tp_submit->v_tp_ud = 1; + + if ((data) AND (data->len)) + { + tp_submit->tp_ud.length = septets; + tp_submit->tp_ud.c_data = data->len; + memcpy(tp_submit->tp_ud.data, data->data, data->len); + } + else + { + /* enters when zero character SMS to be sent */ + } + } +} + + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_fillTpDeliver | ++--------------------------------------------------------------------+ + + PURPOSE : fills a T_TP_DELIVER (only used by +CMGW) + +*/ +GLOBAL void cmhSMS_fillTpDeliver (T_TP_DELIVER* tp_deliver, + T_ACI_CMD_SRC srcId, + UBYTE msgType, + T_tp_oa* oa_addr, + T_ACI_SM_DATA* data, + UBYTE septets, + T_ACI_UDH_DATA* udh ) +{ + T_SMS_SET_PRM * pSMSSetPrm; /* points to SMS parameter set */ + UBYTE alphabet; + + TRACE_FUNCTION ("cmhSMS_fillTpDeliver()"); + + pSMSSetPrm = smsShrdPrm.pSetPrm[srcId]; + + memset(tp_deliver, 0, sizeof(T_TP_DELIVER)); + + tp_deliver->tp_vt_mti = SMS_VT_DELIVER; + tp_deliver->tp_rp = (msgType & TP_RP_MASK) ? 1 : 0; + tp_deliver->tp_mti = SMS_DELIVER; + + if (oa_addr->digits NEQ 0x00) + memcpy(&tp_deliver->tp_oa, oa_addr, sizeof(T_tp_oa)); + + tp_deliver->tp_pid = pSMSSetPrm -> pid; + tp_deliver->tp_dcs = pSMSSetPrm -> dcs; + + memcpy(&tp_deliver->tp_scts, &pSMSSetPrm -> vpAbs, sizeof(T_tp_scts)); + + if ((data) AND (data->len)) + { + alphabet = cmhSMS_getAlphabetPp ( pSMSSetPrm -> dcs ); + + if ((udh) AND (udh->len)) + { + tp_deliver->tp_udhi = 1; + tp_deliver->v_tp_udh_inc = 1; + tp_deliver->tp_udh_inc.tp_udh.c_data = udh->len; + memcpy(tp_deliver->tp_udh_inc.tp_udh.data, udh->data, udh->len); + + /* copy user data */ + tp_deliver->tp_udh_inc.c_data = data->len; + memcpy(tp_deliver->tp_udh_inc.data, data->data, data->len); + + /* 7-bit data */ + if (alphabet EQ 0x00) + { + tp_deliver->tp_udh_inc.length = septets + (((udh->len+1)*8)/7); + + /* space for the fill bits */ + if (((udh->len+1)*8)%7 NEQ 0) tp_deliver->tp_udh_inc.length++; + } + /* 8-bit data */ + else + { + tp_deliver->tp_udh_inc.length = tp_deliver->tp_udh_inc.c_data; + } + } + else + { + tp_deliver->v_tp_ud = 1; + tp_deliver->tp_ud.length = septets; + tp_deliver->tp_ud.c_data = data->len; + memcpy(tp_deliver->tp_ud.data, data->data, data->len); + } + } + else /* if ((data) AND (data->len)) */ + { + tp_deliver->v_tp_ud = 1; + tp_deliver->tp_ud.length = 0; + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_fillTpCommand | ++--------------------------------------------------------------------+ + + PURPOSE : fills a T_TP_COMMAND + +*/ +GLOBAL void cmhSMS_fillTpCommand ( T_TP_COMMAND* tp_command, + UBYTE fo, + UBYTE ct, + UBYTE mr, + UBYTE pid, + UBYTE mn, + T_tp_da* da_addr, + T_ACI_CMD_DATA* data, + T_ACI_UDH_DATA* udh) + +{ + TRACE_FUNCTION ("cmhSMS_fillTpCommand()"); + + memset(tp_command, 0, sizeof(T_TP_COMMAND)); + + tp_command->tp_vt_mti = SMS_VT_COMMAND; + tp_command->tp_srr = (fo & TP_SRR_MASK) ? 1 : 0; + tp_command->tp_mti = SMS_COMMAND; + tp_command->tp_mr = mr; + tp_command->tp_pid = pid; + tp_command->tp_ct = ct; + tp_command->tp_mn = mn; + + if (da_addr->digits NEQ 0x00) + memcpy(&tp_command->tp_da, da_addr, sizeof(T_tp_da)); + + if ((data) AND (data->len)) + { + if ((udh) AND (udh->len)) + { + tp_command->tp_udhi = 1; + tp_command->v_tp_cdh_inc = 1; + tp_command->tp_cdh_inc.tp_udh.c_data = udh->len; + memcpy(tp_command->tp_cdh_inc.tp_udh.data, udh->data, udh->len); + tp_command->tp_cdh_inc.c_data = data->len; + memcpy(tp_command->tp_cdh_inc.data, data->data, data->len); + } + else + { + tp_command->v_tp_cd = 1; + tp_command->tp_cd.c_data = data->len; + memcpy(tp_command->tp_cd.data, data->data, data->len); + } + } + else + { + /* command length field must be present */ + tp_command->v_tp_cd = 1; + tp_command->tp_cd.c_data = 0; + } + +} +#ifdef FF_CPHS + +/* ++----------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| ROUTINE : cmhSMS_check_voice_mail_ind| ++----------------------------------------------------------------------+ + + PURPOSE : +*/ + +LOCAL BOOL cmhSMS_check_voice_mail_ind( T_TP_DELIVER *sms_deliver ) +{ + TRACE_FUNCTION("cmhSMS_check_voice_mail_ind()"); + + if ( sms_deliver->tp_oa.digits NEQ 4 OR + sms_deliver->tp_oa.ton NEQ SMS_TON_ALPHANUMERIC ) + { + TRACE_EVENT_P2("no vmi -> oa... digits:%d ton:%d", + sms_deliver->tp_oa.digits, sms_deliver->tp_oa.ton); + return FALSE; + } + + switch (sms_deliver->tp_dcs & 0xF0) + { + case SMS_DCS_GRP_DEF: + case SMS_DCS_GRP_CLASS: + if ( (sms_deliver->tp_dcs & 0xF) EQ 0 OR + (sms_deliver->tp_dcs & 0xF) EQ 0xC ) + { + break; /* GSM Default Alphabet */ + } + /* no break, if FALSE */ + /*lint -fallthrough*/ + case SMS_DCS_GRP_COMPR: + case SMS_DCS_GRP_CLASS_COMPR: + case SMS_DCS_GRP_MW_STORE_UCS2: + TRACE_EVENT_P1("no vmi -> dcs: %d", sms_deliver->tp_dcs); + return FALSE; /* no GSM Default Alphabet */ + case SMS_DCS_DATA_CLASS: + if (sms_deliver->tp_dcs & 0x4) + { + TRACE_EVENT_P1("no vmi -> dcs: %d", sms_deliver->tp_dcs); + return FALSE; /* no GSM Default Alphabet */ + } + } + + if (!sms_deliver->v_tp_ud) + { + TRACE_EVENT("no vmi -> no ud"); + return FALSE; /* not only text present */ + } + if ( ( sms_deliver->tp_ud.length NEQ 1 ) OR + ( (sms_deliver->tp_ud.data[0] & 0x7F) NEQ ' ') ) + { + TRACE_EVENT_P2("no vmi -> ud... length:%d data[0]:%d", + sms_deliver->tp_ud.length, sms_deliver->tp_ud.data[0]); + return FALSE; /* no single space */ + } + + TRACE_FUNCTION ("CPHS VWI: send to cphs module"); + + return TRUE; +} + + +/* ++-------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| ROUTINE : cmhSMS_voice_mail_ind_get_line| ++-------------------------------------------------------------------------+ + + PURPOSE : +*/ +LOCAL void cmhSMS_voice_mail_ind_get_data( T_TP_DELIVER *sms_deliver, + UBYTE *flag_set, + T_CPHS_LINES *line ) +{ + TRACE_FUNCTION("cmhSMS_voice_mail_ind_get_line()"); + + /* get flag set, which is send in the first bit of the first + byte of the originating address number. Due to the decoding + each byte of the originating address number is now splitted + into 2 bytes, so that the first 4 bits of the former first + byte can be found in byte 1 */ + *flag_set = sms_deliver->tp_oa.num[0] & 0x1; + + /* line is coded in character 1 bit 1 of GSM originating address. + the originating address of T_TP_DELIVER is allready decoded + so that this information is to be found in byte 3 of the + originating address number */ + + if (sms_deliver->tp_oa.num[2] & 0x1) + { + *line = CPHS_LINE2; + } + else + { + *line = CPHS_LINE1; + } +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| ROUTINE : cmhSMS_voice_mail_ind | ++----------------------------------------------------------------------+ + + PURPOSE : +*/ + +GLOBAL BOOL cmhSMS_voice_mail_ind( T_sms_sdu *sms_sdu) +{ + T_TP_DELIVER *sms_deliver; + T_rp_addr rp_addr; + T_CPHS_LINES line; + UBYTE flag_set; + UBYTE *message; + + TRACE_FUNCTION("cmhSMS_voice_mail_ind()"); + + /* check if cphs is active */ + + + /* check if indication is voice mail indication */ + if ( sms_sdu ) + { + message = cmhSMS_decodeMsg(sms_sdu, &rp_addr, SMS_VT_DELIVER); + + if (message EQ NULL) + return FALSE; + + if ( message[0] NEQ SMS_VT_DELIVER) + { + TRACE_EVENT_P1("wrong VTI = %x", message[0]); + } + + sms_deliver = (T_TP_DELIVER*)message; + + if ( cphs_check_status() EQ CPHS_OK ) + { + if ( cmhSMS_check_voice_mail_ind(sms_deliver) ) + { + cmhSMS_voice_mail_ind_get_data(sms_deliver, &flag_set, &line); + + cphs_voice_mail_ind(flag_set, line); + + return TRUE; + } + } + } + return FALSE; +} + +#endif /* FF_CPHS*/ + + +/* ++----------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| ROUTINE : cmhSMS_resetMtDsCnmiParam | ++----------------------------------------------------------------------+ + PURPOSE : this function resets the <mt> and <ds> parameter for the + SMS acknowledge in Phase2+ mode (+CNMA). +*/ +GLOBAL void cmhSMS_resetMtDsCnmiParam(void) +{ + smsShrdPrm.mtHndl = 0; /* reset <mt> and <ds> param in error case */ + smsShrdPrm.srHndl = 0; + + smsShrdPrm.CNMImt = 0; + smsShrdPrm.CNMIds = 0; + { /* inform the SMS entity about the parameter changes */ + PALLOC (mnsms_configure_req, MNSMS_CONFIGURE_REQ); + + /* fill in primitive parameter: command request */ + mnsms_configure_req -> pref_mem_3 = smsShrdPrm.mem3; + mnsms_configure_req -> mt = smsShrdPrm.mtHndl; + mnsms_configure_req -> ds = smsShrdPrm.srHndl; + mnsms_configure_req -> mhc = (smsShrdPrm.CSMSservice NEQ CSMS_SERV_GsmPh2Plus) + ? SMS_MHC_PH2 : SMS_MHC_PH2PLUS; + mnsms_configure_req->v_cmms_mode = FALSE; + mnsms_configure_req->v_tmms_val = FALSE; + + PSENDX (SMS, mnsms_configure_req); + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSS | +| STATE : code ROUTINE : sAT_PlusCMGWPdu | ++-------------------------------------------------------------------+ + + PURPOSE : This is the internal function which is responsible for + storing messages into the mobile station or SIM card. + AT command which is responsible for writing a short + message to memory in PDU mode. +*/ +GLOBAL BOOL cmhSMS_storePduToSim( T_ACI_CMD_SRC srcId, + UBYTE stat, + T_ACI_SM_DATA *pdu ) +{ + T_ACI_RETURN ret; + + TRACE_FUNCTION ("cmhSMS_storePduToSim()"); + + /* check if command executable */ + if(!cmhSMS_checkAccess (srcId, &ret)) + { + return FALSE; + } + + { + PALLOC (mnsms_store_req, MNSMS_STORE_REQ); + + mnsms_store_req -> mem_type = smsShrdPrm.mem2; + mnsms_store_req -> rec_num = CMGW_IDX_FREE_ENTRY; + mnsms_store_req -> condx = SMS_CONDX_OVR_NON; + mnsms_store_req -> status = stat; + + if ( (pdu->len > 0) AND (pdu->len <= SIM_PDU_LEN) ) + { + mnsms_store_req->sms_sdu.l_buf = pdu->len * 8; + mnsms_store_req->sms_sdu.o_buf = 0; + memcpy (mnsms_store_req->sms_sdu.buf, pdu->data, pdu->len); + } + else + { + TRACE_FUNCTION ("cmhSMS_storePduToSim() : wrong PDU len"); + PFREE (mnsms_store_req); + return FALSE; + } + + PSENDX (SMS, mnsms_store_req); + } + + smsShrdPrm.smsEntStat.curCmd = AT_CMD_CMGW; + smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = srcId; + smsShrdPrm.uiInternalSmsStorage = srcId; + + return TRUE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_removeStatusRFUBits | ++--------------------------------------------------------------------+ + + PURPOSE : ACI-SPR-17004: Method for removing of SMS RFU status + bits as defined by GSM 11.11 section 9.3 + +*/ +GLOBAL void cmhSMS_removeStatusRFUBits ( UBYTE* status ) +{ + TRACE_FUNCTION("cmhSMS_removeStatusRFUBits()"); + + /* See GSM 11.11 section 10.5.3 for position of RFU bits in status */ + + /* test the pattern of the three lowest bits, match for "101" */ + if ((*status & 0x07) EQ 0x05) + { + /* set the highest three bits to 0 */ + *status &= 0x1F; + } + else + { + /* set the highest five bits to 0 */ + *status &= 0x07; + } + +} + +/* ++-------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_SMSF | +| STATE : code ROUTINE : cmhSMS_convertDeliverStatusToACI| ++-------------------------------------------------------------------------+ + + PURPOSE : converts the SMS delivery status to ACI CPRSM status. + +*/ +GLOBAL T_ACI_CPRSM_MOD cmhSMS_convertDeliverStatusToACI ( UBYTE status ) +{ + T_ACI_CPRSM_MOD mode; + + TRACE_FUNCTION("cmhSMS_convertDeliverStatusToACI()"); + + switch (status) + { + case SMS_DELIVER_STATUS_PAUSE: + mode = CPRSM_MOD_Pause; + break; + case SMS_DELIVER_STATUS_RESUME: + mode = CPRSM_MOD_Resume; + break; + default: + mode = CPRSM_MOD_NotPresent; + } + return mode; +} + +/*==== EOF ========================================================*/