comparison gsm-fw/ccd/cdc_com.c @ 648:970d6199f2c5

gsm-fw/ccd/*.[ch]: initial import from the LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 04 Sep 2014 05:48:57 +0000
parents
children
comparison
equal deleted inserted replaced
647:a60b375014e3 648:970d6199f2c5
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 */