FreeCalypso > hg > freecalypso-sw
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 */ |