FreeCalypso > hg > fc-selenite
comparison src/gpf/ccd/cdc_com.c @ 5:1ea54a97e831
src/gpf: import of Magnetite src/gpf3
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 15 Jul 2018 08:11:07 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 4:6e457872f745 | 5:1ea54a97e831 |
|---|---|
| 1 /* | |
| 2 +----------------------------------------------------------------------------- | |
| 3 | Project : | |
| 4 | Modul : cdc_com.c | |
| 5 +----------------------------------------------------------------------------- | |
| 6 | Copyright 2002 Texas Instruments Berlin, AG | |
| 7 | All rights reserved. | |
| 8 | | |
| 9 | This file is confidential and a trade secret of Texas | |
| 10 | Instruments Berlin, AG | |
| 11 | The receipt of or possession of this file does not convey | |
| 12 | any rights to reproduce or disclose its contents or to | |
| 13 | manufacture, use, or sell anything it may describe, in | |
| 14 | whole, or in part, without the specific written consent of | |
| 15 | Texas Instruments Berlin, AG. | |
| 16 +----------------------------------------------------------------------------- | |
| 17 | Purpose : Condat Conder Decoder | |
| 18 | Definitions of common functions for encoding and decoding of | |
| 19 | GSM, GPRS or UMTS air interface messages | |
| 20 +----------------------------------------------------------------------------- | |
| 21 */ | |
| 22 | |
| 23 #ifdef _MSDOS | |
| 24 #include <dos.h> | |
| 25 #include <conio.h> | |
| 26 #endif | |
| 27 | |
| 28 /* | |
| 29 * standard definitions like UCHAR, ERROR etc. | |
| 30 */ | |
| 31 #include "typedefs.h" | |
| 32 #include "header.h" | |
| 33 #include <string.h> | |
| 34 #include <stdlib.h> | |
| 35 | |
| 36 /* | |
| 37 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only | |
| 38 * look at ccdapi.h | |
| 39 */ | |
| 40 #undef USE_DRIVER | |
| 41 #include "ccdapi.h" | |
| 42 | |
| 43 /* | |
| 44 * Types and functions for bit access and manipulation | |
| 45 */ | |
| 46 #include "ccd_globs.h" | |
| 47 #include "bitfun.h" | |
| 48 | |
| 49 /* | |
| 50 * Declaration of coder/decoder-tables | |
| 51 */ | |
| 52 #include "ccdtable.h" | |
| 53 #include "ccddata.h" | |
| 54 | |
| 55 /* | |
| 56 * Prototypes and constants in the common part of ccd | |
| 57 */ | |
| 58 #include "ccd.h" | |
| 59 #include "ccd_codingtypes.h" | |
| 60 | |
| 61 /* | |
| 62 * Need memory allocation functions for dynamic arrays (pointers) | |
| 63 */ | |
| 64 #ifdef DYNAMIC_ARRAYS | |
| 65 #include "vsi.h" | |
| 66 #endif | |
| 67 | |
| 68 #ifndef RUN_FLASH | |
| 69 const UBYTE padding_bits[8] = {0, 0, 1, 0, 1, 0, 1, 1}; | |
| 70 const UBYTE padding_bits_prev[8] = {1, 0, 0, 1, 0, 1, 0, 1}; | |
| 71 #endif /* !RUN_FLASH */ | |
| 72 | |
| 73 #ifndef RUN_FLASH | |
| 74 /* Attention for RUN_...: static data (used in cdc_skipElem) */ | |
| 75 static UBYTE dummy[256]; | |
| 76 #endif /* !RUN_FLASH */ | |
| 77 | |
| 78 typedef struct unknownTag | |
| 79 { | |
| 80 U8 errCode; | |
| 81 U8 tag; | |
| 82 U16 bitpos; | |
| 83 struct unknownTag *next; | |
| 84 }T_UNKNOWN_TAG; | |
| 85 | |
| 86 | |
| 87 #ifndef RUN_FLASH | |
| 88 /* | |
| 89 +--------------------------------------------------------------------+ | |
| 90 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 91 | STATE : code ROUTINE : cdc_init_ctx_table | | |
| 92 +--------------------------------------------------------------------+ | |
| 93 | |
| 94 PURPOSE : init the iei_ctx table. This must be done before decoding | |
| 95 a message. | |
| 96 | |
| 97 */ | |
| 98 | |
| 99 static void cdc_init_ctx_table (T_CCD_Globs *globs) | |
| 100 { | |
| 101 int i; | |
| 102 | |
| 103 #ifdef DEBUG_CCD | |
| 104 TRACE_CCD (globs, "CONTEXT table init"); | |
| 105 #endif | |
| 106 | |
| 107 for (i=0; i<MAX_RECURSIONS_PER_MSG; i++) | |
| 108 { | |
| 109 globs->iei_ctx[i].valid = FALSE; | |
| 110 } | |
| 111 globs->numEOCPending = 0; | |
| 112 } | |
| 113 #endif /* !RUN_FLASH */ | |
| 114 | |
| 115 #ifndef RUN_INT_RAM | |
| 116 /* | |
| 117 +--------------------------------------------------------------------+ | |
| 118 | PROJECT : CCD (6144) MODULE : CCD | | |
| 119 | STATE : code ROUTINE : cdc_BCD_decode | | |
| 120 +--------------------------------------------------------------------+ | |
| 121 | |
| 122 PURPOSE : Decoding of an bitstream containing a BCD string | |
| 123 with k digits. If the first digit in the bitstream | |
| 124 is DIGIT_2, the digits are ordered | |
| 125 in the Bitstream as follow: | |
| 126 | |
| 127 MSBit LSBit | |
| 128 8 7 6 5 4 3 2 1 | |
| 129 DIGIT_2 DIGIT_1 Octett n | |
| 130 DIGIT_4 DIGIT_3 Octett n+1 | |
| 131 : : : : : : : : | |
| 132 DIGIT_Z DIGIT_X Octett n+m | |
| 133 | |
| 134 if the number of the digits is odd, the last | |
| 135 Octett contains the bit pattern 1111 in the | |
| 136 most significant nibble. | |
| 137 | |
| 138 : : : : : : : : | |
| 139 1 1 1 1 DIGIT_X Octett n+m | |
| 140 | |
| 141 NOTE: If the first digit in the bitstream is DIGIT_1, | |
| 142 the digits are ordered in a different way: | |
| 143 | |
| 144 MSBit LSBit | |
| 145 8 7 6 5 4 3 2 1 | |
| 146 DIGIT_1 XXXXXXX Octett n | |
| 147 DIGIT_3 DIGIT_2 Octett n+1 | |
| 148 DIGIT_5 DIGIT_4 Octett n+2 | |
| 149 : : : : : : : : | |
| 150 DIGIT_Z DIGIT_X Octett n+m | |
| 151 | |
| 152 In this case, if the number of the digits | |
| 153 is even, the last octett contains the bit | |
| 154 pattern 1111 in the most significant nibble. | |
| 155 | |
| 156 : : : : : : : : | |
| 157 1 1 1 1 DIGIT_X Octett n+m | |
| 158 | |
| 159 The amount of digits may be constant or variable. | |
| 160 | |
| 161 NOTE: A special case (type BCD_NOFILL) is the encoding and | |
| 162 decoding of a BCD string starting with DIGIT_2 but | |
| 163 without setting/checking the most significant nibble | |
| 164 of Octet n+m. This nibble belongs to the next IE | |
| 165 (usual coded by type BCD_MNC). | |
| 166 Type BCD_NOFILL is coded by startDigit EQ 2. | |
| 167 */ | |
| 168 | |
| 169 void cdc_BCD_decode (const ULONG e_ref, UBYTE startDigit, T_CCD_Globs *globs) | |
| 170 { | |
| 171 BOOL is_variable; | |
| 172 UBYTE *digits; | |
| 173 UBYTE *addr_c_xxx; | |
| 174 ULONG i, max_rep, nibbles_to_read, repeat; | |
| 175 ULONG cix_ref, num_prolog_steps, prolog_step_ref; | |
| 176 int k; | |
| 177 | |
| 178 #ifdef DEBUG_CCD | |
| 179 #ifndef CCD_SYMBOLS | |
| 180 TRACE_CCD (globs, "cdc_BCD_decode()"); | |
| 181 #else | |
| 182 TRACE_CCD (globs, "cdc_BCD_decode() %s", ccddata_get_alias((USHORT) e_ref, 1)); | |
| 183 #endif | |
| 184 #endif | |
| 185 | |
| 186 cix_ref = melem[e_ref].calcIdxRef; | |
| 187 num_prolog_steps = calcidx[cix_ref].numPrologSteps; | |
| 188 prolog_step_ref = calcidx[cix_ref].prologStepRef; | |
| 189 | |
| 190 /* | |
| 191 * if this element is conditional, check the condition | |
| 192 */ | |
| 193 if (calcidx[cix_ref].numCondCalcs NEQ 0 | |
| 194 AND ! ccd_conditionOK (e_ref, globs)) | |
| 195 return; | |
| 196 | |
| 197 /* | |
| 198 * if this element have a defined Prolog | |
| 199 * we have to process it before decoding the bitstream | |
| 200 */ | |
| 201 if (num_prolog_steps) | |
| 202 { | |
| 203 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); | |
| 204 } | |
| 205 | |
| 206 /* | |
| 207 * if this element is repeatable, and the number of | |
| 208 * repeats depends on another element, calculate the repeater | |
| 209 */ | |
| 210 | |
| 211 if (melem[e_ref].repType NEQ ' ') | |
| 212 { | |
| 213 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs); | |
| 214 } | |
| 215 else | |
| 216 { | |
| 217 repeat = 1; | |
| 218 is_variable = FALSE; | |
| 219 } | |
| 220 | |
| 221 /* | |
| 222 * setup the offset into the C-structure for this element | |
| 223 */ | |
| 224 globs->pstructOffs = melem[e_ref].structOffs; | |
| 225 | |
| 226 if (melem[e_ref].optional) | |
| 227 { | |
| 228 /* | |
| 229 * for optional elements set the valid-flag | |
| 230 */ | |
| 231 globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE; | |
| 232 } | |
| 233 | |
| 234 | |
| 235 if (is_variable) | |
| 236 { | |
| 237 /* | |
| 238 * for variable sized elements store the min-value | |
| 239 * as counter into the C-Structure (c_xxx). | |
| 240 */ | |
| 241 addr_c_xxx = (UBYTE *) (globs->pstruct + globs->pstructOffs++); | |
| 242 if (max_rep > 255) | |
| 243 globs->pstructOffs++; | |
| 244 } | |
| 245 else | |
| 246 addr_c_xxx = NULL; | |
| 247 | |
| 248 digits = (UBYTE *) (globs->pstruct + globs->pstructOffs); | |
| 249 | |
| 250 | |
| 251 if (startDigit EQ 1) | |
| 252 { | |
| 253 /* | |
| 254 * read the BCD digits out of the bitstream. | |
| 255 * The read order is 1,X,3,2,5,4 ... | |
| 256 */ | |
| 257 /* | |
| 258 * if the first digit is digit_1 read it and skip | |
| 259 * the next 4 bits, because they do not belong to | |
| 260 * the BCD stream. | |
| 261 */ | |
| 262 digits[0] = bf_decodeByteNumber (4, globs); | |
| 263 bf_incBitpos (4, globs); | |
| 264 /* | |
| 265 * make a correction on the repeatvalue | |
| 266 */ | |
| 267 if (melem[e_ref].repType NEQ ' ') | |
| 268 { | |
| 269 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs); | |
| 270 } | |
| 271 | |
| 272 k = 2; | |
| 273 | |
| 274 for (i=0; i<repeat; i++) | |
| 275 { | |
| 276 digits[k] = bf_decodeByteNumber (4, globs); | |
| 277 #ifdef DEBUG_CCD | |
| 278 TRACE_CCD (globs, "BCD digit (%X) read", (USHORT) digits[k]); | |
| 279 #endif | |
| 280 k = ((k&1) EQ 0) ? (k-1) : (k+3); | |
| 281 } | |
| 282 } | |
| 283 else | |
| 284 { | |
| 285 /* | |
| 286 * read the BCD digits out of the bitstream. | |
| 287 * The read order is 2,1,4,3,6,5 ... | |
| 288 */ | |
| 289 k = 1; | |
| 290 | |
| 291 nibbles_to_read = repeat; | |
| 292 | |
| 293 if (repeat & 1) | |
| 294 nibbles_to_read++; | |
| 295 | |
| 296 for (i=0; i<nibbles_to_read; i++) | |
| 297 { | |
| 298 digits[k] = bf_decodeByteNumber (4, globs); | |
| 299 #ifdef DEBUG_CCD | |
| 300 TRACE_CCD (globs, "BCD digit (%X) read", (USHORT) digits[k]); | |
| 301 #endif | |
| 302 k = ((k&1) EQ 1) ? (k-1) : (k+3); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 /* | |
| 307 * check the 1111 pattern and the even odd criteria | |
| 308 */ | |
| 309 | |
| 310 if (startDigit EQ 1) | |
| 311 { | |
| 312 if ((repeat & 1) EQ 0) | |
| 313 { | |
| 314 /* even number of digits */ | |
| 315 if (digits[repeat] NEQ 0xf) | |
| 316 repeat++; | |
| 317 } | |
| 318 } | |
| 319 else | |
| 320 { | |
| 321 if ((repeat & 1) EQ 1) | |
| 322 { | |
| 323 /* odd number of digits */ | |
| 324 if (digits[repeat] NEQ 0xf AND startDigit EQ 0) | |
| 325 { | |
| 326 /* | |
| 327 * if there is no 1111 pattern generate an error | |
| 328 */ | |
| 329 ccd_setError (globs, ERR_PATTERN_MISMATCH, | |
| 330 CONTINUE, | |
| 331 (USHORT) (globs->bitpos-8), (USHORT) -1); | |
| 332 } | |
| 333 } | |
| 334 | |
| 335 else | |
| 336 { | |
| 337 /* even number of digits - the last may be 0xf */ | |
| 338 if (digits[repeat-1] EQ 0xf) | |
| 339 repeat--; /* 0x0f dosn't belong to the coded digit string */ | |
| 340 } | |
| 341 } | |
| 342 | |
| 343 if (addr_c_xxx NEQ NULL) | |
| 344 { | |
| 345 /* | |
| 346 * store the number of digits into the | |
| 347 * c_xxx variable if there is one. | |
| 348 */ | |
| 349 if (max_rep > 65535) | |
| 350 { | |
| 351 ULONG *addr_c_xxx_u32; | |
| 352 addr_c_xxx_u32 = (ULONG *)addr_c_xxx; | |
| 353 *addr_c_xxx_u32 = repeat; | |
| 354 } | |
| 355 else if (max_rep > 255) | |
| 356 { | |
| 357 USHORT *addr_c_xxx_u16; | |
| 358 addr_c_xxx_u16 = (USHORT *)addr_c_xxx; | |
| 359 *addr_c_xxx_u16 = (USHORT) repeat; | |
| 360 } | |
| 361 else | |
| 362 *addr_c_xxx = (UBYTE) repeat; | |
| 363 } | |
| 364 } | |
| 365 #endif /* !RUN_INT_RAM */ | |
| 366 | |
| 367 #ifndef RUN_INT_RAM | |
| 368 /* | |
| 369 +--------------------------------------------------------------------+ | |
| 370 | PROJECT : CCD (6144) MODULE : CCD | | |
| 371 | STATE : code ROUTINE : cdc_BCD_encode | | |
| 372 +--------------------------------------------------------------------+ | |
| 373 | |
| 374 PURPOSE : encoding a Bytearray, that contain a BCD Number, into | |
| 375 bitstream. | |
| 376 The digits coded in the following order | |
| 377 into the Bitstream: | |
| 378 | |
| 379 MSBit LSBit | |
| 380 7 8 6 5 4 3 2 1 | |
| 381 DIGIT_2 DIGIT_1 Octett n | |
| 382 DIGIT_4 DIGIT_3 Octett n+1 | |
| 383 : : : : : : : : | |
| 384 DIGIT_Z DIGIT_X Octett n+m | |
| 385 | |
| 386 if the number of the digits are odd, the bit pattern 1111 | |
| 387 will be coded in the most significant nibble of | |
| 388 the last Octett. | |
| 389 | |
| 390 : : : : : : : : | |
| 391 1 1 1 1 DIGIT_X Octett n+m | |
| 392 | |
| 393 The amount of digits may be constant or variable. | |
| 394 */ | |
| 395 void cdc_BCD_encode (const ULONG e_ref, UBYTE startDigit, T_CCD_Globs *globs) | |
| 396 { | |
| 397 ULONG repeat; | |
| 398 int k; | |
| 399 register UBYTE *digits; | |
| 400 BOOL fullBitsNeeded=FALSE; | |
| 401 ULONG cix_ref, num_prolog_steps, prolog_step_ref; | |
| 402 | |
| 403 #ifdef DEBUG_CCD | |
| 404 #ifndef CCD_SYMBOLS | |
| 405 TRACE_CCD (globs, "cdc_BCD_encode()"); | |
| 406 #else | |
| 407 TRACE_CCD (globs, "cdc_BCD_encode() %s", ccddata_get_alias((USHORT) e_ref, 1)); | |
| 408 #endif | |
| 409 #endif | |
| 410 | |
| 411 cix_ref = melem[e_ref].calcIdxRef; | |
| 412 num_prolog_steps = calcidx[cix_ref].numPrologSteps; | |
| 413 prolog_step_ref = calcidx[cix_ref].prologStepRef; | |
| 414 | |
| 415 /* | |
| 416 * if this element is conditional, check the condition | |
| 417 */ | |
| 418 if (calcidx[cix_ref].numCondCalcs NEQ 0 | |
| 419 AND ! ccd_conditionOK (e_ref, globs)) | |
| 420 return; | |
| 421 | |
| 422 /* | |
| 423 * if this element have a defined Prolog | |
| 424 * we have to process it before decoding the bitstream | |
| 425 */ | |
| 426 if (num_prolog_steps) | |
| 427 { | |
| 428 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); | |
| 429 } | |
| 430 | |
| 431 /* | |
| 432 * setup the offset into the C-structure for this element | |
| 433 */ | |
| 434 globs->pstructOffs = melem[e_ref].structOffs; | |
| 435 | |
| 436 if (melem[e_ref].optional) | |
| 437 { | |
| 438 /* | |
| 439 * for optional elements check the valid-flag | |
| 440 */ | |
| 441 if (globs->pstruct[globs->pstructOffs++] == FALSE) | |
| 442 return; | |
| 443 #ifdef DEBUG_CCD | |
| 444 else if (globs->pstruct [melem[e_ref].structOffs] != TRUE) | |
| 445 { | |
| 446 TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d", | |
| 447 e_ref); | |
| 448 } | |
| 449 #endif | |
| 450 } | |
| 451 | |
| 452 /* | |
| 453 * if this element is repeatable, and the number of | |
| 454 * repeats depends on another element, calculate the repeater | |
| 455 */ | |
| 456 if (melem[e_ref].repType EQ 'v' OR melem[e_ref].repType EQ 'i') | |
| 457 { | |
| 458 /* | |
| 459 * for variable sized elements read the amount | |
| 460 * of repeats out of the C-Structure (c_xxx). | |
| 461 * If the number of repeats given by the C-Structure | |
| 462 * exceeds the allowed value (maxRepeat) CCD gives a warning! | |
| 463 */ | |
| 464 if (melem[e_ref].maxRepeat > 255) | |
| 465 { | |
| 466 ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++)); | |
| 467 repeat = MINIMUM (count, (ULONG) melem[e_ref].maxRepeat); | |
| 468 if (repeat < count) | |
| 469 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, | |
| 470 e_ref, globs->pstruct + globs->pstructOffs); | |
| 471 } | |
| 472 else | |
| 473 { | |
| 474 repeat = (ULONG)MINIMUM (globs->pstruct[globs->pstructOffs], | |
| 475 melem[e_ref].maxRepeat); | |
| 476 if ( repeat < (ULONG) (globs->pstruct[globs->pstructOffs]) ) | |
| 477 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, | |
| 478 (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 479 } | |
| 480 globs->pstructOffs++; | |
| 481 } | |
| 482 else | |
| 483 if (melem[e_ref].repType EQ 'c') | |
| 484 repeat = (ULONG) melem[e_ref].maxRepeat; | |
| 485 else | |
| 486 repeat = 1; | |
| 487 | |
| 488 /* There seems to exist cases where address contains no digits. */ | |
| 489 if (repeat EQ 0) | |
| 490 return; | |
| 491 | |
| 492 /* | |
| 493 * setup the read pointer to the byte array that contain | |
| 494 * the BCD number. | |
| 495 */ | |
| 496 digits = (UBYTE *) (globs->pstruct + globs->pstructOffs); | |
| 497 | |
| 498 if (startDigit EQ 1) | |
| 499 { | |
| 500 /* | |
| 501 * write the BCD digits into the bitstream. | |
| 502 * The write order is 1,X,3,2,5,4 ... | |
| 503 */ | |
| 504 if ((repeat & 1) EQ 0) | |
| 505 { | |
| 506 /* | |
| 507 * for even digits store the 1111 pattern at last digit | |
| 508 */ | |
| 509 fullBitsNeeded = TRUE; | |
| 510 } | |
| 511 /* | |
| 512 * if the first digit is digit_1 write it and skip | |
| 513 * the next 4 bits, because they does not belong to | |
| 514 * the BCD stream. | |
| 515 */ | |
| 516 bf_codeByteNumber (4, digits[0], globs); | |
| 517 | |
| 518 #ifdef DEBUG_CCD | |
| 519 TRACE_CCD (globs, "BCD digit (%X) written", (USHORT) digits[0]); | |
| 520 TRACE_CCD (globs, "skipping 4 bits"); | |
| 521 #endif | |
| 522 | |
| 523 bf_incBitpos (4, globs); | |
| 524 k = 2; | |
| 525 | |
| 526 while (--repeat>1) | |
| 527 { | |
| 528 bf_codeByteNumber (4, digits[k], globs); | |
| 529 #ifdef DEBUG_CCD | |
| 530 TRACE_CCD (globs, "BCD digit (%X) written", (USHORT) digits[k]); | |
| 531 #endif | |
| 532 k = ((k&1) EQ 0) ? (k-1) : (k+3); | |
| 533 } | |
| 534 if (repeat) | |
| 535 { | |
| 536 if (fullBitsNeeded) | |
| 537 { | |
| 538 bf_codeByteNumber (4, 0xf, globs); | |
| 539 k = ((k&1) EQ 0) ? (k-1) : (k+3); | |
| 540 } | |
| 541 bf_codeByteNumber (4, digits[k], globs); | |
| 542 } | |
| 543 | |
| 544 } | |
| 545 else | |
| 546 { | |
| 547 /* | |
| 548 * store the BCD digits into the bitstream. | |
| 549 * The write order is 2,1,4,3,6,5 ... | |
| 550 */ | |
| 551 if (repeat & 1) | |
| 552 { | |
| 553 /* | |
| 554 * for odd digits store the 1111 pattern at last digit | |
| 555 * in case of type BCD_NOFILL use 0 instead | |
| 556 */ | |
| 557 fullBitsNeeded = TRUE; | |
| 558 } | |
| 559 | |
| 560 k = 1; | |
| 561 | |
| 562 while ( repeat-- > 1) | |
| 563 { | |
| 564 bf_codeByteNumber (4, digits[k], globs); | |
| 565 #ifdef DEBUG_CCD | |
| 566 TRACE_CCD (globs, "BCD digit (%X) written", (USHORT) digits[k]); | |
| 567 #endif | |
| 568 k = ((k&1) EQ 1) ? (k-1) : (k+3); | |
| 569 } | |
| 570 if (fullBitsNeeded) | |
| 571 { | |
| 572 bf_codeByteNumber (4, (UBYTE)((startDigit NEQ 2) ? 0xf : 0), globs); | |
| 573 k = ((k&1) EQ 1) ? (k-1) : (k+3); | |
| 574 } | |
| 575 bf_codeByteNumber (4, digits[k], globs); | |
| 576 } | |
| 577 } | |
| 578 #endif /* !RUN_INT_RAM */ | |
| 579 | |
| 580 #ifndef RUN_FLASH | |
| 581 /* Attention for RUN_...: static function */ | |
| 582 /* | |
| 583 +--------------------------------------------------------------------+ | |
| 584 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 585 | STATE : code ROUTINE : cdc_init_table | | |
| 586 +--------------------------------------------------------------------+ | |
| 587 | |
| 588 PURPOSE : init the iei_table for each new msg that is to be decoded. | |
| 589 The c_ref references a composition (msg). The function | |
| 590 initialises the table entrys only for the used iei for | |
| 591 this message. | |
| 592 | |
| 593 */ | |
| 594 | |
| 595 static void cdc_init_table (const ULONG c_ref, T_CCD_Globs *globs) | |
| 596 | |
| 597 { | |
| 598 ULONG look_up; | |
| 599 ULONG num_elems; | |
| 600 ULONG ie_table_idx; | |
| 601 ULONG rlevel = globs->ccd_recurs_level; | |
| 602 | |
| 603 if (globs->iei_ctx[rlevel].valid AND rlevel < (ULONG) globs->last_level) | |
| 604 { | |
| 605 int i; | |
| 606 /* | |
| 607 * this iei context has been initialized before, so | |
| 608 * no action for this. All deeper levels must be set | |
| 609 * to invalid; | |
| 610 */ | |
| 611 for (i=globs->last_level; i<MAX_RECURSIONS_PER_MSG; i++) | |
| 612 globs->iei_ctx[i].valid = FALSE; | |
| 613 | |
| 614 #ifdef DEBUG_CCD | |
| 615 TRACE_CCD (globs, "TAG table init for old level %d", rlevel); | |
| 616 #endif | |
| 617 } | |
| 618 else | |
| 619 { | |
| 620 /* | |
| 621 * this iei context has not been initialized before, so | |
| 622 * initialize the iei_table for this. | |
| 623 */ | |
| 624 #ifdef DEBUG_CCD | |
| 625 TRACE_CCD (globs, "TAG table init for new level %d", rlevel); | |
| 626 #endif | |
| 627 look_up = (ULONG) mcomp[c_ref].componentRef; | |
| 628 num_elems = (ULONG) mcomp[c_ref].numOfComponents; | |
| 629 | |
| 630 /* | |
| 631 * store the startposition of the corresponding melem table and | |
| 632 * the number of elements in the IEtable | |
| 633 */ | |
| 634 globs->iei_ctx[rlevel].melemStart = (USHORT) look_up; | |
| 635 globs->iei_ctx[rlevel].ieTableLen = (USHORT) num_elems; | |
| 636 globs->iei_ctx[rlevel].EOCPending = FALSE; | |
| 637 globs->iei_ctx[rlevel].countSkipped = 0; | |
| 638 | |
| 639 /* | |
| 640 * for each element with an iei (ident) setup the | |
| 641 * the iei_table-entry. | |
| 642 */ | |
| 643 ie_table_idx = 0; | |
| 644 | |
| 645 /* | |
| 646 * if the number of IE in this message is greater than | |
| 647 * the allocated IEItable, generate an error. | |
| 648 */ | |
| 649 if (num_elems > MAX_IE_PER_MSG) | |
| 650 ccd_setError (globs, ERR_INTERNAL_ERROR, BREAK, (USHORT) -1); | |
| 651 | |
| 652 while (num_elems--) | |
| 653 { | |
| 654 if (melem[look_up].ident NEQ 0xffff) | |
| 655 { | |
| 656 globs->iei_ctx[rlevel].iei_table[ie_table_idx].ident = (UBYTE) melem[look_up].ident; | |
| 657 | |
| 658 /* | |
| 659 * GSM1TV elements have only a 4 bit Tag (T). For this | |
| 660 * elements we have to shift the ident into the upper nibble | |
| 661 * and set the lower nibble to zero. For GSM2T elements and | |
| 662 * GSM1TV elements set the MSBit (Bit7). | |
| 663 */ | |
| 664 if (melem[look_up].codingType EQ CCDTYPE_GSM1_TV) | |
| 665 { | |
| 666 /* | |
| 667 * shift into the upper nibble, clear the lower nibble | |
| 668 * and set the MSBit. | |
| 669 */ | |
| 670 globs->iei_ctx[rlevel].iei_table[ie_table_idx].ident <<= 4; | |
| 671 globs->iei_ctx[rlevel].iei_table[ie_table_idx].ident |= 0x80; | |
| 672 globs->iei_ctx[rlevel].iei_table[ie_table_idx].ident &= 0xf0; | |
| 673 } | |
| 674 else | |
| 675 { | |
| 676 if (melem[look_up].codingType EQ CCDTYPE_GSM2_T) | |
| 677 { | |
| 678 /* | |
| 679 * Set the MSBit. | |
| 680 */ | |
| 681 globs->iei_ctx[rlevel].iei_table[ie_table_idx].ident |= 0x80; | |
| 682 } | |
| 683 } | |
| 684 globs->iei_ctx[rlevel].iei_table[ie_table_idx].act_amount = 0; | |
| 685 globs->iei_ctx[rlevel].iei_table[ie_table_idx].exhausted = FALSE; | |
| 686 | |
| 687 switch (melem[look_up].codingType) | |
| 688 { | |
| 689 case CCDTYPE_GSM1_TV: | |
| 690 | |
| 691 case CCDTYPE_GSM2_T: | |
| 692 | |
| 693 case CCDTYPE_GSM3_TV: | |
| 694 | |
| 695 case CCDTYPE_GSM4_TLV: | |
| 696 | |
| 697 case CCDTYPE_GSM5_TV: | |
| 698 | |
| 699 case CCDTYPE_GSM5_TLV: | |
| 700 | |
| 701 case CCDTYPE_GSM1_ASN: | |
| 702 | |
| 703 case CCDTYPE_GSM6_TLV: | |
| 704 | |
| 705 globs->iei_ctx[rlevel].iei_table[ie_table_idx].valid = TRUE; | |
| 706 break; | |
| 707 | |
| 708 default: | |
| 709 globs->iei_ctx[rlevel].iei_table[ie_table_idx].valid = FALSE; | |
| 710 break; | |
| 711 } | |
| 712 } | |
| 713 else | |
| 714 globs->iei_ctx[rlevel].iei_table[ie_table_idx].valid = FALSE; | |
| 715 | |
| 716 #ifdef DEBUG_CCD | |
| 717 TRACE_CCD (globs, "iei_table[%d] v=%d ident=%x level=%d", | |
| 718 ie_table_idx, | |
| 719 globs->iei_ctx[rlevel].iei_table[ie_table_idx].valid, | |
| 720 globs->iei_ctx[rlevel].iei_table[ie_table_idx].ident, | |
| 721 rlevel); | |
| 722 #endif | |
| 723 | |
| 724 look_up++; | |
| 725 ie_table_idx++; | |
| 726 } | |
| 727 globs->iei_ctx[rlevel].valid = TRUE; | |
| 728 } | |
| 729 } | |
| 730 #endif /* !RUN_FLASH */ | |
| 731 | |
| 732 #ifndef RUN_FLASH | |
| 733 /* Attention for RUN_...: static function */ | |
| 734 /* | |
| 735 +--------------------------------------------------------------------+ | |
| 736 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 737 | STATE : code ROUTINE : cdc_search_table | | |
| 738 +--------------------------------------------------------------------+ | |
| 739 | |
| 740 PURPOSE : search on the iei_table for the given TAG (T). | |
| 741 if the TAG can be found (and - in case of CCDTYPE_GSM1_ASN - | |
| 742 if the information element isn't exhausted), the table | |
| 743 index was returned as a difference between the found index | |
| 744 and the aktIndex, -127 otherwise. | |
| 745 | |
| 746 */ | |
| 747 | |
| 748 static int cdc_search_table | |
| 749 ( | |
| 750 int akt_index, | |
| 751 ULONG t, | |
| 752 BOOL limited, | |
| 753 BOOL *nonTaggedFound, | |
| 754 T_CCD_Globs *globs | |
| 755 ) | |
| 756 { | |
| 757 int tab_idx; | |
| 758 ULONG iei; | |
| 759 int ret = -127; | |
| 760 ULONG rec_level = globs->ccd_recurs_level; | |
| 761 | |
| 762 /* | |
| 763 * search from the akt position to the end of the table. | |
| 764 * This is faster, because in correct messages the found Tag | |
| 765 * is at a later position in the table. | |
| 766 */ | |
| 767 tab_idx = akt_index; | |
| 768 | |
| 769 *nonTaggedFound = FALSE; | |
| 770 | |
| 771 while (tab_idx < (int) globs->iei_ctx[rec_level].ieTableLen) | |
| 772 { | |
| 773 #ifdef DEBUG_CCD | |
| 774 TRACE_CCD (globs, "looking for Tag(%x) iei_table[%d] v=%d ident=%x level=%d", | |
| 775 t, tab_idx, | |
| 776 globs->iei_ctx[rec_level].iei_table[tab_idx].valid, | |
| 777 globs->iei_ctx[rec_level].iei_table[tab_idx].ident, | |
| 778 rec_level); | |
| 779 #endif | |
| 780 | |
| 781 if (globs->iei_ctx[rec_level].iei_table[tab_idx].valid) | |
| 782 { | |
| 783 if (limited) | |
| 784 { | |
| 785 iei= (ULONG)(globs->iei_ctx[rec_level].iei_table[tab_idx].ident & 0x7f); | |
| 786 } | |
| 787 else | |
| 788 { | |
| 789 iei= (ULONG)(globs->iei_ctx[rec_level].iei_table[tab_idx].ident); | |
| 790 } | |
| 791 if ( iei EQ t ) | |
| 792 { | |
| 793 if ( globs->iei_ctx[rec_level].iei_table[tab_idx].exhausted EQ FALSE ) | |
| 794 { | |
| 795 return (tab_idx-akt_index); | |
| 796 } | |
| 797 else if ( (globs->iei_ctx[rec_level].melemStart + akt_index) | |
| 798 EQ (int) globs->iei_ctx[rec_level].melemLast) | |
| 799 { | |
| 800 /* | |
| 801 * allows multiple appearance of the repeated element is coded as | |
| 802 * TLV0 TLV1 TLV2 .... | |
| 803 */ | |
| 804 return (tab_idx-akt_index); | |
| 805 } | |
| 806 else | |
| 807 { | |
| 808 ret = (tab_idx-akt_index); | |
| 809 } | |
| 810 } | |
| 811 } | |
| 812 else | |
| 813 *nonTaggedFound = TRUE; | |
| 814 tab_idx++; | |
| 815 } | |
| 816 | |
| 817 tab_idx = 0; | |
| 818 | |
| 819 while (tab_idx < akt_index) | |
| 820 { | |
| 821 #ifdef DEBUG_CCD | |
| 822 TRACE_CCD (globs, "looking for Tag(%x) iei_table[%d] v=%d ident=%x level=%d", | |
| 823 t, tab_idx, | |
| 824 globs->iei_ctx[rec_level].iei_table[tab_idx].valid, | |
| 825 globs->iei_ctx[rec_level].iei_table[tab_idx].ident, | |
| 826 rec_level); | |
| 827 #endif | |
| 828 if (limited) | |
| 829 { | |
| 830 iei= (ULONG)(globs->iei_ctx[rec_level].iei_table[tab_idx].ident & 0x7f); | |
| 831 } | |
| 832 else | |
| 833 { | |
| 834 iei= (ULONG) globs->iei_ctx[rec_level].iei_table[tab_idx].ident; | |
| 835 } | |
| 836 if (globs->iei_ctx[rec_level].iei_table[tab_idx].valid | |
| 837 AND (iei EQ t) ) | |
| 838 { | |
| 839 if ( globs->iei_ctx[rec_level].iei_table[tab_idx].exhausted EQ FALSE ) | |
| 840 { | |
| 841 return (tab_idx-akt_index); | |
| 842 } | |
| 843 else | |
| 844 { | |
| 845 ret = (tab_idx-akt_index); | |
| 846 } | |
| 847 } | |
| 848 tab_idx++; | |
| 849 } | |
| 850 | |
| 851 if (ret != -127) | |
| 852 { | |
| 853 globs->SequenceError = TRUE; | |
| 854 } | |
| 855 | |
| 856 return ret; | |
| 857 } | |
| 858 #endif /* !RUN_FLASH */ | |
| 859 | |
| 860 #ifndef RUN_FLASH | |
| 861 /* Attention for RUN_...: static function */ | |
| 862 /* | |
| 863 +--------------------------------------------------------------------+ | |
| 864 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 865 | STATE : code ROUTINE : cdc_decode_L | | |
| 866 +--------------------------------------------------------------------+ | |
| 867 | |
| 868 PURPOSE : Decode the length element of TLV and LV values | |
| 869 */ | |
| 870 | |
| 871 static ULONG cdc_decode_L (const ULONG e_ref, const ULONG len_l, T_CCD_Globs *globs) | |
| 872 { | |
| 873 ULONG l; | |
| 874 | |
| 875 switch (melem[e_ref].codingType) | |
| 876 { | |
| 877 case CCDTYPE_GSM1_ASN: | |
| 878 l = (ULONG) bf_decodeByteNumber (8, globs); | |
| 879 #ifdef DEBUG_CCD | |
| 880 TRACE_CCD (globs, "decoding 8 bits, l = (%x)", l); | |
| 881 #endif | |
| 882 if (l EQ 0x80) | |
| 883 l = 0xFFFF; | |
| 884 else if (l EQ 0x81) | |
| 885 { | |
| 886 l = (ULONG) bf_decodeByteNumber (8, globs); | |
| 887 #ifdef DEBUG_CCD | |
| 888 TRACE_CCD (globs, "decoding 8 bits after 0x81, l = (%x)", l); | |
| 889 #endif | |
| 890 } | |
| 891 else if (l EQ 0x82) | |
| 892 { | |
| 893 l = bf_decodeShortNumber (16, globs); | |
| 894 #ifdef DEBUG_CCD | |
| 895 TRACE_CCD (globs, "decoding 16 bits after 0x82, l = (%x)", l); | |
| 896 #endif | |
| 897 } | |
| 898 break; | |
| 899 | |
| 900 case CCDTYPE_GSM5_TLV: | |
| 901 l = (ULONG) bf_decodeByteNumber (8, globs); | |
| 902 | |
| 903 if (l EQ 0x81) | |
| 904 { | |
| 905 l = (ULONG) bf_decodeByteNumber (8, globs); | |
| 906 #ifdef DEBUG_CCD | |
| 907 TRACE_CCD (globs, "decoding 8 bits after 0x81, l = (%x)", l); | |
| 908 } | |
| 909 else | |
| 910 { | |
| 911 TRACE_CCD (globs, "decoding 8 bits, l = (%x)", l); | |
| 912 #endif | |
| 913 } | |
| 914 break; | |
| 915 | |
| 916 case CCDTYPE_GSM6_TLV: | |
| 917 l = bf_decodeShortNumber (16, globs); | |
| 918 #ifdef DEBUG_CCD | |
| 919 TRACE_CCD (globs, "decoding 16 bits, l = (%x)", l); | |
| 920 #endif | |
| 921 break; | |
| 922 | |
| 923 default: | |
| 924 l = (ULONG) bf_decodeByteNumber (len_l, globs); | |
| 925 #ifdef DEBUG_CCD | |
| 926 TRACE_CCD (globs, "decoding %d bits, l = (%x)", len_l, l); | |
| 927 #endif | |
| 928 break; | |
| 929 } | |
| 930 | |
| 931 /* | |
| 932 * Write the value of l at the end of UPN Stack. | |
| 933 * this could be read by an IE of the coding type NO_CODE. | |
| 934 */ | |
| 935 globs->KeepReg[0] = l ; | |
| 936 return l; | |
| 937 } | |
| 938 #endif /* !RUN_FLASH */ | |
| 939 | |
| 940 #ifndef RUN_FLASH | |
| 941 /* Attention for RUN_...: static function */ | |
| 942 /* | |
| 943 +--------------------------------------------------------------------+ | |
| 944 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 945 | STATE : code ROUTINE : cdc_tagged_LV_decode| | |
| 946 +--------------------------------------------------------------------+ | |
| 947 | |
| 948 PURPOSE : If the parameter lenL is set to a positive value, | |
| 949 this function decodes the L-component. | |
| 950 After this it decodes the element referenced | |
| 951 by eRef out of the bitstream into the C-Structure | |
| 952 (globs->pstruct) at position globs->pstructOffs. | |
| 953 If a repeat value is defined for this element, | |
| 954 this function decodes only one appeareance | |
| 955 of the element because it is a tagged | |
| 956 element. In this case the decoded element is stored in | |
| 957 an array wich is indexed by eIndex; | |
| 958 */ | |
| 959 | |
| 960 static BOOL cdc_tagged_LV_decode (const ULONG e_ref, | |
| 961 ULONG e_index, | |
| 962 const ULONG len_l, | |
| 963 T_CCD_Globs *globs) | |
| 964 { | |
| 965 ULONG amount, l; | |
| 966 USHORT act_maxBP, tmp_maxBP; | |
| 967 BOOL endOfComposition = FALSE; | |
| 968 BOOL asn1=FALSE; | |
| 969 U32 offset=0; | |
| 970 #ifdef DYNAMIC_ARRAYS | |
| 971 U8 *old_pstruct = NULL; | |
| 972 #endif | |
| 973 | |
| 974 if (melem[e_ref].codingType EQ CCDTYPE_GSM1_ASN) | |
| 975 asn1 = TRUE; | |
| 976 | |
| 977 if (melem[e_ref].elemType NEQ 'S') | |
| 978 { | |
| 979 /* | |
| 980 * set the offset into the C-structure for this element. | |
| 981 */ | |
| 982 if (melem[e_ref].optional) | |
| 983 { | |
| 984 globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE; | |
| 985 } | |
| 986 | |
| 987 if (melem[e_ref].repType EQ 'i') | |
| 988 { | |
| 989 /* | |
| 990 * The number of appearance of all repeatable IEs may | |
| 991 * differ in a message. So we have to store the number | |
| 992 * in a c_xxx counter into the C-Structure. | |
| 993 */ | |
| 994 if (melem[e_ref].maxRepeat > 65535) | |
| 995 *(ULONG *) (globs->pstruct + globs->pstructOffs++) = e_index; | |
| 996 else if (melem[e_ref].maxRepeat > 255) | |
| 997 *(USHORT *) (globs->pstruct + globs->pstructOffs++) = (USHORT) e_index; | |
| 998 else | |
| 999 globs->pstruct[globs->pstructOffs] = (UBYTE) e_index; | |
| 1000 | |
| 1001 globs->pstructOffs++; | |
| 1002 | |
| 1003 /* | |
| 1004 * Recalculate the struct offset for repeatable IEs. | |
| 1005 * New pointer types 'R' and 'F' are equivalent to 'V'. | |
| 1006 */ | |
| 1007 #ifdef DYNAMIC_ARRAYS | |
| 1008 offset = (e_index-1) * ((melem[e_ref].elemType EQ 'V' | |
| 1009 OR melem[e_ref].elemType EQ 'R' | |
| 1010 OR melem[e_ref].elemType EQ 'F' | |
| 1011 ) ? mvar[melem[e_ref].elemRef].cSize | |
| 1012 : mcomp[melem[e_ref].elemRef].cSize | |
| 1013 ); | |
| 1014 #else | |
| 1015 offset = (e_index-1) * ((melem[e_ref].elemType EQ 'V') | |
| 1016 ? mvar[melem[e_ref].elemRef].cSize | |
| 1017 : mcomp[melem[e_ref].elemRef].cSize | |
| 1018 ); | |
| 1019 #endif | |
| 1020 } | |
| 1021 } | |
| 1022 /* | |
| 1023 * If len_l > 0 read the l-Component out of the bistream. | |
| 1024 */ | |
| 1025 if (len_l) | |
| 1026 { | |
| 1027 if( len_l <= (ULONG) (globs->maxBitpos - globs->bitpos) ) | |
| 1028 { | |
| 1029 act_maxBP = globs->maxBitpos; | |
| 1030 l = cdc_decode_L (e_ref, len_l, globs); | |
| 1031 | |
| 1032 if (l EQ 0xFFFF) | |
| 1033 { | |
| 1034 /* | |
| 1035 * For ASN1-BER encoding we must look for the special | |
| 1036 * length 0x80 because it indicates the indefinite | |
| 1037 * length. This needs a special handling with later EOC tags. | |
| 1038 * | |
| 1039 */ | |
| 1040 globs->iei_ctx[globs->ccd_recurs_level].EOCPending = TRUE; | |
| 1041 globs->numEOCPending++; | |
| 1042 | |
| 1043 #ifdef DEBUG_CCD | |
| 1044 TRACE_CCD (globs, "implicit ASN1 length - EOC is pending"); | |
| 1045 #endif | |
| 1046 } | |
| 1047 else | |
| 1048 { | |
| 1049 /* | |
| 1050 * Calculate the max bitpos for this element | |
| 1051 */ | |
| 1052 tmp_maxBP = (USHORT) (globs->bitpos + (l*8)); | |
| 1053 if (globs->buflen < tmp_maxBP) | |
| 1054 { | |
| 1055 ccd_recordFault (globs, ERR_MSG_LEN, CONTINUE, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1056 } | |
| 1057 else if (globs->maxBitpos < tmp_maxBP) | |
| 1058 { | |
| 1059 ccd_recordFault (globs, ERR_ELEM_LEN, BREAK, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1060 } | |
| 1061 globs->maxBitpos = (USHORT)MINIMUM (globs->buflen, tmp_maxBP); | |
| 1062 tmp_maxBP = globs->maxBitpos; | |
| 1063 } | |
| 1064 } | |
| 1065 else | |
| 1066 { | |
| 1067 ccd_recordFault (globs, ERR_ELEM_LEN, BREAK, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1068 } | |
| 1069 } | |
| 1070 #ifdef DYNAMIC_ARRAYS | |
| 1071 /* | |
| 1072 * Check for pointer types; allocate memory if necessary. | |
| 1073 */ | |
| 1074 if ((melem[e_ref].elemType >= 'P' AND melem[e_ref].elemType <= 'R') OR | |
| 1075 (melem[e_ref].elemType >= 'D' AND melem[e_ref].elemType <= 'F')) | |
| 1076 { | |
| 1077 U32 cSize; | |
| 1078 U8 *addr; | |
| 1079 | |
| 1080 /* | |
| 1081 * Find size to allocate; | |
| 1082 * - Read from mcomp or mvar according to type | |
| 1083 */ | |
| 1084 cSize = (ULONG)((melem[e_ref].elemType EQ 'V' OR | |
| 1085 melem[e_ref].elemType EQ 'R') | |
| 1086 ? mvar[melem[e_ref].elemRef].cSize | |
| 1087 : mcomp[melem[e_ref].elemRef].cSize | |
| 1088 ); | |
| 1089 | |
| 1090 /* | |
| 1091 * Allocate additional memory | |
| 1092 */ | |
| 1093 addr = (U8 *)DP_ALLOC( cSize, globs->alloc_head, DP_NO_FRAME_GUESS); | |
| 1094 | |
| 1095 /* If no memory, log error and return immediately */ | |
| 1096 if (addr EQ NULL) { | |
| 1097 ccd_setError (globs, ERR_NO_MEM, | |
| 1098 BREAK, | |
| 1099 (USHORT) -1); | |
| 1100 return endOfComposition; | |
| 1101 } | |
| 1102 else | |
| 1103 memset (addr, 0, (size_t)(cSize)); | |
| 1104 | |
| 1105 /* | |
| 1106 * Memory allocated; | |
| 1107 * 1. Save old "globs->pstruct" variables | |
| 1108 * 2. Store pointer to freshly allocated memory area in structure | |
| 1109 * 3. Initialize pstruct to point to the freshly allocated memory area. | |
| 1110 * 4. Initialize pstructOffs to 0 to start decoding at offset 0 | |
| 1111 * in the new memory area. | |
| 1112 */ | |
| 1113 old_pstruct = globs->pstruct; | |
| 1114 *(U8 **)(globs->pstruct + globs->pstructOffs) = addr; | |
| 1115 globs->pstruct = addr; | |
| 1116 globs->pstructOffs = 0; | |
| 1117 } | |
| 1118 else | |
| 1119 { | |
| 1120 globs->pstructOffs += offset; | |
| 1121 } | |
| 1122 #else /* DYNAMIC_ARRAYS */ | |
| 1123 globs->pstructOffs += offset; | |
| 1124 #endif /* DYNAMIC_ARRAYS */ | |
| 1125 | |
| 1126 | |
| 1127 /* | |
| 1128 * Decode the value. Keep caution with BER encoding of ASN1 integers. | |
| 1129 * All other types can be decoded by a generic function. | |
| 1130 */ | |
| 1131 if (asn1 AND melem[e_ref].elemType EQ 'V' | |
| 1132 AND | |
| 1133 melem[e_ref].repType EQ ' ' | |
| 1134 AND | |
| 1135 l NEQ 0xFFFF | |
| 1136 ) | |
| 1137 { | |
| 1138 #ifdef DEBUG_CCD | |
| 1139 #ifdef CCD_SYMBOLS | |
| 1140 TRACE_CCD (globs, "BER decoding of ASN.1 integer %s", | |
| 1141 ccddata_get_alias((USHORT) e_ref, 1)); | |
| 1142 #else | |
| 1143 TRACE_CCD (globs, "BER decoding of ASN.1 integer; e_ref = %d", melem[e_ref].elemRef); | |
| 1144 #endif | |
| 1145 #endif | |
| 1146 | |
| 1147 if (mvar[melem[e_ref].elemRef].cType EQ 'X') | |
| 1148 bf_readBitChunk (l*8, globs); | |
| 1149 else | |
| 1150 bf_readBits (l*8, globs); | |
| 1151 } | |
| 1152 else | |
| 1153 { | |
| 1154 amount = 1; | |
| 1155 if (len_l) | |
| 1156 { | |
| 1157 if (l > 0) | |
| 1158 { | |
| 1159 cdc_decodeElemvalue (e_ref, &amount, globs); | |
| 1160 } | |
| 1161 else | |
| 1162 { | |
| 1163 amount = 0; | |
| 1164 } | |
| 1165 } | |
| 1166 else | |
| 1167 { | |
| 1168 if (melem[e_ref].codingType != CCDTYPE_GSM2_T) | |
| 1169 cdc_decodeElemvalue (e_ref, &amount, globs); | |
| 1170 } | |
| 1171 } | |
| 1172 #ifdef DYNAMIC_ARRAYS | |
| 1173 /* | |
| 1174 * Restore globs->pstruct for possible use below | |
| 1175 */ | |
| 1176 if (old_pstruct NEQ NULL) | |
| 1177 globs->pstruct = old_pstruct; | |
| 1178 #endif | |
| 1179 | |
| 1180 if (asn1 AND globs->numEOCPending AND !bf_endOfBitstream(globs)) | |
| 1181 { | |
| 1182 UBYTE T = bf_decodeByteNumber (8, globs); | |
| 1183 #ifdef DEBUG_CCD | |
| 1184 TRACE_CCD (globs, "looking for EOC decoding 8 bits T = (%x)", T); | |
| 1185 #endif | |
| 1186 | |
| 1187 if (T EQ 0) | |
| 1188 { | |
| 1189 #ifdef DEBUG_CCD | |
| 1190 TRACE_CCD (globs, "First EOC octet found"); | |
| 1191 #endif | |
| 1192 | |
| 1193 if (globs->iei_ctx[globs->ccd_recurs_level].EOCPending) | |
| 1194 { | |
| 1195 #ifdef DEBUG_CCD | |
| 1196 TRACE_CCD (globs, "End of ASN1 TLV"); | |
| 1197 #endif | |
| 1198 /* | |
| 1199 * Skip the second EOC octet. | |
| 1200 */ | |
| 1201 bf_incBitpos (8, globs); | |
| 1202 globs->iei_ctx[globs->ccd_recurs_level].EOCPending = FALSE; | |
| 1203 globs->numEOCPending--; | |
| 1204 } | |
| 1205 else | |
| 1206 { | |
| 1207 /* | |
| 1208 * The read first EOC octet belongs to an ASN1 TLV of a | |
| 1209 * higher recursion level. Let it be read and evalauted later | |
| 1210 * again for that IE. | |
| 1211 */ | |
| 1212 bf_setBitpos (globs->bitpos-8, globs); | |
| 1213 #ifdef DEBUG_CCD | |
| 1214 TRACE_CCD (globs, "End of higer level ASN1 TLV"); | |
| 1215 TRACE_CCD (globs, "Decrementing bitpos by 8 to %d", globs->bitpos); | |
| 1216 #endif | |
| 1217 endOfComposition = TRUE; | |
| 1218 } | |
| 1219 } | |
| 1220 else | |
| 1221 { | |
| 1222 if (globs->iei_ctx[globs->ccd_recurs_level].EOCPending) | |
| 1223 { | |
| 1224 /* | |
| 1225 * EOC element is pending but not found. | |
| 1226 */ | |
| 1227 ccd_setError (globs, ERR_EOC_TAG_MISSING, | |
| 1228 BREAK, | |
| 1229 (USHORT) T, | |
| 1230 globs->bitpos-8, | |
| 1231 (USHORT) -1); | |
| 1232 | |
| 1233 bf_setBitpos (globs->bitpos-8, globs); | |
| 1234 } | |
| 1235 else | |
| 1236 { | |
| 1237 /* | |
| 1238 * normal TAG leave it in the bitstream | |
| 1239 */ | |
| 1240 #ifdef DEBUG_CCD | |
| 1241 TRACE_CCD (globs, "Normal TAG - Decrementing bitpos by 8 to %d", globs->bitpos); | |
| 1242 #endif | |
| 1243 bf_setBitpos (globs->bitpos-8, globs); | |
| 1244 } | |
| 1245 } | |
| 1246 } | |
| 1247 | |
| 1248 if (len_l) | |
| 1249 { | |
| 1250 if (!asn1) | |
| 1251 { | |
| 1252 if (globs->bitpos > tmp_maxBP) | |
| 1253 { | |
| 1254 ccd_recordFault (globs, ERR_ELEM_LEN, CONTINUE, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1255 } | |
| 1256 else | |
| 1257 { | |
| 1258 /* | |
| 1259 * set the bitpos to the end of the LV or TLV element | |
| 1260 */ | |
| 1261 bf_setBitpos (tmp_maxBP, globs); | |
| 1262 } | |
| 1263 } | |
| 1264 /* | |
| 1265 * set the maxBitpos to the next octet boundary if the | |
| 1266 * last non-spare IE does not end at an octet boundary. | |
| 1267 * This is necessary for avoiding an early end of decoding. | |
| 1268 */ | |
| 1269 /* | |
| 1270 globs->maxBitpos = globs->buflen; | |
| 1271 */ | |
| 1272 globs->maxBitpos = act_maxBP; | |
| 1273 } | |
| 1274 | |
| 1275 return endOfComposition; | |
| 1276 } | |
| 1277 #endif /* !RUN_FLASH */ | |
| 1278 | |
| 1279 #ifndef RUN_FLASH | |
| 1280 /* Attention for RUN_...: static function */ | |
| 1281 /* | |
| 1282 +--------------------------------------------------------------------+ | |
| 1283 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 1284 | STATE : code ROUTINE : cdc_normal_LV_decode| | |
| 1285 +--------------------------------------------------------------------+ | |
| 1286 | |
| 1287 PURPOSE : If the parameter lenL is set, this function | |
| 1288 decodes the L-component. After this it decodes | |
| 1289 the element referenced by eRef from the | |
| 1290 bitstream into the C-Structure (globs->pstruct) | |
| 1291 at position globs->pstructOffs. | |
| 1292 If a repeat value is defined for this element | |
| 1293 this function decodes the V-component multiple and stores | |
| 1294 the values into an array. | |
| 1295 */ | |
| 1296 | |
| 1297 static BOOL cdc_normal_LV_decode (const ULONG e_ref, | |
| 1298 const ULONG len_l, | |
| 1299 T_CCD_Globs *globs) | |
| 1300 { | |
| 1301 ULONG l, repeat, amount, max_rep; | |
| 1302 USHORT act_maxBP, tmp_maxBP; | |
| 1303 BOOL is_variable; | |
| 1304 BOOL endOfComposition = FALSE; | |
| 1305 BOOL asn1; | |
| 1306 BOOL length_in_bits; | |
| 1307 #ifdef DYNAMIC_ARRAYS | |
| 1308 U8 *old_pstruct = NULL; | |
| 1309 #endif | |
| 1310 | |
| 1311 switch (melem[e_ref].codingType) | |
| 1312 { | |
| 1313 case CCDTYPE_GSM1_ASN: | |
| 1314 asn1 = TRUE; | |
| 1315 length_in_bits = FALSE; | |
| 1316 break; | |
| 1317 | |
| 1318 case CCDTYPE_GSM7_LV: | |
| 1319 asn1 = FALSE; | |
| 1320 length_in_bits = TRUE; | |
| 1321 break; | |
| 1322 | |
| 1323 default: | |
| 1324 asn1 = FALSE; | |
| 1325 length_in_bits = FALSE; | |
| 1326 break; | |
| 1327 } | |
| 1328 | |
| 1329 /* | |
| 1330 * if this element is repeatable, and the number of | |
| 1331 * repeats depends on another element, calculate the repeater | |
| 1332 */ | |
| 1333 if (melem[e_ref].repType NEQ ' ') | |
| 1334 { | |
| 1335 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs); | |
| 1336 } | |
| 1337 else | |
| 1338 { | |
| 1339 repeat = 1; | |
| 1340 is_variable = FALSE; | |
| 1341 } | |
| 1342 | |
| 1343 if (melem[e_ref].elemType NEQ 'S') | |
| 1344 { | |
| 1345 /* | |
| 1346 * Element is not a SPARE. | |
| 1347 * Setup the offset into the C-structure for this element | |
| 1348 */ | |
| 1349 if (melem[e_ref].optional) | |
| 1350 { | |
| 1351 globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE; | |
| 1352 } | |
| 1353 | |
| 1354 if (is_variable) | |
| 1355 { | |
| 1356 /* | |
| 1357 * for variable sized elements store the min-value | |
| 1358 * as counter into the C-Structure (c_xxx). | |
| 1359 */ | |
| 1360 if (max_rep > 65535) | |
| 1361 *(ULONG *) (globs->pstruct + globs->pstructOffs++) = repeat; | |
| 1362 else if (max_rep > 255) | |
| 1363 *(USHORT *) (globs->pstruct + globs->pstructOffs++) = (USHORT) repeat; | |
| 1364 else | |
| 1365 globs->pstruct[globs->pstructOffs] = (UBYTE) repeat; | |
| 1366 | |
| 1367 globs->pstructOffs++; | |
| 1368 } | |
| 1369 } | |
| 1370 | |
| 1371 /* | |
| 1372 * if len_l > 0 read the l-Component out of the bistream. | |
| 1373 */ | |
| 1374 if (len_l) | |
| 1375 { | |
| 1376 if( len_l <= (ULONG)(globs->maxBitpos - globs->bitpos) ) | |
| 1377 { | |
| 1378 act_maxBP = globs->maxBitpos; | |
| 1379 | |
| 1380 l = cdc_decode_L (e_ref, len_l, globs); | |
| 1381 | |
| 1382 if (l EQ 0xFFFF) | |
| 1383 { | |
| 1384 /* | |
| 1385 * for ASN1 element coding we must look for the special | |
| 1386 * length 0x80 because it indicates the indefinite | |
| 1387 * length. This needs a special handling with later EOC tags. | |
| 1388 */ | |
| 1389 globs->iei_ctx[globs->ccd_recurs_level].EOCPending = TRUE; | |
| 1390 | |
| 1391 globs->numEOCPending++; | |
| 1392 | |
| 1393 #ifdef DEBUG_CCD | |
| 1394 TRACE_CCD (globs, "implicit ASN1 length - EOC is pending"); | |
| 1395 #endif | |
| 1396 } | |
| 1397 else | |
| 1398 { | |
| 1399 /* | |
| 1400 * calculate the max bitpos for this element | |
| 1401 */ | |
| 1402 if (!length_in_bits) | |
| 1403 l *= 8; | |
| 1404 | |
| 1405 tmp_maxBP = (USHORT) (globs->bitpos + l); | |
| 1406 | |
| 1407 if (globs->buflen < tmp_maxBP) | |
| 1408 { | |
| 1409 ccd_recordFault (globs, ERR_MSG_LEN, CONTINUE, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1410 } | |
| 1411 else if (globs->maxBitpos < tmp_maxBP) | |
| 1412 { | |
| 1413 ccd_recordFault (globs, ERR_ELEM_LEN, BREAK, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1414 } | |
| 1415 globs->maxBitpos = (USHORT)MINIMUM (globs->buflen, tmp_maxBP); | |
| 1416 tmp_maxBP = globs->maxBitpos; | |
| 1417 | |
| 1418 /* | |
| 1419 * for bitfields which appear in TLV or LV elements | |
| 1420 * we must calculate the length (repeat) from the l values | |
| 1421 */ | |
| 1422 if (melem[e_ref].repType EQ 'b') | |
| 1423 repeat = l; | |
| 1424 } | |
| 1425 } | |
| 1426 else | |
| 1427 { | |
| 1428 ccd_recordFault (globs, ERR_ELEM_LEN, BREAK, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1429 } | |
| 1430 } | |
| 1431 #ifdef DYNAMIC_ARRAYS | |
| 1432 /* | |
| 1433 * MVJ: Dynamic array addition. | |
| 1434 * Check for pointer types; allocate memory if necessary. | |
| 1435 */ | |
| 1436 if ((melem[e_ref].elemType >= 'P' AND melem[e_ref].elemType <= 'R') OR | |
| 1437 (melem[e_ref].elemType >= 'D' AND melem[e_ref].elemType <= 'F')) { | |
| 1438 ULONG cSize, rep; | |
| 1439 U8 *addr; | |
| 1440 | |
| 1441 /* | |
| 1442 * Find size to allocate; | |
| 1443 * - Read from mcomp or mvar according to type | |
| 1444 * - Unbounded (0-terminated) ASN1-types are allocated with MAX repeat | |
| 1445 */ | |
| 1446 if (globs->iei_ctx[globs->ccd_recurs_level].EOCPending) { | |
| 1447 rep = (ULONG) melem[e_ref].maxRepeat; | |
| 1448 } else { | |
| 1449 rep = repeat; | |
| 1450 } | |
| 1451 cSize = (ULONG)((melem[e_ref].elemType EQ 'V' OR | |
| 1452 melem[e_ref].elemType EQ 'R') | |
| 1453 ? mvar[melem[e_ref].elemRef].cSize | |
| 1454 : mcomp[melem[e_ref].elemRef].cSize | |
| 1455 ) * rep; | |
| 1456 | |
| 1457 /* | |
| 1458 * Allocate additional memory | |
| 1459 */ | |
| 1460 addr = (U8 *)DP_ALLOC( cSize, globs->alloc_head, DP_NO_FRAME_GUESS); | |
| 1461 | |
| 1462 /* If no memory, log error and return immediately */ | |
| 1463 if (addr EQ NULL) { | |
| 1464 ccd_setError (globs, ERR_NO_MEM, | |
| 1465 BREAK, | |
| 1466 (USHORT) -1); | |
| 1467 return endOfComposition; | |
| 1468 } | |
| 1469 else | |
| 1470 memset (addr, 0, (size_t)cSize); | |
| 1471 | |
| 1472 /* | |
| 1473 * Memory allocated; | |
| 1474 * 1. Save old "globs->pstruct" variables | |
| 1475 * 2. Store pointer to freshly allocated memory area in structure | |
| 1476 * 3. Initialize pstruct to point to the freshly allocated memory area. | |
| 1477 * 4. Initialize pstructOffs to 0 to start decoding at offset 0 | |
| 1478 * in the new memory area. | |
| 1479 */ | |
| 1480 old_pstruct = globs->pstruct; | |
| 1481 *(U8 **)(globs->pstruct + globs->pstructOffs) = addr; | |
| 1482 globs->pstruct = addr; | |
| 1483 globs->pstructOffs = 0; | |
| 1484 } | |
| 1485 #endif | |
| 1486 | |
| 1487 /* | |
| 1488 * Decode the value. Keep caution with BER encoding of ASN1 integers. | |
| 1489 * All other types can be decoded by a generic function. | |
| 1490 */ | |
| 1491 if (asn1 AND melem[e_ref].elemType EQ 'V' | |
| 1492 AND | |
| 1493 melem[e_ref].repType EQ ' ' | |
| 1494 AND | |
| 1495 l NEQ 0xFFFF | |
| 1496 ) | |
| 1497 { | |
| 1498 #ifdef DEBUG_CCD | |
| 1499 #ifdef CCD_SYMBOLS | |
| 1500 TRACE_CCD (globs, "BER decoding of ASN.1 integer %s", | |
| 1501 ccddata_get_alias((USHORT) e_ref, 1)); | |
| 1502 #else | |
| 1503 TRACE_CCD (globs, "BER decoding of ASN.1 integer; e_ref = %d", melem[e_ref].elemRef); | |
| 1504 #endif | |
| 1505 #endif | |
| 1506 amount = l; | |
| 1507 if (mvar[melem[e_ref].elemRef].cType EQ 'X') | |
| 1508 bf_readBitChunk (l, globs); | |
| 1509 else | |
| 1510 bf_readBits (l, globs); | |
| 1511 } | |
| 1512 else | |
| 1513 { | |
| 1514 amount = repeat; | |
| 1515 if (len_l) | |
| 1516 { | |
| 1517 if (l > 0) | |
| 1518 { | |
| 1519 cdc_decodeElemvalue (e_ref, &amount, globs); | |
| 1520 } | |
| 1521 else | |
| 1522 { | |
| 1523 amount = 0; | |
| 1524 } | |
| 1525 } | |
| 1526 else | |
| 1527 { | |
| 1528 if (melem[e_ref].codingType != CCDTYPE_GSM2_T) | |
| 1529 cdc_decodeElemvalue (e_ref, &amount, globs); | |
| 1530 } | |
| 1531 } | |
| 1532 | |
| 1533 #ifdef DYNAMIC_ARRAYS | |
| 1534 /* | |
| 1535 * Restore globs->pstruct for possible use below | |
| 1536 */ | |
| 1537 if (old_pstruct NEQ NULL) { | |
| 1538 globs->pstruct = old_pstruct; | |
| 1539 } | |
| 1540 #endif | |
| 1541 | |
| 1542 if (amount NEQ repeat AND is_variable) | |
| 1543 { | |
| 1544 /* | |
| 1545 * If the number of decoded elements is not equal to the given | |
| 1546 * repeat value, because the bitstream or the IE ended, | |
| 1547 * store the new c_xxx value. | |
| 1548 */ | |
| 1549 globs->pstructOffs = melem[e_ref].structOffs; | |
| 1550 | |
| 1551 if (melem[e_ref].optional) | |
| 1552 globs->pstructOffs++; | |
| 1553 | |
| 1554 globs->pstruct[globs->pstructOffs] = (UBYTE) amount; | |
| 1555 | |
| 1556 if (melem[e_ref].repType NEQ 'i') | |
| 1557 { | |
| 1558 /* | |
| 1559 * if this element is not of the repeat style 'interval' | |
| 1560 * ([X..Y] where X and Y are constants) we have to generate | |
| 1561 * an ccd error because some outstanding repeats are missing. | |
| 1562 */ | |
| 1563 ccd_setError (globs, ERR_MAND_ELEM_MISS, | |
| 1564 CONTINUE, | |
| 1565 (USHORT) -1); | |
| 1566 } | |
| 1567 } | |
| 1568 | |
| 1569 if (asn1 AND globs->numEOCPending AND !bf_endOfBitstream(globs)) | |
| 1570 { | |
| 1571 UBYTE T = bf_decodeByteNumber (8, globs); | |
| 1572 #ifdef DEBUG_CCD | |
| 1573 TRACE_CCD (globs, "looking for EOC decoding 8 bits T = (%x)", T); | |
| 1574 #endif | |
| 1575 | |
| 1576 if (T EQ 0) | |
| 1577 { | |
| 1578 #ifdef DEBUG_CCD | |
| 1579 TRACE_CCD (globs, "First EOC octet found"); | |
| 1580 #endif | |
| 1581 | |
| 1582 if (globs->iei_ctx[globs->ccd_recurs_level].EOCPending) | |
| 1583 { | |
| 1584 #ifdef DEBUG_CCD | |
| 1585 TRACE_CCD (globs, "End of ASN1 TLV"); | |
| 1586 #endif | |
| 1587 /* | |
| 1588 * Skip the second EOC octet. | |
| 1589 */ | |
| 1590 bf_incBitpos (8, globs); | |
| 1591 globs->iei_ctx[globs->ccd_recurs_level].EOCPending = FALSE; | |
| 1592 globs->numEOCPending--; | |
| 1593 } | |
| 1594 else | |
| 1595 { | |
| 1596 /* | |
| 1597 * The read first EOC octet belongs to an ASN1 TLV of a | |
| 1598 * higher recursion level. Let it be read and evalauted later | |
| 1599 * again for that IE. | |
| 1600 */ | |
| 1601 bf_setBitpos (globs->bitpos-8, globs); | |
| 1602 #ifdef DEBUG_CCD | |
| 1603 TRACE_CCD (globs, "End of higer level ASN1 TLV"); | |
| 1604 TRACE_CCD (globs, "Decrementing bitpos by 8 to %d", globs->bitpos); | |
| 1605 #endif | |
| 1606 endOfComposition = TRUE; | |
| 1607 } | |
| 1608 } | |
| 1609 else | |
| 1610 { | |
| 1611 if (globs->iei_ctx[globs->ccd_recurs_level].EOCPending) | |
| 1612 { | |
| 1613 /* | |
| 1614 * EOC element is pending but not found. | |
| 1615 */ | |
| 1616 ccd_setError (globs, ERR_EOC_TAG_MISSING, | |
| 1617 BREAK, | |
| 1618 (USHORT) T, | |
| 1619 globs->bitpos-8, | |
| 1620 (USHORT) -1); | |
| 1621 | |
| 1622 bf_setBitpos (globs->bitpos-8, globs); | |
| 1623 } | |
| 1624 else | |
| 1625 { | |
| 1626 /* | |
| 1627 * normal TAG leave it in the bitstream | |
| 1628 */ | |
| 1629 #ifdef DEBUG_CCD | |
| 1630 TRACE_CCD (globs, "Normal TAG - Decrementing bitpos by 8 to %d", globs->bitpos); | |
| 1631 #endif | |
| 1632 bf_setBitpos (globs->bitpos-8, globs); | |
| 1633 } | |
| 1634 } | |
| 1635 } | |
| 1636 | |
| 1637 if (len_l) | |
| 1638 { | |
| 1639 if (!asn1) | |
| 1640 { | |
| 1641 if (globs->bitpos > tmp_maxBP) | |
| 1642 { | |
| 1643 ccd_recordFault (globs, ERR_ELEM_LEN, CONTINUE, (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 1644 } | |
| 1645 else | |
| 1646 { | |
| 1647 /* | |
| 1648 * set the bitpos to the end of the LV or TLV element | |
| 1649 */ | |
| 1650 bf_setBitpos (tmp_maxBP, globs); | |
| 1651 } | |
| 1652 } | |
| 1653 | |
| 1654 /* | |
| 1655 * set the maxBitpos to the next octet boundary if the | |
| 1656 * last non-spare IE does not end at an octet boundary. | |
| 1657 * This is necessary for avoiding an early end of decoding. | |
| 1658 */ | |
| 1659 /* | |
| 1660 globs->maxBitpos = globs->buflen; | |
| 1661 */ | |
| 1662 globs->maxBitpos = act_maxBP; | |
| 1663 } | |
| 1664 | |
| 1665 return endOfComposition; | |
| 1666 } | |
| 1667 #endif /* !RUN_FLASH */ | |
| 1668 | |
| 1669 #ifndef RUN_FLASH | |
| 1670 /* Attention for RUN_...: static function */ | |
| 1671 /* | |
| 1672 +--------------------------------------------------------------------+ | |
| 1673 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 1674 | STATE : code ROUTINE : cdc_skipElem | | |
| 1675 +--------------------------------------------------------------------+ | |
| 1676 | |
| 1677 PURPOSE : Skip an element referenced by eRef. This function | |
| 1678 perform a decoding of this element, but not into | |
| 1679 the target C-Structure. A dummy C-Structure is used | |
| 1680 instead. | |
| 1681 The complete decoding is necesary, because there is | |
| 1682 no information about the length of this element. | |
| 1683 B.t.w. for mandatory elements with fixed length, we can | |
| 1684 calculate the length, for optional elements or for | |
| 1685 variable sized arrays or bitbuffers it is impossible | |
| 1686 without decoding the entire element. | |
| 1687 */ | |
| 1688 | |
| 1689 static void cdc_skipElem (const ULONG e_ref, const ULONG len_l, T_CCD_Globs *globs) | |
| 1690 { | |
| 1691 UBYTE *ActStructAddr; | |
| 1692 U32 ActStructOffs; | |
| 1693 | |
| 1694 #ifdef DEBUG_CCD | |
| 1695 TRACE_CCD (globs, "skipping element %d", | |
| 1696 melem[e_ref].elemRef); | |
| 1697 #endif | |
| 1698 | |
| 1699 ActStructAddr = globs->pstruct; | |
| 1700 ActStructOffs = globs->pstructOffs; | |
| 1701 | |
| 1702 globs->pstruct = dummy; | |
| 1703 globs->pstructOffs = 0; | |
| 1704 | |
| 1705 cdc_tagged_LV_decode (e_ref, 1, len_l, globs); | |
| 1706 | |
| 1707 globs->pstruct = ActStructAddr; | |
| 1708 globs->pstructOffs = ActStructOffs; | |
| 1709 } | |
| 1710 #endif /* !RUN_FLASH */ | |
| 1711 | |
| 1712 #ifndef RUN_FLASH | |
| 1713 /* | |
| 1714 +--------------------------------------------------------------------+ | |
| 1715 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 1716 | STATE : code ROUTINE : cdc_tlv_decode | | |
| 1717 +--------------------------------------------------------------------+ | |
| 1718 | |
| 1719 PURPOSE : Decoding of the T-components of T TV and TLV typed | |
| 1720 information elements. The len determines the | |
| 1721 length of the T component. This function returns the | |
| 1722 index (reference) of the rigth element. If the | |
| 1723 iei is not known in this composition (msg or submsg) | |
| 1724 an error handling is done and NO_REF is returned. | |
| 1725 | |
| 1726 */ | |
| 1727 | |
| 1728 SHORT cdc_tlv_decode (const ULONG c_ref, | |
| 1729 const ULONG e_ref, | |
| 1730 const T_TLV_SORT *tlv_inf, | |
| 1731 T_CCD_Globs *globs) | |
| 1732 { | |
| 1733 ULONG repeat, max_rep; | |
| 1734 ULONG ie_amount, l, len_l, len_t, t; | |
| 1735 BOOL is_variable, nonTagged, limitSearch=FALSE; | |
| 1736 UBYTE CR=FALSE; | |
| 1737 SHORT IdxOffset = 0; | |
| 1738 int ieTableIdx; | |
| 1739 BOOL asn1, non_std_tag; | |
| 1740 SHORT ret; | |
| 1741 ULONG cix_ref, num_prolog_steps, prolog_step_ref; | |
| 1742 /* .../src/linux/include/asm/current.h defines a macro 'current' */ | |
| 1743 T_UNKNOWN_TAG *first, *currentTag; | |
| 1744 | |
| 1745 | |
| 1746 /* | |
| 1747 * Set the flag for the type of extension which is to expect | |
| 1748 * at the end of the message. | |
| 1749 */ | |
| 1750 globs->SeekTLVExt = TRUE; | |
| 1751 | |
| 1752 /* Set ref number for calcidx table. */ | |
| 1753 cix_ref = melem[e_ref].calcIdxRef; | |
| 1754 num_prolog_steps = calcidx[cix_ref].numPrologSteps; | |
| 1755 prolog_step_ref = calcidx[cix_ref].prologStepRef; | |
| 1756 | |
| 1757 /* | |
| 1758 * if this element is conditional, check the condition | |
| 1759 */ | |
| 1760 if (calcidx[cix_ref].numCondCalcs NEQ 0 | |
| 1761 AND ! ccd_conditionOK (e_ref, globs)) | |
| 1762 return 1; | |
| 1763 | |
| 1764 len_t = 8; | |
| 1765 switch (melem[e_ref].codingType) | |
| 1766 { | |
| 1767 case CCDTYPE_GSM1_ASN: | |
| 1768 asn1 = TRUE; | |
| 1769 non_std_tag = FALSE; | |
| 1770 len_l = 8; | |
| 1771 break; | |
| 1772 | |
| 1773 case CCDTYPE_GSM5_TV: | |
| 1774 case CCDTYPE_GSM5_TLV: | |
| 1775 non_std_tag = TRUE; | |
| 1776 asn1 = FALSE; | |
| 1777 len_l = 8; | |
| 1778 break; | |
| 1779 | |
| 1780 case CCDTYPE_GSM6_TLV: | |
| 1781 non_std_tag = FALSE; | |
| 1782 asn1 = FALSE; | |
| 1783 len_l = 16; | |
| 1784 break; | |
| 1785 | |
| 1786 case CCDTYPE_GSM7_LV: | |
| 1787 non_std_tag = FALSE; | |
| 1788 asn1 = FALSE; | |
| 1789 len_l = 7; | |
| 1790 break; | |
| 1791 | |
| 1792 default: | |
| 1793 asn1 = FALSE; | |
| 1794 non_std_tag = FALSE; | |
| 1795 len_l = 8; | |
| 1796 break; | |
| 1797 } | |
| 1798 | |
| 1799 /* | |
| 1800 * if this element have a defined Prolog | |
| 1801 * we have to process it before decoding the bitstream | |
| 1802 */ | |
| 1803 if (num_prolog_steps) | |
| 1804 { | |
| 1805 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); | |
| 1806 } | |
| 1807 | |
| 1808 if (tlv_inf->gotTag) | |
| 1809 { | |
| 1810 /* | |
| 1811 * tagged element | |
| 1812 */ | |
| 1813 len_t = 8; | |
| 1814 /* | |
| 1815 * initialize the iei_table for each new message | |
| 1816 */ | |
| 1817 if (globs->ccd_recurs_level NEQ globs->last_level) | |
| 1818 { | |
| 1819 cdc_init_table (c_ref, globs); | |
| 1820 globs->TagPending = FALSE; | |
| 1821 globs->SequenceError = FALSE; | |
| 1822 globs->last_level = globs->ccd_recurs_level; | |
| 1823 } | |
| 1824 | |
| 1825 /* | |
| 1826 * calculate the index into the ieTable for this element | |
| 1827 */ | |
| 1828 ieTableIdx = (int)(e_ref - globs->iei_ctx[globs->ccd_recurs_level].melemStart); | |
| 1829 | |
| 1830 if (globs->TagPending) | |
| 1831 { | |
| 1832 /* | |
| 1833 * if we previously read a t value and does not processed it | |
| 1834 * get this pending tag. | |
| 1835 */ | |
| 1836 t = (ULONG) globs->PendingTag; | |
| 1837 globs->TagPending = FALSE; | |
| 1838 } | |
| 1839 else | |
| 1840 { | |
| 1841 /* | |
| 1842 * read the information element identifier out of the bitstream. | |
| 1843 * If the first bit (MSBit) of the t-component is set, it is | |
| 1844 * a Tag of a TYPE1 or TYPE2 element. | |
| 1845 */ | |
| 1846 | |
| 1847 t = (ULONG) bf_decodeByteNumber (8, globs); | |
| 1848 | |
| 1849 | |
| 1850 | |
| 1851 if (!asn1 AND !non_std_tag AND (t & 0x80) EQ 0x80 AND (t & 0xA0) NEQ 0xA0) | |
| 1852 { | |
| 1853 ULONG Tag4 = t & 0xf0; | |
| 1854 /* | |
| 1855 * MSBit is set. We have to check if the Tag value can | |
| 1856 * be found as a 4 bit or 8 bit value in the IEI-table. | |
| 1857 */ | |
| 1858 if (cdc_search_table (ieTableIdx, Tag4, limitSearch, &nonTagged, globs) NEQ -127) | |
| 1859 { | |
| 1860 /* | |
| 1861 * Tag found as a 4 bit value. Decrement the readpointer | |
| 1862 * of the bitstream by 4, because we have read out 4 bits | |
| 1863 * to much. | |
| 1864 */ | |
| 1865 bf_setBitpos (globs->bitpos-4, globs); | |
| 1866 t = Tag4; | |
| 1867 len_t =4; | |
| 1868 #ifdef DEBUG_CCD | |
| 1869 TRACE_CCD (globs, "4 bit Tag decrementing bitpos by 4 to %d", globs->bitpos); | |
| 1870 #endif | |
| 1871 } | |
| 1872 } | |
| 1873 } | |
| 1874 | |
| 1875 #ifdef DEBUG_CCD | |
| 1876 TRACE_CCD (globs, "reading t = 0x%X", t); | |
| 1877 #endif | |
| 1878 | |
| 1879 if (melem[e_ref].codingType EQ CCDTYPE_GSM5_TLV) | |
| 1880 { | |
| 1881 limitSearch = TRUE; | |
| 1882 CR = (UBYTE) (((t & 0x80) EQ 0x80) ? TRUE : FALSE); | |
| 1883 t &= 0x7f; | |
| 1884 } | |
| 1885 | |
| 1886 | |
| 1887 if (asn1 AND t EQ 0x00) | |
| 1888 { | |
| 1889 /* | |
| 1890 * This is for ASN1 element coding the special | |
| 1891 * End Of Component Tag (EOC). The following length must be zero. | |
| 1892 */ | |
| 1893 bf_setBitpos (globs->bitpos-8, globs); | |
| 1894 | |
| 1895 #ifdef DEBUG_CCD | |
| 1896 TRACE_CCD (globs, "ASN1 End of Component found belongs to higher TLV"); | |
| 1897 TRACE_CCD (globs, "leaving this level and decrementing bitpos by 8 to %d", globs->bitpos); | |
| 1898 #endif | |
| 1899 | |
| 1900 return END_OF_COMPOSITION; /* skip the remaining elements in this level */ | |
| 1901 } /* asn1 and EOC */ | |
| 1902 else | |
| 1903 { | |
| 1904 if ((IdxOffset = (SHORT) cdc_search_table (ieTableIdx, t, limitSearch, &nonTagged, globs)) == -127) | |
| 1905 { | |
| 1906 /* | |
| 1907 * t (iei) not defined in this composition (msg or submsg) | |
| 1908 */ | |
| 1909 if (asn1) | |
| 1910 { | |
| 1911 if (melem[mcomp[c_ref].componentRef + mcomp[c_ref].numOfComponents -1].codingType == CCDTYPE_GSM5_V) | |
| 1912 { | |
| 1913 /* Restore the old bitposition (before the 'TAG') and return | |
| 1914 * IdxOffset to jump to last element of the composition. | |
| 1915 * The coding type of this elements is CCDTYPE_GSM5_V | |
| 1916 */ | |
| 1917 bf_setBitpos (globs->bitpos-8, globs); | |
| 1918 IdxOffset = (SHORT)(mcomp[c_ref].numOfComponents - ieTableIdx - 1); | |
| 1919 return (IdxOffset); | |
| 1920 } | |
| 1921 | |
| 1922 /* | |
| 1923 * for recursive ASN.1 structs it is possible that the foreign | |
| 1924 * tag belongs to a upper level composition of element. | |
| 1925 * | |
| 1926 * | |
| 1927 * Restore the old bitposition (before the TAG) and return | |
| 1928 * END_OF_COMPOSITION to leave this composition level | |
| 1929 */ | |
| 1930 bf_setBitpos (globs->bitpos-8, globs); | |
| 1931 #ifdef DEBUG_CCD | |
| 1932 TRACE_CCD (globs, "Unknown Tag. It may belong to upper ASN.1 comp -> dec. bitpos by 8 to %d", globs->bitpos); | |
| 1933 #endif | |
| 1934 | |
| 1935 return END_OF_COMPOSITION; /* skip the remaining elements in this level */ | |
| 1936 } | |
| 1937 else if (nonTagged) | |
| 1938 { | |
| 1939 U16 actBitpos; | |
| 1940 actBitpos = globs->bitpos-8; | |
| 1941 | |
| 1942 if (melem[mcomp[c_ref].componentRef + mcomp[c_ref].numOfComponents -1].codingType == CCDTYPE_GSM5_V && | |
| 1943 melem[e_ref].codingType EQ CCDTYPE_GSM5_TLV) | |
| 1944 { | |
| 1945 #if defined (CCD_TEST) | |
| 1946 currentTag = (T_UNKNOWN_TAG *) malloc(sizeof(T_UNKNOWN_TAG)); | |
| 1947 #else | |
| 1948 currentTag = (T_UNKNOWN_TAG *) D_ALLOC(sizeof(T_UNKNOWN_TAG)); | |
| 1949 #endif | |
| 1950 first = currentTag; | |
| 1951 currentTag->bitpos = globs->bitpos-8; | |
| 1952 currentTag->errCode = ERR_NO_MORE_ERROR; | |
| 1953 currentTag->next = NULL; | |
| 1954 | |
| 1955 /* unknown GSM Type TLV -> skip 'l' bytes */ | |
| 1956 /* at least 8 bits must remain for following expeceted tagged element */ | |
| 1957 while (globs->maxBitpos - 8 - globs->bitpos >= 8) | |
| 1958 { | |
| 1959 currentTag->bitpos = globs->bitpos-8; | |
| 1960 currentTag->tag = (UBYTE) t; | |
| 1961 | |
| 1962 /* | |
| 1963 * Expecting a CCDTYPE_GSM5_TLV type we get an unknown tag with MSB set. | |
| 1964 * Store bitpos and t for the application (SAT) for the handling of | |
| 1965 * comprehension required elements. | |
| 1966 */ | |
| 1967 | |
| 1968 if (CR) | |
| 1969 { // save (ERR_COMPREH_REQUIRED; globs->bitpos-len_t) | |
| 1970 currentTag->errCode = ERR_COMPREH_REQUIRED; | |
| 1971 } | |
| 1972 else | |
| 1973 { // save (ERR_IE_NOT_EXPECTED; globs->bitpos-len_t) | |
| 1974 currentTag->errCode = ERR_IE_NOT_EXPECTED; | |
| 1975 } | |
| 1976 | |
| 1977 l = (ULONG) bf_decodeByteNumber (8, globs); | |
| 1978 bf_incBitpos ((l << 3) , globs); | |
| 1979 | |
| 1980 t = (ULONG) bf_decodeByteNumber (8, globs); | |
| 1981 | |
| 1982 limitSearch = TRUE; | |
| 1983 CR = (UBYTE) (((t & 0x80) EQ 0x80) ? TRUE : FALSE); | |
| 1984 t &= 0x7f; | |
| 1985 | |
| 1986 if (cdc_search_table (ieTableIdx, t, limitSearch, &nonTagged, globs) != -127) | |
| 1987 { | |
| 1988 bf_setBitpos (globs->bitpos-8, globs); | |
| 1989 // set all ccd Errors | |
| 1990 do | |
| 1991 { | |
| 1992 currentTag = first; | |
| 1993 ccd_setError (globs, currentTag->errCode, | |
| 1994 CONTINUE, | |
| 1995 (USHORT) currentTag->tag, | |
| 1996 currentTag->bitpos, | |
| 1997 (USHORT) -1); | |
| 1998 first = currentTag->next; | |
| 1999 #if defined (CCD_TEST) | |
| 2000 free(currentTag); | |
| 2001 #else | |
| 2002 D_FREE(currentTag); | |
| 2003 #endif | |
| 2004 } | |
| 2005 while (first != NULL ); | |
| 2006 | |
| 2007 return 0; | |
| 2008 } | |
| 2009 else | |
| 2010 { | |
| 2011 #if defined (CCD_TEST) | |
| 2012 currentTag->next = (T_UNKNOWN_TAG *) malloc(sizeof(T_UNKNOWN_TAG)); | |
| 2013 #else | |
| 2014 currentTag->next = (T_UNKNOWN_TAG *) D_ALLOC(sizeof(T_UNKNOWN_TAG)); | |
| 2015 #endif | |
| 2016 currentTag = currentTag->next; | |
| 2017 currentTag->next = NULL; | |
| 2018 } | |
| 2019 } | |
| 2020 | |
| 2021 do | |
| 2022 { | |
| 2023 currentTag = first; | |
| 2024 first = currentTag->next; | |
| 2025 #if defined (CCD_TEST) | |
| 2026 free(currentTag); | |
| 2027 #else | |
| 2028 D_FREE(currentTag); | |
| 2029 #endif | |
| 2030 } | |
| 2031 while (first != NULL ); | |
| 2032 } | |
| 2033 | |
| 2034 /* | |
| 2035 * a non tagged element is possible in the message. If the tag | |
| 2036 * can not be found, the tag may be the beginning of the non tagged | |
| 2037 * element. E.g. rest octetts in sysinfo 4 | |
| 2038 * | |
| 2039 * Restore the old bitposition (before the TAG) and return 1 to | |
| 2040 * go to the next element. | |
| 2041 */ | |
| 2042 | |
| 2043 bf_setBitpos (actBitpos, globs); | |
| 2044 #ifdef DEBUG_CCD | |
| 2045 TRACE_CCD (globs, "Unknown Tag but mand. IE possible -> dec. bitpos by 8 to %d", globs->bitpos); | |
| 2046 #endif | |
| 2047 | |
| 2048 return 1; | |
| 2049 } | |
| 2050 | |
| 2051 | |
| 2052 /* | |
| 2053 * Otherwise look if it is a type 1,2 or 4 Element | |
| 2054 */ | |
| 2055 if ((t & 0x80) EQ 0x80) | |
| 2056 { | |
| 2057 /* MSBit set -> GSM Type 1 or Type2 -> skip 1 byte */ | |
| 2058 /* position already incremented by decoding the TAG value */ | |
| 2059 } | |
| 2060 /* Just another reason for getting IdxOffset equal to 0. */ | |
| 2061 else if (globs->ccd_recurs_level >= MAX_RECURSIONS_PER_MSG) | |
| 2062 { | |
| 2063 ccd_setError (globs, ERR_INTERNAL_ERROR, BREAK, (USHORT) -1); | |
| 2064 } | |
| 2065 else | |
| 2066 { | |
| 2067 /* | |
| 2068 * Expecting a CCDTYPE_GSM5_TLV type we get an unknown tag with MSB set. | |
| 2069 * Store bitpos and t for the application (SAT) for the handling of | |
| 2070 * comprehension required elements. | |
| 2071 */ | |
| 2072 if (CR) | |
| 2073 { | |
| 2074 ccd_setError (globs, ERR_COMPREH_REQUIRED, | |
| 2075 CONTINUE, | |
| 2076 (USHORT) t, | |
| 2077 (USHORT) globs->bitpos-len_t, | |
| 2078 (USHORT) -1); | |
| 2079 } | |
| 2080 /* | |
| 2081 * Expecting other types than CCDTYPE_GSM5_TLV we get an unknown tag with | |
| 2082 * comprehension required bits (5, 6, 7 and 8 of IEI according to GSM0407) | |
| 2083 * are set to zero. | |
| 2084 * Store bitpos and t for the application for the handling of comprehension | |
| 2085 * required elements. | |
| 2086 */ | |
| 2087 else if ((t & 0x70) EQ 0 AND | |
| 2088 melem[e_ref].codingType NEQ CCDTYPE_GSM5_TLV) | |
| 2089 { | |
| 2090 ccd_setError (globs, ERR_COMPREH_REQUIRED, | |
| 2091 CONTINUE, | |
| 2092 (USHORT) t, | |
| 2093 (USHORT) globs->bitpos-len_t, | |
| 2094 (USHORT) -1); | |
| 2095 } | |
| 2096 /* | |
| 2097 * We get an unknown tag and any sort of comprehension required flag is set. | |
| 2098 * Store bitpos and t for the application | |
| 2099 */ | |
| 2100 else | |
| 2101 { | |
| 2102 ccd_setError (globs, ERR_IE_NOT_EXPECTED, | |
| 2103 CONTINUE, | |
| 2104 (USHORT) t, | |
| 2105 (USHORT) globs->bitpos-len_t, | |
| 2106 (USHORT) -1); | |
| 2107 } | |
| 2108 | |
| 2109 /* MSBit cleared -> GSM Type TLV -> skip 'l' bytes */ | |
| 2110 if (globs->maxBitpos - globs->bitpos >= 8) | |
| 2111 { | |
| 2112 l = (ULONG) bf_decodeByteNumber (8, globs); | |
| 2113 bf_incBitpos ((l << 3) , globs); | |
| 2114 } | |
| 2115 else | |
| 2116 { | |
| 2117 ccd_recordFault (globs, | |
| 2118 ERR_ELEM_LEN, | |
| 2119 BREAK, | |
| 2120 (USHORT) e_ref, | |
| 2121 globs->pstruct + globs->pstructOffs); | |
| 2122 } | |
| 2123 } | |
| 2124 | |
| 2125 /* | |
| 2126 * return 0 -> that means try it again with this actual element | |
| 2127 * referenced by e_ref | |
| 2128 */ | |
| 2129 return 0; | |
| 2130 } /* tag not found */ | |
| 2131 else | |
| 2132 { | |
| 2133 T_IEI_TABLE *iei_tbl = &globs->iei_ctx[globs->ccd_recurs_level].iei_table[ieTableIdx]; | |
| 2134 /* | |
| 2135 * element definition for this iei found | |
| 2136 */ | |
| 2137 if (IdxOffset NEQ 0) | |
| 2138 { | |
| 2139 /* | |
| 2140 * found index differs from the actual index | |
| 2141 */ | |
| 2142 globs->TagPending = TRUE; | |
| 2143 globs->PendingTag = (UBYTE) t; | |
| 2144 | |
| 2145 if (!asn1 AND IdxOffset < 0) | |
| 2146 { | |
| 2147 /* | |
| 2148 * found an element in wrong sequence | |
| 2149 * (for ASN1 elements the sequence order is not relevant) | |
| 2150 */ | |
| 2151 ccd_setError (globs, ERR_IE_SEQUENCE, | |
| 2152 (UBYTE) ((asn1) ? BREAK : CONTINUE), | |
| 2153 (USHORT) t, | |
| 2154 (USHORT) globs->bitpos-len_t, | |
| 2155 (USHORT) -1); | |
| 2156 | |
| 2157 globs->SequenceError = TRUE; | |
| 2158 } | |
| 2159 if (globs->SequenceError) | |
| 2160 { | |
| 2161 globs->RefBeforeError = (USHORT) e_ref; | |
| 2162 } | |
| 2163 if (asn1) | |
| 2164 { | |
| 2165 globs->iei_ctx[globs->ccd_recurs_level].countSkipped += IdxOffset; | |
| 2166 } | |
| 2167 /* | |
| 2168 * skip to the found element | |
| 2169 */ | |
| 2170 return (IdxOffset); | |
| 2171 } | |
| 2172 else | |
| 2173 { | |
| 2174 globs->iei_ctx[globs->ccd_recurs_level].melemLast = (USHORT) e_ref; | |
| 2175 | |
| 2176 if (iei_tbl->act_amount == 0) | |
| 2177 { | |
| 2178 /* | |
| 2179 * first apearance of this iei | |
| 2180 * calculate the upper and lower boundaries and the | |
| 2181 * facility of multiple appearance of this tagged element | |
| 2182 * in the bitstream. | |
| 2183 */ | |
| 2184 | |
| 2185 /* | |
| 2186 * The element is repeatable. There are three kinds of | |
| 2187 * repeat definitions valid for standard elements: | |
| 2188 * [5] - The element is repeated 5 times. | |
| 2189 * [0..5] - The element is repeated 0 to 5 times. | |
| 2190 * [a..5] - The element is repeated "the value of a" times. | |
| 2191 * | |
| 2192 * For tagged elements the following processing is defined: | |
| 2193 * | |
| 2194 * [5] - The t-Component is decoded | |
| 2195 * (maybe the l-Component too (if defined one). | |
| 2196 * After this the V-component of the element | |
| 2197 * is decoded 5 times. | |
| 2198 * | |
| 2199 * [0..5] - The t- and maybe the l-Component are decoded. | |
| 2200 * After this one V-Component is decoded and it | |
| 2201 * is stored as an array entry into | |
| 2202 * the target C-Structure. In this case the | |
| 2203 * parameter ieIndex gives the index into | |
| 2204 * this array, where the element has to | |
| 2205 * be written into. | |
| 2206 * | |
| 2207 * [a..5] - The t- and maybe the l-Component are decoded. | |
| 2208 * After this one V-Component is decoded | |
| 2209 * "a" times and is stored into the C-Structure | |
| 2210 * as an array. | |
| 2211 * | |
| 2212 */ | |
| 2213 switch (melem[e_ref+IdxOffset].repType) | |
| 2214 { | |
| 2215 case 'i': | |
| 2216 /* | |
| 2217 * multiapearance of this element. The V-component is | |
| 2218 * repeated once | |
| 2219 */ | |
| 2220 is_variable = ccd_calculateRep (e_ref+IdxOffset, | |
| 2221 &repeat, | |
| 2222 &max_rep, | |
| 2223 globs); | |
| 2224 | |
| 2225 iei_tbl->max_amount = (UBYTE) max_rep; | |
| 2226 iei_tbl->multiple = TRUE; | |
| 2227 break; | |
| 2228 | |
| 2229 case 'v': | |
| 2230 case 'b': | |
| 2231 default: | |
| 2232 /* | |
| 2233 * if this element is repeatable, and the number of | |
| 2234 * repeats depends on another element, the valid amount | |
| 2235 * of this element is 1 and the V-component will be | |
| 2236 * repeated. | |
| 2237 */ | |
| 2238 iei_tbl->max_amount = 1; | |
| 2239 iei_tbl->multiple = FALSE; | |
| 2240 break; | |
| 2241 } | |
| 2242 iei_tbl->act_amount = 1; | |
| 2243 } | |
| 2244 | |
| 2245 if (iei_tbl->act_amount <= iei_tbl->max_amount) | |
| 2246 { | |
| 2247 /* | |
| 2248 * process only the max_amount appearances of each element. | |
| 2249 * All additional IEs are ignored. | |
| 2250 */ | |
| 2251 ie_amount = (ULONG)(iei_tbl->act_amount)++; | |
| 2252 } | |
| 2253 else | |
| 2254 { | |
| 2255 if (asn1) | |
| 2256 { | |
| 2257 /* For ASN1 elements the sequence order is not relevant. | |
| 2258 * It is possible that the tag belongs to an upper level | |
| 2259 * composition of elements. | |
| 2260 * Restore the old bitposition (before the TAG) and return | |
| 2261 * END_OF_COMPOSITION to leave this composition level | |
| 2262 */ | |
| 2263 bf_setBitpos (globs->bitpos-8, globs); | |
| 2264 #ifdef DEBUG_CCD | |
| 2265 TRACE_CCD (globs, "Tag may belong to upper ASN.1 comp -> dec. bitpos by 8 to %d", globs->bitpos); | |
| 2266 #endif | |
| 2267 | |
| 2268 return END_OF_COMPOSITION; /* skip the remaining elements in this level */ | |
| 2269 } | |
| 2270 else | |
| 2271 { | |
| 2272 ie_amount = 0; | |
| 2273 ccd_setError (globs, ERR_MAX_IE_EXCEED, | |
| 2274 CONTINUE, | |
| 2275 (USHORT) t, | |
| 2276 (USHORT) globs->bitpos-len_t, | |
| 2277 (USHORT) -1); | |
| 2278 } | |
| 2279 } | |
| 2280 | |
| 2281 /* | |
| 2282 * The t-component matches with the defined identifier for | |
| 2283 * the actual element definition (e_ref). | |
| 2284 */ | |
| 2285 | |
| 2286 if (globs->SequenceError) | |
| 2287 { | |
| 2288 globs->SequenceError = FALSE; | |
| 2289 | |
| 2290 if (asn1) | |
| 2291 { | |
| 2292 /* For ASN1 elements the sequence order is not relevant. | |
| 2293 * It is possible that the tag belongs to an upper level | |
| 2294 * composition of elements. | |
| 2295 * Restore the old bitposition (before the TAG) and return | |
| 2296 * END_OF_COMPOSITION to leave this composition level | |
| 2297 */ | |
| 2298 bf_setBitpos (globs->bitpos-8, globs); | |
| 2299 #ifdef DEBUG_CCD | |
| 2300 TRACE_CCD (globs, "Tag may belong to upper ASN.1 comp -> dec. bitpos by 8 to %d", globs->bitpos); | |
| 2301 #endif | |
| 2302 | |
| 2303 return END_OF_COMPOSITION; /* skip the remaining elements in this level */ | |
| 2304 } | |
| 2305 else | |
| 2306 { | |
| 2307 /* found an element in wrong sequence */ | |
| 2308 | |
| 2309 cdc_skipElem (e_ref, (tlv_inf->gotLen ? len_l:0), globs); | |
| 2310 return (SHORT)(globs->RefBeforeError - e_ref); | |
| 2311 } | |
| 2312 } | |
| 2313 | |
| 2314 /* | |
| 2315 * if this element is conditional, check the condition | |
| 2316 */ | |
| 2317 if (calcidx[cix_ref].numCondCalcs NEQ 0 | |
| 2318 AND ! ccd_conditionOK (e_ref, globs)) | |
| 2319 { | |
| 2320 /* | |
| 2321 * if the condition for this element is not valid | |
| 2322 * but this element appears in the message, generate | |
| 2323 * an error and skip the element | |
| 2324 */ | |
| 2325 ccd_setError (globs, ERR_IE_NOT_EXPECTED, | |
| 2326 CONTINUE, | |
| 2327 (USHORT) t, | |
| 2328 (USHORT) globs->bitpos-len_t, | |
| 2329 (USHORT) -1); | |
| 2330 | |
| 2331 cdc_skipElem (e_ref, (tlv_inf->gotLen ? len_l:0), globs); | |
| 2332 | |
| 2333 return 0; | |
| 2334 } | |
| 2335 | |
| 2336 /* | |
| 2337 * check for a valid index | |
| 2338 */ | |
| 2339 if (ie_amount EQ 0) | |
| 2340 { | |
| 2341 /* | |
| 2342 * The max number of repeats are reached | |
| 2343 * In this case we must skip this element. | |
| 2344 */ | |
| 2345 cdc_skipElem (e_ref, (tlv_inf->gotLen ? len_l:0), globs); | |
| 2346 | |
| 2347 return 0; | |
| 2348 } | |
| 2349 | |
| 2350 | |
| 2351 if (iei_tbl->multiple) | |
| 2352 { | |
| 2353 if (melem[e_ref].elemType NEQ 'S') | |
| 2354 { | |
| 2355 /* | |
| 2356 * Element is not a SPARE | |
| 2357 * Setup the offset into the C-structure for this element | |
| 2358 */ | |
| 2359 globs->pstructOffs = melem[e_ref].structOffs; | |
| 2360 } | |
| 2361 ret = cdc_tagged_LV_decode (e_ref, ie_amount, | |
| 2362 (tlv_inf->gotLen ? len_l:0), globs); | |
| 2363 } | |
| 2364 else | |
| 2365 { | |
| 2366 if (melem[e_ref].elemType NEQ 'S') | |
| 2367 { /* | |
| 2368 * Element is not a SPARE | |
| 2369 * Setup the offset into the C-structure for this element | |
| 2370 */ | |
| 2371 globs->pstructOffs = melem[e_ref].structOffs; | |
| 2372 } | |
| 2373 ret = cdc_normal_LV_decode (e_ref, | |
| 2374 (tlv_inf->gotLen ? len_l:0), globs); | |
| 2375 } | |
| 2376 globs->SeekTLVExt = TRUE; | |
| 2377 iei_tbl->exhausted = TRUE; | |
| 2378 | |
| 2379 if (ret) | |
| 2380 return END_OF_COMPOSITION; | |
| 2381 | |
| 2382 /* | |
| 2383 * if more then one IE of this type are allowed, a ret of 0 | |
| 2384 * indicates the calling function (ccd_decodeComposition()) | |
| 2385 * to leave the pointer to the actual element definition on | |
| 2386 * this element. If the value of ret is greater then 0 the | |
| 2387 * calling function will increment the pointer by the value | |
| 2388 * of ret. | |
| 2389 * cdc_T_decode() has found the expected element definition. | |
| 2390 * Go to the next definition or stay at this definition, | |
| 2391 * if the occurance of this element is more than one. | |
| 2392 */ | |
| 2393 if (iei_tbl->act_amount > iei_tbl->max_amount) | |
| 2394 { | |
| 2395 iei_tbl->act_amount = 0; | |
| 2396 } | |
| 2397 if (iei_tbl->max_amount > 1) | |
| 2398 { | |
| 2399 return (0); | |
| 2400 } | |
| 2401 else | |
| 2402 { | |
| 2403 if (globs->iei_ctx[globs->ccd_recurs_level].countSkipped) | |
| 2404 { | |
| 2405 ret = (-1) * (globs->iei_ctx[globs->ccd_recurs_level].countSkipped); | |
| 2406 (globs->iei_ctx[globs->ccd_recurs_level].countSkipped) = 0; | |
| 2407 return (ret); | |
| 2408 } | |
| 2409 else | |
| 2410 { | |
| 2411 return (1); | |
| 2412 } | |
| 2413 } | |
| 2414 } /* IdxOffset == 0 */ | |
| 2415 } /* tag found */ | |
| 2416 } /* no asn1, no EOC */ | |
| 2417 } /* got tag */ | |
| 2418 else | |
| 2419 { | |
| 2420 /* | |
| 2421 * element has no t-component, process the l- and V-components | |
| 2422 */ | |
| 2423 if (melem[e_ref].elemType NEQ 'S') | |
| 2424 { /* | |
| 2425 * Element is not a SPARE | |
| 2426 * Setup the offset into the C-structure for this element | |
| 2427 */ | |
| 2428 globs->pstructOffs = melem[e_ref].structOffs; | |
| 2429 } | |
| 2430 ret = cdc_normal_LV_decode (e_ref, len_l, globs) ? END_OF_COMPOSITION : 1; | |
| 2431 globs->SeekTLVExt = TRUE; | |
| 2432 return ret; | |
| 2433 } | |
| 2434 } | |
| 2435 #endif /* !RUN_FLASH */ | |
| 2436 | |
| 2437 #ifndef RUN_FLASH | |
| 2438 /* | |
| 2439 +--------------------------------------------------------------------+ | |
| 2440 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 2441 | STATE : code ROUTINE : cdc_tlv_encode | | |
| 2442 +--------------------------------------------------------------------+ | |
| 2443 | |
| 2444 PURPOSE : if T_len > 0 this function encodes the T-Component of | |
| 2445 this element. If L_len > 0 it encodes the number | |
| 2446 of bytes uses for this element. After all the function | |
| 2447 encodes the V-component referenced by eRef from the | |
| 2448 C-Structure (globs->pstruct) at position globs->pstructOffs | |
| 2449 into the bitstream. | |
| 2450 | |
| 2451 */ | |
| 2452 | |
| 2453 void cdc_tlv_encode (const ULONG e_ref, | |
| 2454 UBYTE lenT, | |
| 2455 UBYTE lenL, | |
| 2456 T_CCD_Globs *globs) | |
| 2457 { | |
| 2458 ULONG posL=0, t_repeat, v_repeat, repeat; | |
| 2459 ULONG cSize, startOffset=0; | |
| 2460 BOOL multAppear; | |
| 2461 U8 *old_pstruct = NULL; | |
| 2462 ULONG i; | |
| 2463 ULONG cix_ref, num_prolog_steps, prolog_step_ref; | |
| 2464 | |
| 2465 cix_ref = melem[e_ref].calcIdxRef; | |
| 2466 num_prolog_steps = calcidx[cix_ref].numPrologSteps; | |
| 2467 prolog_step_ref = calcidx[cix_ref].prologStepRef; | |
| 2468 | |
| 2469 /* | |
| 2470 * If this element is conditional, check the condition. | |
| 2471 */ | |
| 2472 if (calcidx[cix_ref].numCondCalcs NEQ 0 | |
| 2473 AND ! ccd_conditionOK (e_ref, globs)) | |
| 2474 return; | |
| 2475 | |
| 2476 /* | |
| 2477 * If this element have a defined Prolog, | |
| 2478 * we have to process it before decoding the bit stream. | |
| 2479 */ | |
| 2480 if (num_prolog_steps) | |
| 2481 { | |
| 2482 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); | |
| 2483 } | |
| 2484 | |
| 2485 if (melem[e_ref].elemType NEQ 'S') | |
| 2486 { | |
| 2487 /* | |
| 2488 * Element is not a SPARE. | |
| 2489 * Setup the offset into the C-structure for this element. | |
| 2490 * In case of pointer types, the pstructOffs must be | |
| 2491 * the offset into the memory area pointed to. CCDGEN must | |
| 2492 * ensure this holds true. | |
| 2493 */ | |
| 2494 globs->pstructOffs = melem[e_ref].structOffs; | |
| 2495 | |
| 2496 if ( ! cdc_isPresent(e_ref, globs) ) | |
| 2497 return; | |
| 2498 | |
| 2499 if (melem[e_ref].repType EQ 'v' OR melem[e_ref].repType EQ 'i') | |
| 2500 { | |
| 2501 /* | |
| 2502 * for variable sized elements read the amount | |
| 2503 * of repeats out of the C-Structure (c_xxx). | |
| 2504 * If the number of repeats given by the C-Structure | |
| 2505 * exceeds the allowed value (maxRepeat) CCD gives a warning! | |
| 2506 */ | |
| 2507 if (melem[e_ref].maxRepeat > 255) | |
| 2508 { | |
| 2509 ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++)); | |
| 2510 repeat = MINIMUM (count, (ULONG) melem[e_ref].maxRepeat); | |
| 2511 if (repeat < count) | |
| 2512 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, | |
| 2513 (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 2514 } | |
| 2515 else | |
| 2516 { | |
| 2517 repeat = (ULONG) MINIMUM (globs->pstruct[globs->pstructOffs], | |
| 2518 melem[e_ref].maxRepeat); | |
| 2519 if ( repeat < (ULONG) (globs->pstruct[globs->pstructOffs]) ) | |
| 2520 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, (USHORT) e_ref, | |
| 2521 globs->pstruct + globs->pstructOffs); | |
| 2522 } | |
| 2523 | |
| 2524 globs->pstructOffs++; | |
| 2525 | |
| 2526 multAppear = (melem[e_ref].repType EQ 'i'); | |
| 2527 } | |
| 2528 else | |
| 2529 { | |
| 2530 /* | |
| 2531 * Field of constant length: repType EQ 'c' | |
| 2532 * or bit-field allocated with | |
| 2533 * given maximum length: repType EQ 'b' (often cType='X') | |
| 2534 */ | |
| 2535 repeat = (ULONG)((melem[e_ref].repType EQ 'c' | |
| 2536 OR melem[e_ref].repType EQ 'b') | |
| 2537 ? melem[e_ref].maxRepeat | |
| 2538 : 1 ); | |
| 2539 multAppear = FALSE; | |
| 2540 } | |
| 2541 | |
| 2542 /* | |
| 2543 * Perform pointer dereference for pointer types. | |
| 2544 * Also, check optionality for these types. | |
| 2545 */ | |
| 2546 #ifdef DYNAMIC_ARRAYS | |
| 2547 if ((melem[e_ref].elemType >= 'P' AND melem[e_ref].elemType <= 'R') OR | |
| 2548 (melem[e_ref].elemType >= 'D' AND melem[e_ref].elemType <= 'F')) | |
| 2549 { | |
| 2550 U8 *deref_pstruct; | |
| 2551 | |
| 2552 /* Get pointer value */ | |
| 2553 deref_pstruct = *(U8 **)(globs->pstruct + globs->pstructOffs); | |
| 2554 | |
| 2555 /* | |
| 2556 * Strictly speaking the 'D' to 'F' types should not need this | |
| 2557 * check (should have returned after the optionality check above), | |
| 2558 * but it will catch stray NULL pointers (or uninitialized | |
| 2559 * valid flags) | |
| 2560 */ | |
| 2561 if (ccd_check_pointer(deref_pstruct) != ccdOK) | |
| 2562 { | |
| 2563 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref, | |
| 2564 &globs->pstruct[globs->pstructOffs]); | |
| 2565 return; | |
| 2566 } | |
| 2567 | |
| 2568 /* | |
| 2569 * Pointer not NULL; | |
| 2570 * 1. Save old globs->pstruct and assign pointer to globs->pstruct | |
| 2571 * as new base. | |
| 2572 * 2. Set pstructOffs to 0 (zero) as the next offset will start | |
| 2573 * in the new memory area. | |
| 2574 */ | |
| 2575 old_pstruct = globs->pstruct; | |
| 2576 globs->pstruct = deref_pstruct; | |
| 2577 globs->pstructOffs = 0; | |
| 2578 } | |
| 2579 #endif | |
| 2580 | |
| 2581 /* | |
| 2582 * 20010621 MVJ: Dynamic array addition. | |
| 2583 * Types 'R' and 'F' point to base types (just as type 'V') and | |
| 2584 * read sizes from the same table. | |
| 2585 */ | |
| 2586 cSize = (ULONG)((melem[e_ref].elemType EQ 'V' | |
| 2587 #ifdef DYNAMIC_ARRAYS | |
| 2588 OR melem[e_ref].elemType EQ 'R' | |
| 2589 OR melem[e_ref].elemType EQ 'F' | |
| 2590 #endif | |
| 2591 ) ? mvar[melem[e_ref].elemRef].cSize | |
| 2592 : mcomp[melem[e_ref].elemRef].cSize | |
| 2593 ); | |
| 2594 | |
| 2595 startOffset = globs->pstructOffs; | |
| 2596 } | |
| 2597 else | |
| 2598 { | |
| 2599 repeat = (ULONG)((melem[e_ref].repType EQ 'c') | |
| 2600 ? melem[e_ref].maxRepeat | |
| 2601 : 1); | |
| 2602 | |
| 2603 multAppear = FALSE; | |
| 2604 | |
| 2605 cSize = 0; | |
| 2606 } | |
| 2607 | |
| 2608 if (multAppear AND lenT) | |
| 2609 { | |
| 2610 /* | |
| 2611 * multiple appearance of the repeated element is coded as | |
| 2612 * TLV0 TLV1 TLV2 .... | |
| 2613 */ | |
| 2614 t_repeat = repeat; | |
| 2615 v_repeat = 1; | |
| 2616 } | |
| 2617 else | |
| 2618 { | |
| 2619 t_repeat = 1; | |
| 2620 v_repeat = repeat; | |
| 2621 } | |
| 2622 | |
| 2623 /* | |
| 2624 * single appearance of the repeated element is coded as | |
| 2625 * TLV0V1V2V3 .... | |
| 2626 */ | |
| 2627 | |
| 2628 for (i=0; i < t_repeat; i++) | |
| 2629 { | |
| 2630 if (lenT) | |
| 2631 { | |
| 2632 /* | |
| 2633 * encode the T-component | |
| 2634 */ | |
| 2635 bf_codeByteNumber (lenT, (UBYTE) melem[e_ref].ident, globs); | |
| 2636 #ifdef DEBUG_CCD | |
| 2637 TRACE_CCD (globs, "encoding %d bits T-value (%x)", lenT, melem[e_ref].ident); | |
| 2638 #endif | |
| 2639 } | |
| 2640 | |
| 2641 /* | |
| 2642 * if lenL > 0 remember the position of the L-component, because | |
| 2643 * we know it after encoding the entire element. for GSM5TLV elements | |
| 2644 * it could be necessary to use 2 bytes for the length information. | |
| 2645 */ | |
| 2646 if (lenL) | |
| 2647 { | |
| 2648 posL = (ULONG) globs->bitpos; | |
| 2649 bf_incBitpos (lenL, globs); | |
| 2650 #ifdef DEBUG_CCD | |
| 2651 TRACE_CCD (globs, "skipping %d bits for L-value at byte %d.%d", lenL, globs->bytepos, globs->byteoffs); | |
| 2652 #endif | |
| 2653 } | |
| 2654 | |
| 2655 if (cSize) | |
| 2656 { | |
| 2657 /* | |
| 2658 * calculate the offset if it is not a spare | |
| 2659 */ | |
| 2660 globs->pstructOffs = (ULONG)(startOffset + (i * cSize)); | |
| 2661 } | |
| 2662 | |
| 2663 /* | |
| 2664 * Encode the value. Keep caution with BER encoding of ASN1 integers. | |
| 2665 * All other types can be encoded by a generic function. | |
| 2666 */ | |
| 2667 if (melem[e_ref].codingType EQ CCDTYPE_GSM1_ASN | |
| 2668 AND | |
| 2669 melem[e_ref].elemType EQ 'V' | |
| 2670 AND melem[e_ref].repType EQ ' ' | |
| 2671 ) | |
| 2672 { | |
| 2673 #ifdef DEBUG_CCD | |
| 2674 #ifdef CCD_SYMBOLS | |
| 2675 TRACE_CCD (globs, "BER encoding of ASN.1 integer %s", | |
| 2676 ccddata_get_alias((USHORT) e_ref, 1)); | |
| 2677 #else | |
| 2678 TRACE_CCD (globs, "BER encoding of ASN.1 integer; e_ref= %d", melem[e_ref].elemRef); | |
| 2679 #endif | |
| 2680 #endif | |
| 2681 | |
| 2682 switch (mvar[melem[e_ref].elemRef].cType) | |
| 2683 { | |
| 2684 case 'B': bf_writeBits (8, globs); | |
| 2685 break; | |
| 2686 case 'S': | |
| 2687 { | |
| 2688 if (*(U16 *) (globs->pstruct+globs->pstructOffs) <= (U16)0xFF) | |
| 2689 bf_writeBits (8, globs); | |
| 2690 else | |
| 2691 bf_writeBits (16, globs); | |
| 2692 } | |
| 2693 break; | |
| 2694 case 'L': | |
| 2695 { | |
| 2696 U32 tmpVal= *(U32 *) (globs->pstruct+globs->pstructOffs); | |
| 2697 | |
| 2698 if ( tmpVal <= (U32)0xFF) | |
| 2699 bf_writeBits (8, globs); | |
| 2700 else if ( tmpVal <= (U32)0xFFFF) | |
| 2701 bf_writeBits (16, globs); | |
| 2702 else if ( tmpVal <= (U32)0xFFFFFF) | |
| 2703 bf_writeBits (24, globs); | |
| 2704 else | |
| 2705 bf_writeBits (32, globs); | |
| 2706 } | |
| 2707 break; | |
| 2708 case 'X': | |
| 2709 { | |
| 2710 U16 ValLen= *(U16 *) (globs->pstruct+globs->pstructOffs); | |
| 2711 | |
| 2712 if ( mvar[melem[e_ref].elemRef].bSize >= ValLen) | |
| 2713 bf_writeBitChunk (ValLen, globs); | |
| 2714 else | |
| 2715 { | |
| 2716 #ifdef DEBUG_CCD | |
| 2717 TRACE_CCD (globs, "value length (%d) exceeds defined bSize!", ValLen); | |
| 2718 #endif | |
| 2719 } | |
| 2720 | |
| 2721 } | |
| 2722 break; | |
| 2723 } | |
| 2724 } | |
| 2725 else | |
| 2726 { | |
| 2727 cdc_encodeElemvalue (e_ref, v_repeat, globs); | |
| 2728 } | |
| 2729 | |
| 2730 /* | |
| 2731 * calculate the bitlen if it is an TLV element and write the | |
| 2732 * L-value. | |
| 2733 */ | |
| 2734 | |
| 2735 if (lenL) | |
| 2736 { | |
| 2737 switch (melem[e_ref].codingType) | |
| 2738 { | |
| 2739 case CCDTYPE_GSM5_TLV: | |
| 2740 { | |
| 2741 USHORT L = (((USHORT)((globs->bitpos - posL)-lenL)+7) >> 3); | |
| 2742 | |
| 2743 | |
| 2744 #ifdef DEBUG_CCD | |
| 2745 TRACE_CCD (globs, "recoding the 8 bit L-value (%d)", L); | |
| 2746 #endif | |
| 2747 | |
| 2748 if (L > 127) | |
| 2749 { | |
| 2750 /* | |
| 2751 * if the length is > 127 we code the first byte to | |
| 2752 * 0x81, shift the whole stuff rightwise by 8 and | |
| 2753 * encode the length in the next byte (16 bits for L) | |
| 2754 */ | |
| 2755 bf_rShift8Bit ((USHORT) (posL+8), (USHORT) (L<<3), globs); | |
| 2756 bf_incBitpos (8, globs); | |
| 2757 bf_recodeByteNumber ((USHORT) posL, lenL, (UBYTE) 0x81, globs); | |
| 2758 bf_recodeByteNumber ((USHORT) (posL+8), lenL, (UBYTE) L, globs); | |
| 2759 /* | |
| 2760 * set the bitpos to a 8 bit aligned position | |
| 2761 * corresponding the L value | |
| 2762 */ | |
| 2763 bf_setBitpos (posL+(L*8)+16, globs); | |
| 2764 } | |
| 2765 else | |
| 2766 { | |
| 2767 bf_recodeByteNumber ((USHORT) posL, lenL, (UBYTE) L, globs); | |
| 2768 /* | |
| 2769 * set the bitpos to a 8 bit aligned position | |
| 2770 * corresponding the L value | |
| 2771 */ | |
| 2772 bf_setBitpos (posL+(L*8)+8, globs); | |
| 2773 } | |
| 2774 break; | |
| 2775 } | |
| 2776 | |
| 2777 case CCDTYPE_GSM6_TLV: | |
| 2778 { | |
| 2779 USHORT L = ((USHORT)(((globs->bitpos - posL)-lenL)+7) >> 3); | |
| 2780 | |
| 2781 #ifdef DEBUG_CCD | |
| 2782 TRACE_CCD (globs, "recoding the 16 bit L-value (%d)", L); | |
| 2783 #endif | |
| 2784 bf_recodeShortNumber ((USHORT)posL, lenL, L, globs); | |
| 2785 /* | |
| 2786 * set the bitpos to a 8 bit aligned position | |
| 2787 * corresponding the L value | |
| 2788 */ | |
| 2789 bf_setBitpos (posL+(L*8)+16, globs); | |
| 2790 break; | |
| 2791 } | |
| 2792 | |
| 2793 case CCDTYPE_GSM7_LV: | |
| 2794 { | |
| 2795 USHORT L = (USHORT) ((globs->bitpos - posL)-lenL); | |
| 2796 | |
| 2797 #ifdef DEBUG_CCD | |
| 2798 TRACE_CCD (globs, "recoding the 7 bit L-value (bitlength) (%d)", L); | |
| 2799 #endif | |
| 2800 bf_recodeShortNumber ((USHORT)posL, lenL, L, globs); | |
| 2801 | |
| 2802 bf_setBitpos (posL+L+7, globs); | |
| 2803 break; | |
| 2804 } | |
| 2805 | |
| 2806 default: | |
| 2807 { | |
| 2808 USHORT L = ((USHORT)(((globs->bitpos - posL)-lenL)+7) >> 3); | |
| 2809 | |
| 2810 #ifdef DEBUG_CCD | |
| 2811 TRACE_CCD (globs, "recoding the 8 bit L-value (%d)", L); | |
| 2812 #endif | |
| 2813 bf_recodeByteNumber ((USHORT)posL, lenL, (UBYTE) L, globs); | |
| 2814 /* | |
| 2815 * Set the bitpos to a 8 bit aligned position | |
| 2816 * corresponding the L value | |
| 2817 */ | |
| 2818 bf_setBitpos (posL+(L*8)+8, globs); | |
| 2819 break; | |
| 2820 } | |
| 2821 } | |
| 2822 } | |
| 2823 } | |
| 2824 | |
| 2825 /* | |
| 2826 * Restore globs->pstruct if overwritten by pointer dereference. | |
| 2827 */ | |
| 2828 if (old_pstruct) | |
| 2829 globs->pstruct = old_pstruct; | |
| 2830 } | |
| 2831 #endif /* !RUN_FLASH */ | |
| 2832 | |
| 2833 #ifndef RUN_FLASH | |
| 2834 /* | |
| 2835 +--------------------------------------------------------------------+ | |
| 2836 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 2837 | STATE : code ROUTINE : cdc_GSM_start | | |
| 2838 +--------------------------------------------------------------------+ | |
| 2839 | |
| 2840 PURPOSE : Initialize the GSM specific codec part for each msg. | |
| 2841 | |
| 2842 */ | |
| 2843 | |
| 2844 void cdc_GSM_start (T_CCD_Globs *globs) | |
| 2845 { | |
| 2846 globs->Swap1V_inProgress = FALSE; | |
| 2847 globs->last_level = 255; | |
| 2848 cdc_init_ctx_table (globs); | |
| 2849 } | |
| 2850 #endif /* !RUN_FLASH */ | |
| 2851 | |
| 2852 #ifndef RUN_INT_RAM | |
| 2853 /* | |
| 2854 +--------------------------------------------------------------------+ | |
| 2855 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 2856 | STATE : code ROUTINE : cdc_isPresent | | |
| 2857 +--------------------------------------------------------------------+ | |
| 2858 | |
| 2859 PURPOSE : For optional elements check the valid-flag in the C-struct. | |
| 2860 Spare elements in PER do not have a corresponding valid flag. | |
| 2861 In case of Dynamic Arrays: | |
| 2862 Postpone optional check for non-code transparent pointer | |
| 2863 types ('P', 'Q', 'R'). | |
| 2864 For these types, the optional flag is the pointer itself. | |
| 2865 These types cannot be checked yet, as the pointer may be | |
| 2866 preceeded by a counter octet, a union tag id octet etc. | |
| 2867 */ | |
| 2868 U16 cdc_isPresent (const ULONG e_ref, T_CCD_Globs *globs) | |
| 2869 { | |
| 2870 if (melem[e_ref].optional) | |
| 2871 { | |
| 2872 #ifdef DYNAMIC_ARRAYS | |
| 2873 if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R') | |
| 2874 { | |
| 2875 if(globs->pstruct[globs->pstructOffs++] == FALSE) | |
| 2876 return FALSE; | |
| 2877 #ifdef DEBUG_CCD | |
| 2878 else if (globs->pstruct [melem[e_ref].structOffs] != TRUE) | |
| 2879 { | |
| 2880 TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d", | |
| 2881 e_ref); | |
| 2882 } | |
| 2883 #endif | |
| 2884 } | |
| 2885 else | |
| 2886 { /*If elemType is P, Q or R - check the pointer value*/ | |
| 2887 if(*(void**) &globs->pstruct[globs->pstructOffs] == NULL) | |
| 2888 return FALSE; | |
| 2889 } | |
| 2890 #else | |
| 2891 if (globs->pstruct[globs->pstructOffs++] == FALSE) | |
| 2892 return FALSE; | |
| 2893 #ifdef DEBUG_CCD | |
| 2894 else if (globs->pstruct [melem[e_ref].structOffs] != TRUE) | |
| 2895 { | |
| 2896 TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d", | |
| 2897 e_ref); | |
| 2898 } | |
| 2899 #endif | |
| 2900 #endif | |
| 2901 } | |
| 2902 return TRUE; | |
| 2903 } | |
| 2904 #endif /* !RUN_INT_RAM */ | |
| 2905 | |
| 2906 #ifndef RUN_FLASH | |
| 2907 /* | |
| 2908 +--------------------------------------------------------------------+ | |
| 2909 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 2910 | STATE : code ROUTINE : is_pointer_type | | |
| 2911 +--------------------------------------------------------------------+ | |
| 2912 | |
| 2913 PURPOSE : Return TRUE for pointer elements. | |
| 2914 | |
| 2915 */ | |
| 2916 BOOL is_pointer_type (const ULONG e_ref) | |
| 2917 { | |
| 2918 return ((melem[e_ref].elemType >= 'P' AND melem[e_ref].elemType <= 'R') OR | |
| 2919 (melem[e_ref].elemType >= 'D' AND melem[e_ref].elemType <= 'F')); | |
| 2920 } | |
| 2921 #endif /* !RUN_FLASH */ | |
| 2922 | |
| 2923 #ifndef RUN_FLASH | |
| 2924 /* | |
| 2925 +--------------------------------------------------------------------+ | |
| 2926 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 2927 | STATE : code ROUTINE : is_variable_type | | |
| 2928 +--------------------------------------------------------------------+ | |
| 2929 | |
| 2930 PURPOSE : Return TRUE for elements with variable character. | |
| 2931 | |
| 2932 */ | |
| 2933 BOOL is_variable_type (const ULONG e_ref) | |
| 2934 { | |
| 2935 return ((melem[e_ref].elemType == 'F') || ( melem[e_ref].elemType == 'R') || | |
| 2936 (melem[e_ref].elemType == 'V')); | |
| 2937 } | |
| 2938 #endif /* !RUN_FLASH */ | |
| 2939 | |
| 2940 #ifndef RUN_INT_RAM | |
| 2941 /* | |
| 2942 +--------------------------------------------------------------------+ | |
| 2943 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 2944 | STATE : code ROUTINE : PER_CommonBegin | | |
| 2945 +--------------------------------------------------------------------+ | |
| 2946 | |
| 2947 PURPOSE : Common settings done by most of the encoding or decoding | |
| 2948 functions for UNALIGNED PER (UMTS). | |
| 2949 It handles position of pointer to the C-structure, | |
| 2950 valid flag for optional elements and length determinant | |
| 2951 for array of elements. | |
| 2952 */ | |
| 2953 SHORT PER_CommonBegin (const ULONG e_ref, ULONG *max_rep, T_CCD_Globs *globs) | |
| 2954 { | |
| 2955 /* | |
| 2956 * Set the offset in the C-structure on the value for this element | |
| 2957 */ | |
| 2958 globs->pstructOffs = melem[e_ref].structOffs; | |
| 2959 | |
| 2960 /* For optional elements we have already set the valid flag in the | |
| 2961 * C-structure while processing ASN1_SEQ. | |
| 2962 */ | |
| 2963 if ( ! cdc_isPresent(e_ref, globs) ) | |
| 2964 return (SHORT)ccdError; | |
| 2965 | |
| 2966 switch (melem[e_ref].repType) | |
| 2967 { | |
| 2968 case ' ': | |
| 2969 /* | |
| 2970 * Element is not an array. | |
| 2971 */ | |
| 2972 *max_rep = 1; | |
| 2973 break; | |
| 2974 case 'c': | |
| 2975 case 'C': | |
| 2976 /* | |
| 2977 * Read the size for an array of fixed length. | |
| 2978 */ | |
| 2979 *max_rep = (ULONG) melem[e_ref].maxRepeat; | |
| 2980 break; | |
| 2981 case 'j': | |
| 2982 case 'J': | |
| 2983 { | |
| 2984 /* | |
| 2985 * Read the size for an array of variable length. | |
| 2986 * Read the value of the last encoded element. It is the length | |
| 2987 * indicator. | |
| 2988 * Hint 1: globs->pstruct[melem[e_ref-1].structOffs is 0, since | |
| 2989 * fields of variable length are projected on a COMP made of an | |
| 2990 * ASN1_INTEGER for the lenght indicator and the field elements | |
| 2991 * (sequences, integers, octets or bits). | |
| 2992 * Hint 2: The current version of UMTS does not use length | |
| 2993 * indicators larger than 64K. Hence the use of USHORT for repeat. | |
| 2994 */ | |
| 2995 switch (mvar[melem[e_ref-1].elemRef].cType) | |
| 2996 { | |
| 2997 case 'B': *max_rep = (ULONG) globs->pstruct[melem[e_ref-1].structOffs]; | |
| 2998 break; | |
| 2999 case 'S': *max_rep = (ULONG) *(USHORT *) (globs->pstruct+melem[e_ref-1].structOffs); | |
| 3000 break; | |
| 3001 default: *max_rep = 0; | |
| 3002 break; | |
| 3003 } | |
| 3004 break; | |
| 3005 } | |
| 3006 default: | |
| 3007 ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, | |
| 3008 globs->pstruct + globs->pstructOffs); | |
| 3009 break; | |
| 3010 } | |
| 3011 | |
| 3012 /* | |
| 3013 * There is nothing to be encoded. | |
| 3014 */ | |
| 3015 if (*max_rep EQ 0) | |
| 3016 { | |
| 3017 return (SHORT)ccdError; | |
| 3018 } | |
| 3019 /* | |
| 3020 * Check the validity of the lenght information. | |
| 3021 */ | |
| 3022 else if (melem[e_ref].maxRepeat AND *max_rep > melem[e_ref].maxRepeat) | |
| 3023 { | |
| 3024 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, (USHORT) e_ref, | |
| 3025 globs->pstruct + globs->pstructOffs); | |
| 3026 } | |
| 3027 | |
| 3028 return (SHORT)ccdOK; | |
| 3029 } | |
| 3030 #endif /* !RUN_INT_RAM */ | |
| 3031 | |
| 3032 | |
| 3033 #ifdef DYNAMIC_ARRAYS | |
| 3034 #ifndef RUN_INT_RAM | |
| 3035 /* | |
| 3036 +--------------------------------------------------------------------+ | |
| 3037 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 3038 | STATE : code ROUTINE : PER_allocmem | | |
| 3039 +--------------------------------------------------------------------+ | |
| 3040 | |
| 3041 PURPOSE : Allocate memory for pointer types (dynamic array addition) | |
| 3042 Returns address of freshly allocated memory | |
| 3043 or ccdError in case no memory is available. | |
| 3044 */ | |
| 3045 U8 *PER_allocmem(const ULONG e_ref, ULONG repeat, T_CCD_Globs *globs) | |
| 3046 { | |
| 3047 /* | |
| 3048 * Check for pointer types; allocate memory if necessary. | |
| 3049 */ | |
| 3050 if ( is_pointer_type(e_ref) ) { | |
| 3051 ULONG cSize; | |
| 3052 U8 *addr; | |
| 3053 | |
| 3054 /* | |
| 3055 * Find size to allocate. | |
| 3056 * Read from mcomp or mvar according to type. | |
| 3057 */ | |
| 3058 cSize = (ULONG)((melem[e_ref].elemType EQ 'V' OR | |
| 3059 melem[e_ref].elemType EQ 'R' | |
| 3060 OR melem[e_ref].elemType EQ 'F') | |
| 3061 ? mvar[melem[e_ref].elemRef].cSize | |
| 3062 : mcomp[melem[e_ref].elemRef].cSize | |
| 3063 ); | |
| 3064 | |
| 3065 #ifdef DEBUG_CCD | |
| 3066 TRACE_CCD (globs, "PER_allocmem(): alloc%5d x%5d bytes (type '%c'); " | |
| 3067 "elem%5d ('%s')", | |
| 3068 repeat, cSize, melem[e_ref].elemType, e_ref, | |
| 3069 #ifdef CCD_SYMBOLS | |
| 3070 mcomp[melem[e_ref].elemRef].name | |
| 3071 #else | |
| 3072 "" | |
| 3073 #endif | |
| 3074 ); | |
| 3075 #endif | |
| 3076 /* | |
| 3077 * Allocate additional memory - append to existing mem chain | |
| 3078 */ | |
| 3079 | |
| 3080 cSize *= repeat; | |
| 3081 addr = (U8 *)DP_ALLOC( cSize, globs->alloc_head, DP_NO_FRAME_GUESS); | |
| 3082 | |
| 3083 /* If no memory, log error and return immediately */ | |
| 3084 if (addr EQ NULL) { | |
| 3085 ccd_setError (globs, ERR_NO_MEM, | |
| 3086 BREAK, | |
| 3087 (USHORT) -1); | |
| 3088 return (U8 *)ccdError; | |
| 3089 } | |
| 3090 else | |
| 3091 memset (addr, 0, (size_t)cSize); | |
| 3092 return addr; | |
| 3093 } | |
| 3094 return (U8 *)ccdError; | |
| 3095 } | |
| 3096 #endif /* !RUN_INT_RAM */ | |
| 3097 | |
| 3098 #ifndef RUN_INT_RAM | |
| 3099 /* | |
| 3100 +--------------------------------------------------------------------+ | |
| 3101 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 3102 | STATE : code ROUTINE : PER_allocmem_and_update| | |
| 3103 +--------------------------------------------------------------------+ | |
| 3104 | |
| 3105 PURPOSE : Allocate memory for pointer types (dynamic array addition) | |
| 3106 Updates global variables after allocation | |
| 3107 (globs->pstruct and globs->pstructOffs). | |
| 3108 Assumes that these global variables are saved by the | |
| 3109 calling function. | |
| 3110 Returns ccdOK or ccdError in case no memory is available. | |
| 3111 */ | |
| 3112 USHORT PER_allocmem_and_update(const ULONG e_ref, ULONG repeat, T_CCD_Globs *globs) | |
| 3113 { | |
| 3114 U8 *addr; | |
| 3115 | |
| 3116 /* Allocate memory */ | |
| 3117 addr = PER_allocmem(e_ref, repeat, globs); | |
| 3118 | |
| 3119 /* No memory ? */ | |
| 3120 if ( addr != (U8 *)ccdError ) { | |
| 3121 /* | |
| 3122 * Memory allocated; | |
| 3123 * 1. Store pointer to freshly allocated memory area in structure | |
| 3124 * 2. Initialize pstruct to point to the freshly allocated memory area. | |
| 3125 * 3. Initialize pstructOffs to 0 to start decoding at offset 0 | |
| 3126 * in the new memory area. | |
| 3127 * Assumes that globs->pstruct is saved in the calling function. | |
| 3128 */ | |
| 3129 *(U8 **)(globs->pstruct + globs->pstructOffs) = addr; | |
| 3130 globs->pstruct = addr; | |
| 3131 globs->pstructOffs = 0; | |
| 3132 return ccdOK; | |
| 3133 } else { | |
| 3134 /* No memory - Return error */ | |
| 3135 return ccdError; | |
| 3136 } | |
| 3137 } | |
| 3138 #endif /* !RUN_INT_RAM */ | |
| 3139 #endif | |
| 3140 | |
| 3141 #ifndef RUN_INT_RAM | |
| 3142 /* | |
| 3143 +--------------------------------------------------------------------+ | |
| 3144 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 3145 | STATE : code ROUTINE : Read_NormallySmallNonNegativeWholeNr| | |
| 3146 +--------------------------------------------------------------------+ | |
| 3147 | |
| 3148 PURPOSE : Read a normally small non-negative whole number as defined | |
| 3149 by ASN.1 PER. Function is used to read elements such as: | |
| 3150 a) bit-map field of SEQUENCE extensions, | |
| 3151 b) index of CHOICE extension or | |
| 3152 c) extension value of extensible INTEGER or ENUMERATED. | |
| 3153 */ | |
| 3154 U32 Read_NormallySmallNonNegativeWholeNr (T_CCD_Globs *globs) | |
| 3155 { | |
| 3156 U32 value_length=0; | |
| 3157 | |
| 3158 /* Read the first bit. If set to 0 it means the value is encoded | |
| 3159 * in the following five bits. Else read a normally small ...nr. | |
| 3160 */ | |
| 3161 if (bf_readBit (globs) EQ 0) | |
| 3162 { | |
| 3163 return ((U32) bf_getBits (6, globs)); | |
| 3164 } | |
| 3165 else | |
| 3166 { | |
| 3167 /* | |
| 3168 * Do not handle the theoretical case that value length | |
| 3169 * needs more than 63 bits. | |
| 3170 */ | |
| 3171 bf_incBitpos (1, globs); | |
| 3172 | |
| 3173 /* | |
| 3174 * Read the value length first. | |
| 3175 * Then use the length to read the value. | |
| 3176 */ | |
| 3177 value_length = (U32) bf_getBits (6, globs); | |
| 3178 return ((U32) bf_getBits (value_length, globs)); | |
| 3179 } | |
| 3180 } | |
| 3181 #endif /* !RUN_INT_RAM */ | |
| 3182 | |
| 3183 #ifndef RUN_INT_RAM | |
| 3184 /* | |
| 3185 +--------------------------------------------------------------------+ | |
| 3186 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 3187 | STATE : code ROUTINE : Write_NormallySmallNonNegativeWholeNr| | |
| 3188 +--------------------------------------------------------------------+ | |
| 3189 | |
| 3190 PURPOSE : Write a normally small non-negative whole number as defined | |
| 3191 by ASN.1 PER. Function is used to encode elements such as: | |
| 3192 a) bit-map field of SEQUENCE extensions, | |
| 3193 b) index of CHOICE extension or | |
| 3194 c) extension value of extensible INTEGER or ENUMERATED. | |
| 3195 */ | |
| 3196 void Write_NormallySmallNonNegativeWholeNr (U32 Value, T_CCD_Globs *globs) | |
| 3197 { | |
| 3198 /* For small numbers write 0 in the first bit. | |
| 3199 * Then encode that number in the succeeding five bits. | |
| 3200 */ | |
| 3201 if (Value < 64) | |
| 3202 { | |
| 3203 bf_writeBit (0, globs); | |
| 3204 bf_writeVal (Value, 6, globs); | |
| 3205 } | |
| 3206 /* | |
| 3207 * Encode the number under the assumption that its length is | |
| 3208 * given by less than 63 bits. Hence encode also the length as a | |
| 3209 * normally small... | |
| 3210 */ | |
| 3211 else | |
| 3212 { | |
| 3213 /* Set flag bits: | |
| 3214 * 1 means "length determinant encoded before the value itself" | |
| 3215 * 0 means "length determinant encoded only in five bits" | |
| 3216 */ | |
| 3217 bf_writeVal (2, 2, globs); | |
| 3218 bf_writeVal (bitSize[Value], 5, globs); | |
| 3219 | |
| 3220 /* Encode the number itself */ | |
| 3221 bf_writeVal (Value, bitSize[Value], globs); | |
| 3222 } | |
| 3223 | |
| 3224 return; | |
| 3225 } | |
| 3226 #endif /* !RUN_INT_RAM */ | |
| 3227 | |
| 3228 #ifndef RUN_INT_RAM | |
| 3229 /* | |
| 3230 +--------------------------------------------------------------------+ | |
| 3231 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 3232 | STATE : code ROUTINE : Read_OpenTpye_Length | | |
| 3233 +--------------------------------------------------------------------+ | |
| 3234 | |
| 3235 PURPOSE : Read length of an ASN.1 open type. | |
| 3236 Open types are normally found in encoding of | |
| 3237 parametrized information objects and extension types. | |
| 3238 */ | |
| 3239 U32 Read_OpenTpye_Length (T_CCD_Globs *globs) | |
| 3240 { | |
| 3241 U32 Value; | |
| 3242 | |
| 3243 /* | |
| 3244 * Flag bit is 0 for "Value < 128" which means | |
| 3245 * "encoding fits in the current octet" | |
| 3246 */ | |
| 3247 if (bf_readBit (globs) EQ 0) | |
| 3248 { | |
| 3249 Value = bf_getBits (7, globs); | |
| 3250 } | |
| 3251 /* | |
| 3252 * Flag bits are 10 for 128 "< Value < 16K". | |
| 3253 * 1 means "encoding does not fit in the current octet". | |
| 3254 * 0 means "encoding needs only one further octet". | |
| 3255 */ | |
| 3256 else if (bf_readBit (globs) EQ 0) | |
| 3257 { | |
| 3258 Value = bf_getBits (14, globs); | |
| 3259 } | |
| 3260 /* Currently no support for bigger values is required. */ | |
| 3261 else | |
| 3262 { | |
| 3263 /* force error detection */ | |
| 3264 Value = 0; | |
| 3265 } | |
| 3266 | |
| 3267 return Value; | |
| 3268 } | |
| 3269 #endif /* !RUN_INT_RAM */ | |
| 3270 | |
| 3271 #ifndef RUN_INT_RAM | |
| 3272 /* | |
| 3273 +--------------------------------------------------------------------+ | |
| 3274 | PROJECT : CCD (6144) MODULE : CDC_COM | | |
| 3275 | STATE : code ROUTINE : Write_OpenTpye_Length | | |
| 3276 +--------------------------------------------------------------------+ | |
| 3277 | |
| 3278 PURPOSE : Write length of an ASN.1 open type. | |
| 3279 Open types are normally found in encoding of | |
| 3280 parametrized information objects and extension types. | |
| 3281 */ | |
| 3282 void Write_OpenTpye_Length (U32 Value, T_CCD_Globs *globs) | |
| 3283 { | |
| 3284 | |
| 3285 if (Value < 128) | |
| 3286 { | |
| 3287 bf_writeVal (Value, 8, globs); | |
| 3288 } | |
| 3289 else if (Value < 0x8000) | |
| 3290 { | |
| 3291 /* Set flag bits: | |
| 3292 * 1 means "encoding does not fit in the current octet" | |
| 3293 * 0 means "encoding needs only one further octet" | |
| 3294 */ | |
| 3295 bf_writeVal (2, 2, globs); | |
| 3296 bf_writeVal (Value, 14, globs); | |
| 3297 } | |
| 3298 /* Currently no support for bigger values is required. */ | |
| 3299 else | |
| 3300 {} | |
| 3301 | |
| 3302 return; | |
| 3303 } | |
| 3304 #endif /* !RUN_INT_RAM */ |
