FreeCalypso > hg > freecalypso-sw
diff gsm-fw/ccd/freq_list.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/freq_list.c Thu Sep 04 05:48:57 2014 +0000 @@ -0,0 +1,500 @@ +/* ++----------------------------------------------------------------------------- +| Project : CCD +| Modul : freq_list.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 : Definition of decoding function for FREQ_LIST type ++----------------------------------------------------------------------------- +*/ + +#define FREQ_LIST_C + +/* + * standard definitions like GLOBAL, UCHAR, ERROR etc. + */ +#include "typedefs.h" +#include "header.h" + +#include "string.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" +/* + * Function prototypes of CCD-CCDDATA interface + */ +#include "ccddata.h" + + +#if !(defined (CCD_TEST)) +#include "vsi.h" +#endif + +#ifndef RUN_INT_RAM +/* + * Attention: in this file all static and global functions as well as + * the static data are controlled by one RUN_.. clause. + * The static data and functions are currently only used in the decode + * function, whereas encoding is not yet available. + */ +static U16 first; +static U16 last; +static U16 num; + + +/* + * The W-parameter in the 256 range start from bit 7 of the + * information element. The following table indicate the number + * of W-parameters and their length in bits. A length of zero + * indicated the end of the table. + */ +static const T_W_PARAM param_256[10] = +{ + /* + * length count + */ + 10, 1, + 8, 1, + 7, 2, + 6, 4, + 5, 8, + 4, 16, + 3, 32, + 2, 64, + 1, 128, + 0, 0 +}; + +/* + * The W-parameter in the 128 range start from bit 7 of the + * information element. The following table indicate the number + * of W-parameters and their length in bits. A length of zero + * indicated the end of the table. +*/ + +static const T_W_PARAM param_128[9] = +{ + /* + * length count + */ + 10, 1, + 7, 1, + 6, 2, + 5, 4, + 4, 8, + 3, 16, + 2, 32, + 1, 64, + 0, 0 +}; + +/* + * Compare results of the first channel with those of the others + * to find the dimensions. + */ +static void completeAddInfo (U8 *BitmapInStruct) +{ + *(U16*) (BitmapInStruct - 2) += num; + if (*(U16*) (BitmapInStruct - 6) > first) + *(U16*) (BitmapInStruct - 6) = first; + if (*(U16*) (BitmapInStruct - 4) < last) + *(U16*) (BitmapInStruct - 6) = last; +} + +static void setFirstChanNr (U8 *BitmapInStruct, short w0) +{ + U16 bitposition; + bitposition = (w0 == 0) ? 0 : (U16)(BITOFFSET_LIST - w0); + BitmapInStruct[bitposition >> 3] |= ByteBitMask[bitposition & 7]; + first = bitposition; + last = bitposition; + num = 1; +} +/* ++--------------------------------------------------------------------+ +| PROJECT : CCD MODULE : cdc_freq_list_decode | ++--------------------------------------------------------------------+ + PURPOSE : The function creates a frequency hopping list from one of + the following information elements according GSM 4.08: + + cell channel description + frequency list + frequency short list + neighbour cell description + + The format identifier of the information element is defined as: + + FORMAT-ID, Format Identifier + + Bit Bit Bit Bit Bit format notation + 8 7 4 3 2 + + 0 0 X X X bit map 0 + 1 0 0 X X 1024 range + 1 0 1 0 0 512 range + 1 0 1 0 1 256 range + 1 0 1 1 0 128 range + 1 0 1 1 1 variable bit map + + The space this IE takes in the C-structure is depicted in the + example below: + typedef struct + { + U16 first; + U16 last; + U16 num; + U8 bitmap[128]; + } BMP_arfcn_list; + + The member bitmap stores a list of frequencies in a range of + 0 - 1023 (GSM), where some of the frequencies are not yet used. +*/ + +SHORT cdc_freq_list_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) +{ + U8 *FirstByte = globs->bitbuf + globs->bytepos; + ULONG cix_ref, num_prolog_steps, prolog_step_ref; + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "cdc_freq_list_decode()"); +#ifdef CCD_SYMBOLS + TRACE_CCD (globs, "decoding list %s with range 1024 format", + ccddata_get_alias((USHORT) e_ref, 1)); +#else + TRACE_CCD (globs, "decoding list %d of range 1024 format", melem[e_ref].elemRef); +#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 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->SeekTLVExt = FALSE; + globs->pstructOffs = melem[e_ref].structOffs; + + /* + * Bitmap 0 format + * only for GSM 900 or GSM 850 bands !!!! + * std = STD_900, STD_EGSM, STD_DUAL, STD_DUAL_EGSM, STD_850, STD_DUAL_US + * No check of std for being PCS 1900 or DCS 1800 is implemented. + */ + if ((*FirstByte & 0x80) == 0) + { + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "bitmap 0 format"); +#endif + /* + * Copy only the first 16 bytes. According to section 10.5.2.1b.2 of + * GSM04.08, 124 bits are dedicated to ARFCN and two bits to the Format-ID. + * Two bits are spare. + */ + FirstByte = globs->pstruct + globs->pstructOffs; + /* first bit */ + *(U16 *) FirstByte = 896;//T_LIST_MAX_SIZE - 16; + /* last bit */ + *(U16 *) (FirstByte+2) = T_LIST_MAX_SIZE; + /* number of entries */ + *(U16 *) (FirstByte+4) = 124; + memcpy (FirstByte + T_LIST_MAX_SIZE - 10, //FirstByte + 6 + T_LIST_MAX_SIZE - 16, + globs->bitbuf + globs->bytepos, 16); + } + else + { + U16 ListLength = mvar[melem[e_ref].elemRef].bSize; + U8 *BitmapInStruct = globs->pstruct + globs->pstructOffs; + first = 0; + last = 0; + num = 0; + /* + * RANGE 128, + */ + if ((*FirstByte & 0x8E) == 0x8C) + { + /* + * Use dynamic memory for calculation instead of global memory or stack. + */ + short *w; + MALLOC (w, 129 * sizeof (U16)); + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "range 128 format"); +#endif + + /* + * The algorithm for several ranges is the same with different + * tables. The W-parameter start with bit 7. Skip over offset. + */ + bf_incBitpos (7, globs); + cdc_decode_param (param_128, w, ListLength, globs); + + /* + * W[0] contains the first channel number + */ + setFirstChanNr (BitmapInStruct, w[0]); + + /* + * Decode and set the remaining channel number according the + * algorithm described in GSM 4.08. + */ + cdc_decode_frequencies (127, &w[1], w[0], FREQUENCY_LIST, globs); + completeAddInfo (BitmapInStruct); + + /* + * free the dynamic allocated memory. + */ + MFREE (w); + } + /* + * RANGE 256 + */ + if ((*FirstByte & 0x8E) == 0x8A) + { + /* + * Use dynamic memory for calculation instead of global memory or stack. + */ + short *w; + MALLOC (w, 257 * sizeof (U16)); + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "range 256 format"); +#endif + + /* + * Decode the W-parameter. The W-parameter start with bit 7. + */ + bf_incBitpos (7, globs); + cdc_decode_param (param_256, w, ListLength, globs); + + /* + * W[0] contains the first channel number + */ + setFirstChanNr (BitmapInStruct, w[0]); + + /* + * decode and set the remaining channel number according the + * algorithm described in GSM 4.08. + */ + cdc_decode_frequencies (255, &w[1], w[0], FREQUENCY_LIST, globs); + completeAddInfo (BitmapInStruct); + + /* + * free the dynamic allocated memory. + */ + MFREE (w); + } + /* + * RANGE 512 + */ + if ((*FirstByte & 0x8E) == 0x88) + { + /* + * Use dynamic memory for calculation instead of global memory or stack. + */ + short *w; + MALLOC (w, 257 * sizeof (U16)); + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "range 512 format"); +#endif + + /* + * the algorithm for the several ranges is the same with different + * tables. The W-parameter start with bit 7. Skip over offset. + */ + bf_incBitpos (7, globs); + cdc_decode_param (param_512, w, ListLength, globs); + + /* + * W[0] contains the first channel number + */ + setFirstChanNr (BitmapInStruct, w[0]); + + /* + * decode and set the remaining channel number according the + * algorithm described in GSM 4.08. + */ + cdc_decode_frequencies (511, &w[1], w[0], FREQUENCY_LIST, globs); + completeAddInfo (BitmapInStruct); + + /* + * free the dynamic allocated memory. + */ + MFREE (w); + } + + if ((*FirstByte & 0x88) == 0x80) + { + /* + * RANGE 1024 + * + * Use dynamic memory for calculation instead of global memory or stack. + */ + U8 f0; + U8 offset; + + short *w; + MALLOC (w, 257 * sizeof (U16)); + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "range 1024 format"); +#endif + + /* + * Get the f0 indicator. It indicates whether channel 0 is part + * of the frequency hopping list or not. + */ + /* The following lines are equal to: + * ccd_decodeByte (FirstByte, (U16)(globs->byteoffs+5), 1, &f0); + */ + offset = globs->byteoffs+5; + if (offset < 8) + { + f0 = FirstByte[0] << offset; + f0 &= 0x80; + } + else + { + U16 tmpvar; + tmpvar = *(U16*) FirstByte; + tmpvar <<= offset; + f0 = tmpvar & 0x8000; + } + + /* + * The algorithm for the several ranges is the same with different + * tables. The W-parameter start with bit 6. Skip over offset. + */ + bf_incBitpos (6, globs); + cdc_decode_param (param_1024, w, ListLength, globs); + + /* + * If indicated add channel 0 to the list + */ + if (f0) + { + /* The following is equal to setFirstChanNr(0); */ + BitmapInStruct[0] |= 0x80; + num = 1; + } + + /* + * decode and set the remaining channel number according the + * algorithm described in GSM 4.08. + */ + cdc_decode_frequencies (1023, &w[0], 0, FREQUENCY_LIST, globs); + completeAddInfo (BitmapInStruct); + + /* + * free the dynamic allocated memory. + */ + MFREE (w); + } + /* + * RANGE variable + */ + if ((*FirstByte & 0x8E) == 0x8E) + { + /* + * The format is similar to the bitmap 0 format. The + * calculation starts from a base channel number svalue + * instead of channel number 1. + */ + U32 lvalue; + U16 svalue; + U32 i; + U16 bitposition; + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "range variable format"); +#endif + + /* Get the first channel number. */ + bf_incBitpos (7, globs); + lvalue = bf_getBits (10, globs); + + /* Copy lvalue to svalue to set the correct channel. */ + svalue = (U16)lvalue; + setFirstChanNr (BitmapInStruct, svalue); + first = svalue; + num = 1; + for (i = 1; i < 112; i++) + { + /* + * Get the value of the next bit. + * If the bit is set, set channel i+svalue + */ + if (bf_readBit (globs)) + { + U16 channel = (U16)for_modulo(i+svalue, 1024); + + bitposition = (channel == 0) ? 0 : (U16)(BITOFFSET_LIST - channel); + BitmapInStruct[bitposition >> 3] |= ByteBitMask[bitposition & 7]; + last = bitposition; + num++; + } + } + completeAddInfo (BitmapInStruct); + } + } + + return 1; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : CCD MODULE : cdc_freq_list_encode | ++--------------------------------------------------------------------+ + + PURPOSE : Encoding function is not needed, since this message is + sent from net to MS. + It could be only useful for testing procedure if there + were an encoder function at this place. + This will be a future work. +*/ + +SHORT cdc_freq_list_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) +{ + +#ifdef DEBUG_CCD + TRACE_CCD (globs, "cdc_freq_list_encode()"); +#endif +#ifdef TARGET_WIN32 + /* TBD */ +#endif + + return 1; +} +#endif /* !RUN_INT_RAM */