comparison gsm-fw/ccd/asn1_seq.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 : asn1_seq.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 : Definition of encoding and decoding functions for ASN1_SEQUENCE
18 | elements
19 +-----------------------------------------------------------------------------
20 */
21
22 #define ASN1_SEQ_C
23
24 /*
25 * Standard definitions like UCHAR, ERROR etc.
26 */
27 #include "typedefs.h"
28 #include "header.h"
29
30 /*
31 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
32 * look at ccdapi.h
33 */
34 #undef USE_DRIVER
35 #include "ccdapi.h"
36
37 /*
38 * Types and functions for bit access and manipulation
39 */
40 #include "ccd_globs.h"
41 #include "bitfun.h"
42
43 /*
44 * Prototypes and constants in the common part of ccd
45 */
46 #include "ccd.h"
47 #include "ccd_codingtypes.h"
48
49 /*
50 * Declaration of coder/decoder tables
51 */
52 #include "ccdtable.h"
53 #include "ccddata.h"
54
55 EXTERN T_FUNC_POINTER codec[MAX_CODEC_ID+1][2];
56
57 #ifndef RUN_INT_RAM
58 /*
59 +--------------------------------------------------------------------+
60 | PROJECT : CCD (6144) MODULE : asn1_seq |
61 | STATE : code ROUTINE : Read_SEQ_BitMap |
62 +--------------------------------------------------------------------+
63
64 PURPOSE : Decode the bit-map preamble for OPTIONAL elements
65 or those with DEFAULT value.
66 */
67 void Read_SEQ_BitMap (const ULONG first_elem, const ULONG last_elem, T_CCD_Globs *globs)
68 {
69 ULONG elem = first_elem;
70 while (elem < last_elem)
71 {
72 if (melem[elem].optional)
73 {
74 /*
75 * For optional elements read the corresponding bit in the preamble
76 * and set the valid flag in the C-Structure to it.
77 */
78 if (melem[elem].elemType < 'P' OR melem[elem].elemType > 'R')
79 {
80 globs->pstruct[melem[elem].structOffs] = (UBYTE) bf_readBit(globs);
81 }
82 else
83 {
84 if(bf_readBit(globs)) /*elemType P, Q or R*/
85 {
86 /*If present set the pointer to -1 (0xFFFF) - anything else than NULL, because the
87 element is present*/
88 *(void**) &globs->pstruct[melem[elem].structOffs] = (void *) 0xFFFF;
89 }
90 else /*Not present set the pointer to NULL*/
91 *(void**) &globs->pstruct[melem[elem].structOffs] = NULL;
92
93 }
94 }
95 /*
96 * For optional elements read the corresponding bit in the preamble
97 * and set the valid flag in the C-structure to it.
98 */
99 else if (melem[elem].codingType EQ CCDTYPE_ASN1_INTEGER)
100 {
101 /*
102 * Check if this variable has a default value.
103 * As long as the DEFAULT values are given with ranges it is right to
104 * look for isDefault in the second entry in mval.cdg.
105 * There is no valid flag for elements with default value. But we use
106 * the first byte of this element within the C-structure for giving a
107 * signal to this function. The only simple type which has DEFAULT is INTEGER.
108 */
109 if (mval[mvar[melem[elem].elemRef].valueDefs+1].isDefault EQ 2)
110 {
111 globs->pstruct[melem[elem].structOffs] = (UBYTE) bf_readBit(globs);
112 }
113 }
114 elem++;
115 }
116 }
117 #endif /* !RUN_INT_RAM */
118
119 #ifndef RUN_INT_RAM
120 /*
121 +--------------------------------------------------------------------+
122 | PROJECT : CCD (6144) MODULE : CDC_GSM |
123 | STATE : code ROUTINE : cdc_asn1_seq_decode |
124 +--------------------------------------------------------------------+
125
126 PURPOSE : Decoding of the SEQUENCE and SEQUENCE OF type for UMTS
127 The element can be a field of fixed or variable length.
128 It can contain OPTIONAL elements or integer elements with
129 a DEFAULT value.
130 A special case is when the element is a so called msg_data.
131 According to CCDDATA a message is made of a msg_type and
132 a msg_data part. If the msg_data has a coding type of
133 ASN1_SEQUENCE this function is called.
134 In this case CCD needs to pass over the msg_type by
135 incrementing globs->pstruct. A msg_data sequence can not
136 be optional. Nor it can be an array of msg_data.
137 If the sequence is not a msg_data this function is called
138 as an equivalent to ccd_decodeComposition. Hence the
139 increment on globs->ccd_recurs_level. A non-msg_data
140 sequence can be optional or an array.
141 */
142 SHORT cdc_asn1_seq_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
143 {
144 ULONG repeat=1, max_rep=1;
145 ULONG cSize, first_elem, last_elem, elem;
146 UBYTE *old_pstruct;
147 #ifdef DEBUG_CCD
148 static S8 trace_nesting_level = -1;
149 #endif
150
151 #ifdef DEBUG_CCD
152 #ifndef CCD_SYMBOLS
153 TRACE_CCD (globs, "cdc_asn1_seq_decode()");
154 #else
155 TRACE_CCD (globs, "cdc_asn1_seq_decode() %s", mcomp[melem[e_ref].elemRef].name);
156 #endif
157 #endif
158
159 /*
160 * This function is called as an equivalent to ccd_decodeComposition.
161 * Hence the increment on globs->ccd_recurs_level.
162 */
163 globs->ccd_recurs_level ++;
164
165 /*
166 * Set pstrcutOffs and max_rep.
167 * Check the valid flag in case of optional elements.
168 */
169 if (PER_CommonBegin (e_ref, &max_rep, globs) NEQ ccdOK)
170 {
171 globs->ccd_recurs_level --;
172 return 1;
173 }
174
175 /*
176 * Prepare for decoding of the same sequence type up to max_rep times.
177 * Set the upper and lower bound of elemRef for processing of each repeatition.
178 * Read the C-size to go ahead in the C-structure after each repeatition.
179 */
180 switch (melem[e_ref].elemType)
181 {
182 case 'C':
183 case 'D':
184 case 'E':
185 case 'P':
186 case 'Q':
187 elem = (ULONG) melem[e_ref].elemRef;
188 first_elem = (ULONG) mcomp[elem].componentRef;
189 last_elem = first_elem + mcomp[elem].numOfComponents;
190 cSize = (ULONG) mcomp[elem].cSize;
191 break;
192 case 'F':
193 case 'R':
194 first_elem = e_ref;
195 last_elem = e_ref + 1;
196 cSize = (ULONG) mvar[e_ref].cSize;
197 break;
198 default:
199 ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK,
200 (USHORT) (globs->bitpos), (USHORT) -1);
201 return 1;
202
203 };
204 /*
205 * Store the current value of the C-structure pointer.
206 * After decoding the SEQUENCE component we will set the pointer
207 * to this stored value. Then we will use pstructOffs for pointing
208 * to the next element.
209 */
210 old_pstruct = globs->pstruct;
211 #ifdef DYNAMIC_ARRAYS
212 /*
213 * Allocate memory for this whole composition, if elemType is
214 * one of the pointer types.
215 */
216 if ( is_pointer_type(e_ref))
217 {
218 if ( PER_allocmem_and_update(e_ref, max_rep, globs) NEQ ccdOK )
219 {
220 /* No memory - Return. Error already set in function call above. */
221 globs->ccd_recurs_level --;
222 return 1;
223 }
224
225 }
226 #endif
227 globs->pstruct += globs->pstructOffs;
228
229 /*
230 * Decode all elements of the field.
231 */
232 while (repeat <= max_rep)
233 {
234 Read_SEQ_BitMap (first_elem, last_elem, globs);
235 elem = first_elem;
236
237 /*
238 * Decode all elements of the array
239 */
240 #ifdef DEBUG_CCD
241 trace_nesting_level++;
242 #endif
243 while (elem < last_elem)
244 {
245 #ifdef ERR_TRC_STK_CCD
246 /*
247 * Save the value for tracing in error case.
248 */
249 globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem;
250 #endif /* ERR_TRC_STK_CCD */
251
252 #ifdef DEBUG_CCD
253 #ifndef CCD_SYMBOLS
254 TRACE_CCD (globs, "decoding level %d element %d", trace_nesting_level, elem - first_elem);
255 #else
256 TRACE_CCD (globs, "decoding level %d element %d '%s'",trace_nesting_level, elem - first_elem, ccddata_get_alias((USHORT) elem, 1));
257 #endif
258 #endif
259
260 /*
261 * Use the jump-table for selecting the decode function.
262 * Possible types are 0, ASN1_INTEGER, BITSTRING, ASN1_CHOICE and
263 * ASN1_SEQUENCE. In case of 0 function cdc_STD_decode will be called.
264 */
265 (void) codec[melem[elem].codingType][DECODE_FUN]
266 (c_ref, elem, globs);
267 elem ++;
268 }
269 #ifdef DEBUG_CCD
270 trace_nesting_level--;
271 #endif
272
273 /*
274 * Set the pointer of the C-structure on the next element.
275 */
276 globs->pstruct += cSize;
277
278 repeat ++;
279 }
280
281 /*
282 * Prepare for decoding the next element.
283 */
284 globs->pstruct = old_pstruct;
285 globs->ccd_recurs_level--;
286
287 return 1;
288 }
289 #endif /* !RUN_INT_RAM */
290
291 #ifndef RUN_INT_RAM
292 /*
293 +--------------------------------------------------------------------+
294 | PROJECT : CCD (6144) MODULE : asn1_seq |
295 | STATE : code ROUTINE : Write_SEQ_BitMap |
296 +--------------------------------------------------------------------+
297
298 PURPOSE : Encode the bit-map preamble for OPTIONAL elements
299 or those with DEFAULT value.
300 */
301 void Write_SEQ_BitMap (const ULONG first_elem, const ULONG last_elem, T_CCD_Globs *globs)
302 {
303 ULONG elem = first_elem;
304 while (elem < last_elem)
305 {
306 if (melem[elem].optional)
307 {
308 /*
309 * For optional elements read the valid flag in the C-Structure
310 * and overwrite the corresponding bit in the preamble.
311 */
312
313 #if defined _TOOLS_
314 int patch;
315 U16 stelem;
316 stelem = globs->error_stack[globs->ccd_recurs_level];
317 globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem;
318 patch = ccd_patch (globs, 1);
319 globs->error_stack[globs->ccd_recurs_level] = stelem;
320 if (patch)
321 {
322 bf_writeBit(1, globs);
323 elem++;
324 continue;
325 }
326 #endif /* _TOOLS_ */
327
328 #ifdef DYNAMIC_ARRAYS
329 if ( is_pointer_type(elem) )
330 {
331 BOOL present;
332 /*
333 * Check for NULL pointer (== notPresent/not valid) for this element.
334 */
335 present = (*(U8 **)(globs->pstruct + melem[elem].structOffs) NEQ NULL);
336 /*
337 * Double check for 'D' to 'F' types. Both NULL pointer and
338 * valid flag. (Strictly not necessary, but may catch uninitialized
339 * flags/pointers).
340 */
341 if (present AND (melem[elem].elemType >= 'D' AND
342 melem[elem].elemType <= 'F'))
343 {
344 present = (BOOL)globs->pstruct[melem[elem].structOffs];
345 }
346 bf_writeBit(present, globs);
347 }
348 else
349 #endif
350 bf_writeBit((BOOL)globs->pstruct[melem[elem].structOffs], globs);
351 }
352 else if (melem[elem].codingType EQ CCDTYPE_ASN1_INTEGER)
353 {
354 /*
355 * Check if this variable has a default value.
356 * As long as the DEFAULT values are given with ranges it is right to
357 * look for isDefault in the second entry in mval.cdg.
358 * There is no valid flag for elements with default value. So we need
359 * to read the value from C-structure and compare it with the DEFAULT
360 * value given in the mval table. The only simple type which has
361 * DEFAULT is INTEGER.
362 */
363 if (mval[mvar[melem[elem].elemRef].valueDefs+1].isDefault EQ 2)
364 {
365 U32 value=0;
366 UBYTE *p;
367 /*
368 * setup the read pointer to the element in the C-structure
369 */
370 #ifdef DYNAMIC_ARRAYS
371 if ( is_pointer_type(elem) )
372 {
373 /*
374 * NULL pointers should be caught as part of the optionality
375 * check in PER_CommonBegin()
376 */
377 p = *(U8 **)(globs->pstruct + globs->pstructOffs);
378 if (ccd_check_pointer(p) != ccdOK)
379 {
380 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) elem,
381 &globs->pstruct[globs->pstructOffs]);
382 return;
383 }
384 }
385 else
386 #endif
387 p = globs->pstruct + melem[elem].structOffs;
388 /*
389 * Default values are all positive and small values (< 64K)
390 * in the current version of umts. The cases 'L' and 'C' are added
391 * to be ready for a future change where we need also a check of
392 * possible errors through type casting.
393 */
394 switch (mvar[melem[elem].elemRef].cType)
395 {
396 case 'B':
397 value = (U32)*(UBYTE *) p;
398 break;
399 case 'C':
400 value = (U32)(S32)*(S8 *) p;
401 break;
402 case 'S':
403 value = (U32)(*(USHORT *) p);
404 break;
405 case 'T':
406 value = (U32)(S32)*(S16 *) p;
407 break;
408 case 'L':
409 value = (U32)*(S32 *) p;
410 break;
411 case 'M':
412 value = (U32)*(U32 *) p;
413 break;
414 default:
415 ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) -1);
416 break;
417 }
418 /*
419 * Compare the value to be encoded with the default value.
420 * Write the presence flag into the preamble.
421 */
422 if (value EQ (U32)mval[mvar[melem[elem].elemRef].valueDefs+1].startValue)
423 {
424 bf_writeBit(0, globs);
425 }
426 else
427 {
428 bf_writeBit(1, globs);
429 }
430 }
431 }
432 elem++;
433 }
434 }
435 #endif /* !RUN_INT_RAM */
436
437 #ifndef RUN_INT_RAM
438 /*
439 +--------------------------------------------------------------------+
440 | PROJECT : CCD (6144) MODULE : CDC_GSM |
441 | STATE : code ROUTINE : cdc_asn1_seq_encode |
442 +--------------------------------------------------------------------+
443
444 PURPOSE : Decoding of the SEQUENCE and SEQUENCE OF type for UMTS
445 The element can be a field of fixed or variable length.
446 It can contain OPTIONAL elements or integer elements with
447 a DEFAULT value.
448 A special case is when the element is a so called msg_data.
449 According to CCDDATA a message is made of a msg_type and
450 a msg_data part. If the msg_data has a coding type of
451 ASN1_SEQUENCE this function is called.
452 In this case CCD needs to pass over the msg_type by
453 incrementing globs->pstruct. A msg_data sequence can not
454 be optional. Nor it can be an array of msg_data.
455 If the sequence is not a msg_data this function is called
456 as an equivalent to ccd_encodeComposition. Hence the
457 increment on globs->ccd_recurs_level. A non-msg_data
458 sequence can be optional or an array.
459 */
460 SHORT cdc_asn1_seq_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
461 {
462 ULONG repeat=1, max_rep=1;
463 ULONG cSize, first_elem, last_elem, elem;
464 UBYTE *old_pstruct;
465 #ifdef DEBUG_CCD
466 static S8 trace_nesting_level = -1;
467 #endif
468
469 #ifdef DEBUG_CCD
470 #ifndef CCD_SYMBOLS
471 TRACE_CCD (globs, "cdc_asn1_seq_encode()");
472 #else
473 TRACE_CCD (globs, "cdc_asn1_seq_encode() %s", mcomp[melem[e_ref].elemRef].name);
474 #endif
475 #endif
476
477 /*
478 * This function is called as an equivalent to ccd_encodeComposition.
479 * Hence the increment on globs->ccd_recurs_level.
480 */
481 globs->ccd_recurs_level ++;
482
483 /*
484 * Set pstrcutOffs and max_rep.
485 * Check the valid flag in case of optional elements.
486 */
487 if (PER_CommonBegin (e_ref, &max_rep, globs) NEQ ccdOK)
488 {
489 globs->ccd_recurs_level --;
490 return 1;
491 }
492
493 /*
494 * Prepare for encoding of the same sequence type up to max_rep times.
495 * Set the upper and lower bound of elemRef for processing of each repeatition.
496 * Read the C-size to go ahead in the C-structure after each repeatition.
497 */
498 switch (melem[e_ref].elemType)
499 {
500 case 'C':
501 case 'D':
502 case 'E':
503 case 'P':
504 case 'Q':
505 {
506 elem = (ULONG) melem[e_ref].elemRef;
507 first_elem = (ULONG) mcomp[elem].componentRef;
508 last_elem = first_elem + mcomp[elem].numOfComponents;
509 cSize = (ULONG) mcomp[elem].cSize;
510 break;
511 }
512 case 'F':
513 case 'R':
514 {
515 first_elem = e_ref;
516 last_elem = e_ref + 1;
517 cSize = (ULONG) mvar[e_ref].cSize;
518 break;
519 }
520 default:
521 ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK,
522 (USHORT) (globs->bitpos), (USHORT) -1);
523 return 1;
524
525 }
526 /*
527 * Store the current value of the C-structure pointer.
528 * After encoding the SEQUENCE component we will set the pointer
529 * to this stored value. Then we will use pstructOffs for pointing
530 * to the next element.
531 */
532 old_pstruct = globs->pstruct;
533 globs->pstruct += globs->pstructOffs;
534
535 #ifdef DYNAMIC_ARRAYS
536 if ( is_pointer_type(e_ref) ) {
537 if (ccd_check_pointer(*(U8 **)globs->pstruct) == ccdOK)
538 {
539 globs->pstruct = *(U8 **) globs->pstruct;
540 }
541 else
542 {
543 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref,
544 &globs->pstruct[globs->pstructOffs]);
545 return 1;
546 }
547 }
548 #endif
549
550
551 /*
552 * Encode all elements of the field.
553 */
554 while (repeat <= max_rep)
555 {
556 Write_SEQ_BitMap (first_elem, last_elem, globs);
557
558 /*
559 * Encode all elements
560 */
561 #ifdef DEBUG_CCD
562 trace_nesting_level++;
563 #endif
564
565 elem = first_elem;
566 while (elem < last_elem)
567 {
568 #ifdef ERR_TRC_STK_CCD
569 /*
570 * Save the value for tracing in error case.
571 */
572 globs->error_stack[globs->ccd_recurs_level] = (USHORT) elem;
573 #endif /* ERR_TRC_STK_CCD */
574 #ifdef DEBUG_CCD
575 #ifndef CCD_SYMBOLS
576 TRACE_CCD (globs, "encoding level %d element %d", trace_nesting_level, elem - first_elem);
577 #else
578 TRACE_CCD (globs, "encoding level %d element %d '%s'", trace_nesting_level, elem - first_elem ,ccddata_get_alias((USHORT) elem, 1));
579 #endif
580 #endif
581
582 #if defined _TOOLS_
583 if (!ccd_patch (globs, 0))
584 #endif /* _TOOLS_ */
585 /*
586 * Use the jump-table for selecting the code function.
587 * Possible types are 0, ASN1_INTEGER, BITSTRING, ASN1_CHOICE and
588 * ASN1_SEQUENCE. In case of 0 function cdc_STD_encode will be called.
589 */
590 (void) codec[melem[elem].codingType][ENCODE_FUN]
591 (c_ref, elem, globs);
592 /*
593 * Set the elemRef to the next element.
594 */
595 elem ++;
596 }
597 #ifdef DEBUG_CCD
598 trace_nesting_level--;
599 #endif
600 /*
601 * Set the pointer of the C-structure on the next element.
602 */
603 globs->pstruct += cSize;
604
605 repeat ++;
606 }
607
608 /*
609 * Prepare for encoding the next element.
610 */
611 globs->pstruct = old_pstruct;
612 globs->ccd_recurs_level--;
613 return 1;
614 }
615 #endif /* !RUN_INT_RAM */