FreeCalypso > hg > freecalypso-sw
diff gsm-fw/ccd/csn1_concat.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/csn1_concat.c Thu Sep 04 05:48:57 2014 +0000 @@ -0,0 +1,415 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : csn1_concat.c ++----------------------------------------------------------------------------- +| Copyright 2004 Texas Instruments Deutschland GmbH +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Deutschland GmbH +| 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 Deutschland GmbH. ++----------------------------------------------------------------------------- +| Purpose : Condat Conder Decoder - +| Definition of encoding and decoding functions of +| CSN1 truncated concatenation 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" +#include "ccd_codingtypes.h" + +/* + * Declaration of coder/decoder tables + */ +#include "ccdtable.h" +#include "ccddata.h" + +EXTERN T_FUNC_POINTER codec[MAX_CODEC_ID+1][2]; + +#ifndef RUN_FLASH +/* ++---------------------------------------------------------------------+ +| PROJECT : CCD (6144) MODULE : CCD | +| STATE : code ROUTINE : cdc_csn1_concat_decode | ++---------------------------------------------------------------------+ + + PURPOSE : decodes the bitstream to a C-Structure.The decoding + rules contains the element definitions for the + elements of this message. + This function may called recursivly because of a + substructured element definition. +*/ + +SHORT cdc_csn1_concat_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) +{ + /* + * index in table melem + */ + ULONG elem_ref, last_elem, start_elem; + SHORT codecRet; + U8 *actStructpos; + U8 actErrLabel; + U16 actMaxBitpos, finalBitPos; + U8 *pnumConcatElem = NULL; + ULONG i, num_concat_elem; + BOOL SetPosExpected = FALSE; + ULONG cix_ref, num_prolog_steps, prolog_step_ref; + +#ifdef DEBUG_CCD + #ifndef CCD_SYMBOLS + TRACE_CCD (globs, "cdc_csn1_concat_decode()"); + #else + TRACE_CCD (globs, "cdc_csn1_concat_decode() %s", ccddata_get_alias((USHORT) e_ref, 1)); + #endif +#endif + + actErrLabel = globs->errLabel; + + /* Set ref number for calcidx table. */ + 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); + } + + globs->ccd_recurs_level++; + + if (globs->bitpos < globs->maxBitpos) + { + if (melem[e_ref].repType == 's') + { + BOOL is_variable; + ULONG max_rep, repeat; + + is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs); + if (repeat > (ULONG) (globs->maxBitpos-globs->bitpos)) + { + ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, + (USHORT) e_ref, globs->pstruct + globs->pstructOffs); + repeat = MINIMUM (repeat, (ULONG) (globs->maxBitpos-globs->bitpos)); + } + + finalBitPos = (USHORT) (globs->bitpos + repeat); + + #ifdef DEBUG_CCD + #ifdef CCD_SYMBOLS + TRACE_CCD (globs, "decoding of concatenation %s as a bit array", + mcomp[melem[e_ref].elemRef].name); + #else + TRACE_CCD (globs, "decoding of concatenation %d as a bit array", melem[e_ref].elemRef); + #endif + #endif + /* Store the limit. The truncated concatenation may contain + other compositions as bitstring. */ + actMaxBitpos = globs->maxBitpos; + globs->maxBitpos = finalBitPos; + } + else + { + #ifdef DEBUG_CCD + #ifdef CCD_SYMBOLS + TRACE_CCD (globs, "decoding concatenation %s", + mcomp[melem[e_ref].elemRef].name); + #else + TRACE_CCD (globs, "decoding concatenation %d", melem[e_ref].elemRef); + #endif + #endif + } + + /* + * Store the actual structure position. + */ + actStructpos = globs->pstruct; + globs->pstructOffs = melem[e_ref].structOffs; + globs->pstruct += globs->pstructOffs; + /* + * setup the index in the melem table for this composition. + */ + elem_ref = (ULONG) mcomp[melem[e_ref].elemRef].componentRef; + last_elem = elem_ref + mcomp[melem[e_ref].elemRef].numOfComponents; + /* + * It is recommended to use a leading element of coding type NO_CODE + * in the message description which is used to count the existing + * elements of the truncated concatenation. If this element is missing + * the decoding process will proceed but the CCD user is forced to + * evaluate all of the valid flags. + */ + + if (melem[elem_ref].codingType == CCDTYPE_NO_CODE) + { + pnumConcatElem = globs->pstruct; + elem_ref++; + + num_concat_elem = (ULONG) (mcomp[melem[e_ref].elemRef].numOfComponents - 1); + } + + start_elem = elem_ref; + /* + * decode all elements + */ + while (elem_ref < last_elem) + + { + #ifdef ERR_TRC_STK_CCD + /* save the value for tracing in error case */ + globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem_ref; + #endif /* ERR_TRC_STK_CCD */ + + /* + * check if the bitstream has ended + */ + if (bf_endOfBitstream(globs) AND !globs->TagPending) + { + /* End of the bit stream is not reached if a call to bf_setBitpos() + * is expected for the next element of the current substructure. + * An instructive example is an empty "mob_id" + */ + cix_ref = melem[elem_ref].calcIdxRef; + num_prolog_steps = calcidx[cix_ref].numPrologSteps; + prolog_step_ref = calcidx[cix_ref].prologStepRef; + + if (num_prolog_steps) + { + i = prolog_step_ref + num_prolog_steps; + + while (i >= prolog_step_ref) + { + if (calc[i].operation == 'S') + { + SetPosExpected = TRUE; + break; + } + i--; + } + } + + if (SetPosExpected EQ FALSE) + { + num_concat_elem = elem_ref - start_elem; + /* after the while loop the recursion level will be decremented. */ + break; + } + + }//if end of bit string + + /* + * use the jump-table for selecting the decode function + */ + codecRet = + codec[melem[elem_ref].codingType][DECODE_FUN](melem[e_ref].elemRef, + elem_ref, globs); + if (codecRet NEQ 0x7f) + { + /* + * set the elem_ref to the next or the same element + */ + elem_ref += codecRet; + } + } + + if (pnumConcatElem != NULL) + { + *pnumConcatElem = (UBYTE) num_concat_elem; + } + + + if (melem[e_ref].repType == 's') + { + if (globs->bitpos > finalBitPos) + { + ccd_recordFault (globs, ERR_CONCAT_LEN, CONTINUE, (USHORT) elem_ref, + globs->pstruct + globs->pstructOffs); + } + bf_setBitpos (finalBitPos, globs); + /* Update maxBitpos to avoid an early end of decoding. */ + globs->maxBitpos = actMaxBitpos; + } + + /* + * restore the write pointer + */ + globs->pstruct = actStructpos; + } + + globs->errLabel = actErrLabel; + /* Reset indicator of exhaustion in the IEI table*/ + for (i = 0; globs->iei_ctx[globs->ccd_recurs_level].iei_table[i].valid == TRUE; i++) + { + globs->iei_ctx[globs->ccd_recurs_level].iei_table[i].exhausted = FALSE; + } + globs->ccd_recurs_level--; + + return 1; +} +#endif /* !RUN_FLASH */ + +#ifndef RUN_FLASH +/* ++---------------------------------------------------------------------+ +| PROJECT : CCD (6144) MODULE : CCD | +| STATE : code ROUTINE : cdc_csn1_concat_encode | ++---------------------------------------------------------------------+ + + PURPOSE : codes the content of a C-Structure into a bitstream. + This function may be called recursivly if an IE in the + structure is itself a structured IE. +*/ + +SHORT cdc_csn1_concat_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) + +{ + ULONG cix_ref, elem_ref, last_elem; + U8 codecRet; + U16 actBitpos; + U8 actByteOffs; + U8 *actStructpos; + +#ifdef DEBUG_CCD + #ifndef CCD_SYMBOLS + TRACE_CCD (globs, "cdc_csn1_concat_encode()"); + #else + TRACE_CCD (globs, "cdc_csn1_concat_encode() %s", ccddata_get_alias((USHORT) e_ref, 1)); + #endif +#endif + + cix_ref = melem[e_ref].calcIdxRef; + + /* + * If this element is conditional, check the condition. + */ + if (calcidx[cix_ref].numCondCalcs NEQ 0 + AND ! ccd_conditionOK (e_ref, globs)) + return 1; + + globs->ccd_recurs_level++; + + actStructpos = globs->pstruct; + globs->pstructOffs = melem[e_ref].structOffs; + globs->pstruct += globs->pstructOffs; + + elem_ref = (ULONG) mcomp[melem[e_ref].elemRef].componentRef; + last_elem = elem_ref + mcomp[melem[e_ref].elemRef].numOfComponents; + + /* + * It is recommended to use a leading element of coding type NO_CODE + * in the message description which is used to count the existing + * elements of the truncated concatenation in case of decoding. + * In case of encoding this element must be skipped. + */ + + if (melem[elem_ref].codingType == CCDTYPE_NO_CODE) + { + elem_ref++; + /* last_elem = elem_ref + *globs->pstruct; + + * Encoding act on the assumption that all elements of the truncated + * concatenation should be encoded. CCD will skip tagged elements + * but in case of CSN1 coding CCD will write the flag indicating absent + * elements. Values of mandatory elements without valid flags are coded + * according to their assignments in the C-structure. + * If more bits are written than the component l_buf of the message buffer + * suggested CCD generates a warning (error code ERR_BUFFER_OF). It is up + * to the user to analyse the consequences of this warning and to choose + * adequate procedures. + */ + } + + /* + * code all elements + */ + while ((elem_ref < last_elem) && (globs->bitpos < globs->msgLen)) + { +#ifdef ERR_TRC_STK_CCD + /* + * Save the value for tracing in error case. + */ + globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem_ref; +#endif /* ERR_TRC_STK_CCD */ + +#if defined _TOOLS_ + if (ccd_patch (globs, 0)) + codecRet = 1; + else +#endif /* _TOOLS_ */ + + actBitpos = globs->bitpos; + actByteOffs = globs->byteoffs; + + /* Use the jump-table for selecting encode function. */ + codecRet = (UBYTE) + codec[melem[elem_ref].codingType][ENCODE_FUN](melem[e_ref].elemRef, + elem_ref, globs); + + if (globs->bitpos < globs->msgLen) + { + if (codecRet NEQ 0x7f) + { + /* Set the elem_ref to the next or the same element. */ + elem_ref += codecRet; + } + } + else + { + if (globs->bitpos > globs->msgLen) + { + globs->bitpos = actBitpos; + globs->byteoffs = actByteOffs; + ccd_recordFault (globs, ERR_CONCAT_LEN, CONTINUE, (USHORT) elem_ref, + globs->pstruct + globs->pstructOffs); + } + break; + } + } + + globs->pstruct += mcomp[melem[e_ref].elemRef].cSize; + /* + * restore the read pointer + */ + globs->pstruct = actStructpos; + globs->ccd_recurs_level--; + return 1; +} +#endif /* !RUN_FLASH */