FreeCalypso > hg > freecalypso-sw
diff gsm-fw/ccd/bcd_mnc.c @ 648:970d6199f2c5
gsm-fw/ccd/*.[ch]: initial import from the LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 04 Sep 2014 05:48:57 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/ccd/bcd_mnc.c Thu Sep 04 05:48:57 2014 +0000 @@ -0,0 +1,361 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : bcd_mnc.c ++----------------------------------------------------------------------------- +| 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 : Definition of encoding and decoding functions for BCD_MNC elements ++----------------------------------------------------------------------------- +*/ + + +/* + * standard definitions like GLOBAL, UCHAR, ERROR etc. + */ +#include "typedefs.h" +#include "header.h" + +/* + * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only + * look at ccdapi.h + */ +#undef USE_DRIVER +#include "ccdapi.h" + +/* + * Types and functions for bit access and manipulation + */ +#include "ccd_globs.h" +#include "bitfun.h" + +/* + * Prototypes of ccd internal functions + */ +#include "ccd.h" + +/* + * Declaration of coder/decoder tables + */ +#include "ccdtable.h" +#include "ccddata.h" + +#ifndef RUN_INT_RAM +/* ++--------------------------------------------------------------------+ +| PROJECT : CCD (6144) MODULE : CCD | +| STATE : code ROUTINE : cdc_bcd_mnc_decode | ++--------------------------------------------------------------------+ + + PURPOSE : decoding a byte array, that contains a Mobile Network Code, + from the bitstream: + + MSBit LSBit + 7 8 6 5 4 3 2 1 + DIGIT_3 XXXXXXX Octett n-1 + DIGIT_2 DIGIT_1 Octett n + + The current decoding position is expected after Octett n-1 + The byte array should be of dimension [2..3] (preferred) + or [3] or [2] (also supported) + +*/ + + +SHORT cdc_bcd_mnc_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) +{ + ULONG repeat, max_rep; + BOOL is_variable; + UBYTE digBuffer[3]; + UBYTE *addr_c_xxx; + ULONG i; + ULONG cix_ref, num_prolog_steps, prolog_step_ref; + register UBYTE *digits; + +#ifdef DEBUG_CCD + #ifndef CCD_SYMBOLS + TRACE_CCD (globs, "cdc_bcd_mnc_decode()"); + #else + TRACE_CCD (globs, "cdc_bcd_mnc_decode() %s", ccddata_get_alias((USHORT) e_ref, 1)); + #endif +#endif + + cix_ref = melem[e_ref].calcIdxRef; + num_prolog_steps = calcidx[cix_ref].numPrologSteps; + prolog_step_ref = calcidx[cix_ref].prologStepRef; + + /* + * if this element is conditional, check the condition + */ + if (calcidx[cix_ref].numCondCalcs NEQ 0 + AND ! ccd_conditionOK (e_ref, globs)) + return 1; + + /* + * if this element have a defined Prolog + * we have to process it before decoding the bitstream + */ + if (num_prolog_steps) + { + ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); + } + + /* + * if this element is repeatable, and the number of + * repeats depends on another element, calculate the repeater + */ + if (melem[e_ref].repType NEQ ' ') + { + is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs); + } + else + { + repeat = 1; + is_variable = FALSE; + } + + /* + * setup the offset into the C-structure for this element + */ + globs->pstructOffs = melem[e_ref].structOffs; + + if (melem[e_ref].optional) + { + /* + * for optional elements set the valid-flag + */ + globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE; + } + + if (is_variable) + { + if (max_rep < 2 OR max_rep > 3) + { + ccd_setError (globs, ERR_INVALID_TYPE, BREAK, (USHORT) (globs->bitpos), + (USHORT) -1); + } + /* + * for variable sized elements store the min-value + * as counter into the C-Structure (c_xxx). + */ + addr_c_xxx = (UBYTE *) (globs->pstruct + globs->pstructOffs++); + if (max_rep > 255) + globs->pstructOffs++; + } + else + addr_c_xxx = NULL; + + digits = (UBYTE *) (globs->pstruct + globs->pstructOffs); + + bf_setBitpos ((globs->bitpos - 8), globs); + + /* + * read the BCD digits out of the bitstream. + * The read order is 3,X,2,1 + */ + digBuffer[2] = bf_decodeByteNumber (4, globs); + bf_incBitpos (4, globs); + + digBuffer[1] = bf_decodeByteNumber (4, globs); + digBuffer[0] = bf_decodeByteNumber (4, globs); + + if (addr_c_xxx NEQ NULL) + { + /* + * store the number of digits into the + * c_xxx variable if there is one. + */ + repeat = (ULONG) ((digBuffer[2] EQ 0x0f) ? 2 : 3); + if (max_rep > 65535) + { + ULONG *addr_c_xxx_u32; + addr_c_xxx_u32 = (ULONG *)addr_c_xxx; + *addr_c_xxx_u32 = repeat; + } + else if (max_rep > 255) + { + USHORT *addr_c_xxx_u16; + addr_c_xxx_u16 = (USHORT *)addr_c_xxx; + *addr_c_xxx_u16 = (USHORT) repeat; + } + else + *addr_c_xxx = (UBYTE) repeat; + } + else + { + if (max_rep EQ 2 AND digBuffer[2] NEQ 0xf) + ccd_setError (globs, ERR_PATTERN_MISMATCH, + CONTINUE, + (USHORT) (globs->bitpos-16), + (USHORT) -1); + + repeat = max_rep; + } + /* + * store the digits into the C-Structure variable + */ + for (i=0; i<repeat; i++) + digits[i] = digBuffer[i]; + + return 1; +} +#endif /* !RUN_INT_RAM */ + +#ifndef RUN_INT_RAM +/* ++--------------------------------------------------------------------+ +| PROJECT : CCD (6144) MODULE : CCD | +| STATE : code ROUTINE : cdc_bcd_mnc_encode | ++--------------------------------------------------------------------+ + + PURPOSE : encoding a byte array, that contains a Mobile Network Code, + into the bitstream: + + MSBit LSBit + 7 8 6 5 4 3 2 1 + DIGIT_3 XXXXXXX Octett n-1 + DIGIT_2 DIGIT_1 Octett n + + The current coding position is expected after Octett n-1 +*/ + + +SHORT cdc_bcd_mnc_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) +{ + ULONG repeat; + UBYTE dig3; + ULONG cix_ref, num_prolog_steps, prolog_step_ref; + register UBYTE *digits; + +#ifdef DEBUG_CCD + #ifndef CCD_SYMBOLS + TRACE_CCD (globs, "cdc_bcd_mnc_encode()"); + #else + TRACE_CCD (globs, "cdc_bcd_mnc_encode() %s", ccddata_get_alias((USHORT) e_ref, 1)); + #endif +#endif + + cix_ref = melem[e_ref].calcIdxRef; + num_prolog_steps = calcidx[cix_ref].numPrologSteps; + prolog_step_ref = calcidx[cix_ref].prologStepRef; + + /* + * if this element is conditional, check the condition + */ + if (calcidx[cix_ref].numCondCalcs NEQ 0 + AND ! ccd_conditionOK (e_ref, globs)) + return 1; + + /* + * if this element have a defined Prolog + * we have to process it before decoding the bitstream + */ + if (num_prolog_steps) + { + ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); + } + + /* + * setup the offset into the C-structure for this element + */ + globs->pstructOffs = melem[e_ref].structOffs; + + if (melem[e_ref].optional) + { + /* + * for optional elements check the valid-flag + */ + if (globs->pstruct[globs->pstructOffs++] == FALSE) + { + return 1; + } +#ifdef DEBUG_CCD + else if (globs->pstruct [melem[e_ref].structOffs] != TRUE) + { + TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d", + e_ref); + } +#endif + } + + /* + * if this element is repeatable, and the number of + * repeats depends on another element, calculate the repeater + */ + if (melem[e_ref].repType EQ 'v' OR melem[e_ref].repType EQ 'i') + { + /* + * for variable sized elements read the amount + * of repeats out of the C-Structure (c_xxx). + * If the number of repeats given by the C-Structure + * exceeds the allowed value (max_repeat) CCD gives a warning! + */ + if (melem[e_ref].maxRepeat > 255) + { + ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++)); + repeat = MINIMUM (count, (ULONG)melem[e_ref].maxRepeat); + if (repeat < count) + ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, + (USHORT) e_ref, globs->pstruct + globs->pstructOffs); + } + else + { + repeat = (ULONG) MINIMUM (globs->pstruct[globs->pstructOffs], + melem[e_ref].maxRepeat); + if ( repeat < (ULONG) (globs->pstruct[globs->pstructOffs]) ) + ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, + (USHORT) e_ref, globs->pstruct + globs->pstructOffs); + } + + globs->pstructOffs++; + } + else + if (melem[e_ref].repType EQ 'c') + repeat = (ULONG) melem[e_ref].maxRepeat; + else + repeat = 1; + + /* + * setup the read pointer to the byte array that contain + * the BCD number. + */ + digits = (UBYTE *) (globs->pstruct + globs->pstructOffs); + + if (repeat EQ 2) + dig3 = 0x0f; + else if (repeat EQ 3) + dig3 = digits[2]; + else + { + ccd_setError (globs, ERR_INVALID_TYPE, + BREAK, + (USHORT) (globs->bitpos), + (USHORT) -1); + return 1; + } + + bf_setBitpos ((globs->bitpos-8), globs); + bf_codeByteNumber (4, dig3, globs); + bf_incBitpos (4, globs); + bf_codeByteNumber (4, digits[1], globs); + bf_codeByteNumber (4, digits[0], globs); +#ifdef DEBUG_CCD + TRACE_CCD (globs, "skipping back 8 bits"); + TRACE_CCD (globs, "BCD digit (%X) written", (USHORT) dig3); + TRACE_CCD (globs, "skipping 4 bits"); + TRACE_CCD (globs, "BCD digit (%X) written", (USHORT) digits[1]); + TRACE_CCD (globs, "BCD digit (%X) written", (USHORT) digits[0]); +#endif + + return 1; +} +#endif /* !RUN_INT_RAM */