FreeCalypso > hg > freecalypso-sw
view gsm-fw/ccd/asn1_choice_ext.c @ 982:461f7ee5f254
fc-olddump: brown paper bag
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Thu, 10 Dec 2015 05:35:42 +0000 |
parents | 970d6199f2c5 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | Modul : asn1_choice_ext.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 : Encoding and decoding functions for ASN1_CHOICE_EXTENSIBLE type +----------------------------------------------------------------------------- */ /* * Standard definitions like 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 and constants in the common part of ccd */ #include "ccd.h" /* * Declaration of coder/decoder tables */ #include "ccdtable.h" #include "ccddata.h" #ifndef RUN_INT_RAM /* +------------------------------------------------------------------------+ | PROJECT : CCD (6144) MODULE : asn1_choice_ext | | STATE : code ROUTINE : cdc_asn1_choice_ext_decode | +------------------------------------------------------------------------+ PURPOSE : Decode PER extensible CHOICE type The value of the union tag must be calculated from the encoded CHOICE index in the air message. For CHOICE alternatives within the extension root: the index bit-size relates to max index value in the extension root. For CHOICE alternatives within the extension part: the index is encoded as a normally small non-negative whole number. For decoding the CHOICE alternative itself, call the same function as for non-extensible CHOICE types. */ SHORT cdc_asn1_choice_ext_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) { U32 extensionBegin; T_ENUM UnionTag; /* default: only one alternative */ ULONG calc_ref = calcidx[melem[e_ref].calcIdxRef].condCalcRef; #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "cdc_asn1_choice_ext_decode()"); #else TRACE_CCD (globs, "cdc_asn1_choice_ext_decode() %s", mcomp[melem[e_ref].elemRef].name); #endif #endif /* Don't do anything for empty choices */ if (mcomp[melem[e_ref].elemRef].numOfComponents == 0) { return 1; } globs->pstructOffs = melem[e_ref].structOffs; /* For optional elements we have already set the valid flag in the * C-structure. We have done it while processing ASN1_SEQ. */ if ( ! cdc_isPresent(e_ref, globs) ) { return 1; } /* * Get max value of CHOICE index within the extension root. */ if (calc_ref EQ NO_REF OR calc[calc_ref].operation NEQ 'P') { ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, globs->pstruct+globs->pstructOffs); return 1; } else { extensionBegin = calc[calc_ref].operand; } /* * Read the extensinon bit. * If set to 1, read the CHOICE index as a normally samll * non-negative whole number. Otherwise read it according * to the bitSize of index in the extension root. */ if (bf_readBit (globs) EQ 0) { /* CHOICE index is encoded only if there are more than one alternatives. */ if (mcomp[melem[e_ref].elemRef].numOfComponents > 1) { UnionTag = (T_ENUM)bf_getBits (bitSize[extensionBegin], globs); } else UnionTag = 0; if (UnionTag >= (T_ENUM)extensionBegin) { ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref, globs->pstruct+globs->pstructOffs); } PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); } else { U32 finalBP=0; UnionTag = (T_ENUM)Read_NormallySmallNonNegativeWholeNr (globs); UnionTag += extensionBegin; finalBP = Read_OpenTpye_Length (globs)*8; finalBP += globs->bitpos; /* * For unknown extension skip over the octets. */ if (UnionTag <= (T_ENUM)mcomp[melem[e_ref].elemRef].numOfComponents) { PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); } else { #ifdef DEBUG_CCD TRACE_CCD (globs, "Unknown extension with CHOICE index = %ld...skipped to the bit %ld", UnionTag, finalBP); #endif } bf_setBitpos (finalBP, globs); } return 1; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* +------------------------------------------------------------------------+ | PROJECT : CCD (6144) MODULE : asn1_choice_ext | | STATE : code ROUTINE : cdc_asn1_choice_ext_encode | +------------------------------------------------------------------------+ PURPOSE : Encode PER extensible CHOICE type Evaluate the union controller. 1) It refers to a CHOICE alternative within the extension root: Set the extension bit to 0. Write the CHOICE index. Then encode the chosen alternative. ------------------------------------ | extension | CHOICE | encoded | | bit | index | alternative | ------------------------------------ 2) It refers to a CHOICE alternative within the extension list: Set the extension bit to 1. Encode the CHOICE index as a normally small non-negative whole nr. Skip over 6 bits dedicated to length determinant. Encode the chosen alternative. Calculate the bit size of the encoded alternative. Encode the calculated bit size into the field of length determinant. Right shift the encoded alternative, if 6 bits are not enough for the length determinant. ------------------------------------------------ | extension | CHOICE | length | encoded | | bit | index | determinant | alternative | ------------------------------------------------ For encoding the CHOICE alternative itself, call the same function as for non-extensible CHOICE types. */ SHORT cdc_asn1_choice_ext_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) { U16 startBitpos, Len, EndBitPos; T_ENUM UnionTag; /* default: only one alternative */ U32 extensionBegin; ULONG calc_ref= calcidx[melem[e_ref].calcIdxRef].condCalcRef; #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "cdc_asn1_choice_ext_encode()"); #else TRACE_CCD (globs, "cdc_asn1_choice_ext_encode() %s", mcomp[melem[e_ref].elemRef].name); #endif #endif /* Don't do anything for empty choices */ if (mcomp[melem[e_ref].elemRef].numOfComponents == 0) { return 1; } globs->pstructOffs = melem[e_ref].structOffs; /* For optional elements we have already set the valid flag in the * C-structure. We have done it while processing ASN1_SEQ. */ if ( ! cdc_isPresent(e_ref, globs) ) return 1; /* * Get max value of CHOICE index within the extension root. */ if (calc_ref EQ NO_REF OR calc[calc_ref].operation NEQ 'P') { ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK,(USHORT) e_ref, globs->pstruct+globs->pstructOffs); return 1; } else { extensionBegin = calc[calc_ref].operand; } /* * Get the value of chosen index (= union controller). */ UnionTag = *(T_ENUM *) (globs->pstruct+globs->pstructOffs); /* * The chosen alternative belongs to the extension list. */ if ((U32)UnionTag >= extensionBegin) { /* Encode the extension bit first */ bf_writeBit (1, globs); /* Encode the CHOICE index. */ Write_NormallySmallNonNegativeWholeNr (((U32)UnionTag - extensionBegin), globs); /* Skip over the bits estimated for the length determinant. */ bf_incBitpos (8, globs); startBitpos = globs->bitpos; PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); /* * Check if zero padding bits are necessary. If encoding * consumed no bits, insert a zero-octet in the bit string. * Then calculate length of the encoded open type in octets. */ if ((Len = globs->bitpos - startBitpos) EQ 0) { bf_writeVal (0, 8, globs); Len = 1; } else { if ((Len&7) NEQ 0) bf_incBitpos (8 - (Len&7), globs); Len = (U16)(globs->bitpos - startBitpos) >> 3; } EndBitPos = globs->bitpos; /* * Encode the length determinant. */ if (Len < 128) { bf_setBitpos (startBitpos-8, globs); Write_OpenTpye_Length ((U32)Len, globs); } /* * This case does not seem to happen very often. */ else { ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK,(USHORT) e_ref, globs->pstruct+globs->pstructOffs); } /* * Encoding for the extensible choice is finished. * Set the bit position pointer to the end of encoded open type. */ bf_setBitpos (EndBitPos, globs); } /* * The chosen alternative belongs to the extension root. */ else { bf_writeBit (0, globs); /* CHOICE index is encoded only if there are more than one alternatives. */ if (mcomp[melem[e_ref].elemRef].numOfComponents > 1) { bf_writeVal ((ULONG) UnionTag, (ULONG) bitSize[extensionBegin], globs); } PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); } return 1; } #endif /* !RUN_INT_RAM */