comparison gsm-fw/ccd/csn1_sx.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 : CCD
4 | Modul : csn1_sx.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 CSN1_S0 elements
18 +-----------------------------------------------------------------------------
19 */
20 /*
21 * standard definitions like GLOBAL, UCHAR, ERROR etc.
22 */
23 #include "typedefs.h"
24 #include "header.h"
25
26
27 /*
28 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
29 * look at ccdapi.h
30 */
31 #undef USE_DRIVER
32 #include "ccdapi.h"
33
34 /*
35 * Types and functions for bit access and manipulation
36 */
37 #include "ccd_globs.h"
38 #include "bitfun.h"
39
40 /*
41 * Prototypes of ccd internal functions
42 */
43 #include "ccd.h"
44
45 /*
46 * Declaration of coder/decoder tables
47 */
48 #include "ccdtable.h"
49 #include "ccddata.h"
50
51 /*
52 * Need memory allocation functions for dynamic arrays (pointers)
53 */
54 #ifdef DYNAMIC_ARRAYS
55 #include "vsi.h"
56 #include <string.h>
57 #endif
58
59
60 #ifndef RUN_FLASH
61 /*
62 +--------------------------------------------------------------------+
63 | PROJECT : CCD (6144) MODULE : CCD |
64 | STATE : code ROUTINE : cdc_csn1_sx_decode |
65 +--------------------------------------------------------------------+
66
67 PURPOSE : The encoded IE consists of one bit for presence flag and
68 a value part.
69 In case of CSN1_S1 only if the flag bit is equal 1 the
70 value part will follow it.
71 In case of CSN1_S0 only if the flag bit is equal 0 the
72 value part will follow it.
73 */
74
75 SHORT cdc_csn1_sx_decode (int flag, const ULONG e_ref, T_CCD_Globs *globs)
76 {
77 ULONG repeat, max_rep, act_offset;
78 ULONG amount = 1;
79 BOOL is_variable;
80 ULONG cix_ref, num_prolog_steps, prolog_step_ref;
81 #ifdef DYNAMIC_ARRAYS
82 U8 *old_pstruct = NULL;
83 U8 *addr = NULL;
84 #endif
85
86 #ifdef DEBUG_CCD
87 #ifndef CCD_SYMBOLS
88 TRACE_CCD (globs, "cdc_csn1_sx_decode()");
89 #else
90 TRACE_CCD (globs, "cdc_csn1_sx_decode() %s", ccddata_get_alias((USHORT) e_ref, 1));
91 #endif
92 #endif
93
94 globs->SeekTLVExt = FALSE;
95
96 cix_ref = melem[e_ref].calcIdxRef;
97 num_prolog_steps = calcidx[cix_ref].numPrologSteps;
98 prolog_step_ref = calcidx[cix_ref].prologStepRef;
99
100 /*
101 * If this element is conditional, check the condition.
102 */
103 if (calcidx[cix_ref].numCondCalcs NEQ 0
104 AND ! ccd_conditionOK (e_ref, globs))
105 return 1;
106
107 /*
108 * If this element has a defined prologue
109 * we have to process it before decoding the bitstream.
110 */
111 if (num_prolog_steps)
112 {
113 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
114 }
115
116 if (melem[e_ref].repType NEQ ' ')
117 {
118 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs);
119 /* Structured IE is to be handeled as bitstring.*/
120 if (melem[e_ref].repType == 's')
121 {
122 repeat--;
123 }
124 }
125 else
126 {
127 is_variable = FALSE;
128 repeat = 1;
129 }
130
131 #ifdef DYNAMIC_ARRAYS
132 /*
133 * Check for pointer types; allocate memory if necessary.
134 * May overwrite globs->pstruct (and initialize globs->pstructOffs to 0).
135 */
136 if ( is_pointer_type(e_ref) )
137 {
138 U32 cSize;
139
140 /*
141 * Find size to allocate;
142 * - Read from mcomp or mvar according to type
143 */
144 cSize = (ULONG)((melem[e_ref].elemType EQ 'F' OR
145 melem[e_ref].elemType EQ 'R')
146 ? mvar[melem[e_ref].elemRef].cSize
147 : mcomp[melem[e_ref].elemRef].cSize
148 ) * repeat;
149
150 /*
151 * Allocate additional memory
152 */
153 addr = (U8 *)DP_ALLOC( cSize, globs->alloc_head, DP_NO_FRAME_GUESS);
154
155 /* If no memory, log error and return immediately */
156 if (addr EQ NULL) {
157 ccd_setError (globs, ERR_NO_MEM,
158 BREAK,
159 (USHORT) -1);
160 return 1;
161 }
162 else
163 memset (addr, 0, (size_t)cSize);
164
165 /*
166 * Memory allocated;
167 */
168 }
169 #endif
170
171 if (melem[e_ref].elemType NEQ 'S')
172 {
173 /*
174 * Element is not a SPARE. Setup the struct pointer.
175 */
176 globs->pstructOffs = melem[e_ref].structOffs;
177
178
179 if (is_variable)
180 {
181 UBYTE *addr_v_xxx = NULL;
182 UBYTE *addr_c_xxx;
183 UBYTE act_continue_array;
184
185
186 if (melem[e_ref].optional)
187 {
188 /*
189 * For optional elements we must set the valid-flag,
190 * if there is at least one element in the message.
191 * Therefore we store the address of the valid flag.
192 */
193 /* Dynamic array addition.
194 * Postpone optional flag setting for non-code transparent
195 * pointer types ('P', 'Q', 'R').
196 * For these types, the optional flag is the pointer itself.
197 * These types cannot be set yet, as the pointer may be
198 * preceeded by a counter octet, a union tag id octet etc.
199 */
200 if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R')
201 addr_v_xxx = (UBYTE *) (globs->pstruct + globs->pstructOffs++);
202 }
203 /*
204 * For variable sized elements store the min-value
205 * as counter into the C-Structure (c_xxx).
206 */
207 addr_c_xxx = (UBYTE *) (globs->pstruct + globs->pstructOffs++);
208 if (max_rep > 255)
209 globs->pstructOffs++;
210
211 /*
212 * Store the initial offset
213 */
214
215 act_offset = (ULONG) globs->pstructOffs;
216
217 #ifdef DYNAMIC_ARRAYS
218 if ( is_pointer_type(e_ref) )
219 {
220 /*
221 * 1. Save old "globs->pstruct" variables
222 * 2. Store pointer to freshly allocated memory area in structure
223 * 3. Initialize pstruct to point to the freshly allocated memory area.
224 * 4. Initialize pstructOffs to 0 to start decoding at offset 0
225 * in the new memory area.
226 */
227 old_pstruct = globs->pstruct;
228 *(U8 **)(globs->pstruct + globs->pstructOffs) = addr;
229 globs->pstruct = addr;
230 globs->pstructOffs = 0;
231 }
232 #endif
233
234 /*
235 * repType ='i':
236 * Repeat this element (if it is an array) until we detect a
237 * flag indicating absence.
238 *
239 * repType ='v' and 'c':
240 * Repeat the IE and leave the loop.
241 *
242 * In both cases we expect a 0 at first.
243 */
244 if ((melem[e_ref].repType == 'v') || (melem[e_ref].repType == 'c'))
245 {
246 amount = repeat;
247 }
248 repeat = 0;
249 act_continue_array = globs->continue_array;
250 globs->continue_array = TRUE;
251
252 while (globs->continue_array)
253 {
254 if (flag == 0xFF) /* CSN1_SH type*/
255 {
256 if (bf_readBit(globs) != GET_HL_PREV(1))
257 break;
258 }
259 else
260 {
261 if (bf_readBit(globs) != flag)
262 break;
263 }
264 /*
265 * Flag is set, we must decode the element
266 */
267
268 cdc_decodeElemvalue (e_ref, &amount, globs);
269
270 if (++repeat > max_rep)
271 {
272 /*
273 * Too many repetitions means error in encoded message.
274 */
275 ccd_setError (globs, ERR_MAX_REPEAT,
276 BREAK,
277 (USHORT) (globs->bitpos),
278 (USHORT) -1);
279 return 1;
280 }
281 else if (melem[e_ref].repType EQ 'v')
282 {
283 repeat = amount;
284 break;
285 }
286 /*
287 * Recalculate the struct offset for repeatable IEs.
288 */
289 if (is_variable_type(e_ref))
290 {
291 globs->pstructOffs = (USHORT)(act_offset +
292 (repeat * mvar[melem[e_ref].elemRef].cSize));
293 }
294 else
295 {
296 globs->pstructOffs = (USHORT)(act_offset +
297 (repeat * mcomp[melem[e_ref].elemRef].cSize));
298 }
299 }
300 globs->continue_array = act_continue_array;
301
302 #ifdef DYNAMIC_ARRAYS
303 /*
304 * Restore globs->pstruct
305 */
306 if (old_pstruct NEQ NULL)
307 {
308 globs->pstruct = old_pstruct;
309 }
310 #endif
311
312 if (addr_v_xxx NEQ NULL)
313 {
314 /*
315 * For optional elements set the valid-flag
316 * In this case the pointer addr_c_xxx does not mark
317 * the counter. It points to the valid flag.
318 */
319 if (repeat > 0)
320 *addr_v_xxx++ = (UBYTE) TRUE;
321 }
322 /*
323 * Store the number of digits into the c_xxx variable if there is one.
324 */
325 if (max_rep > 65535)
326 {
327 ULONG *addr_c_xxx_u32;
328 addr_c_xxx_u32 = (ULONG *)addr_c_xxx;
329 *addr_c_xxx_u32 = repeat;
330 }
331 else if (max_rep > 255)
332 {
333 USHORT *addr_c_xxx_u16;
334 addr_c_xxx_u16 = (USHORT *)addr_c_xxx;
335 *addr_c_xxx_u16 = (USHORT) repeat;
336 }
337 else
338 *addr_c_xxx = (UBYTE) repeat;
339 }
340 /*
341 * IE is not defined as an array.
342 */
343 else
344 {
345 BOOL elemPresent;
346
347 if (flag == 0xFF)
348 elemPresent = (bf_readBit(globs) EQ GET_HL_PREV(1));
349 else
350 elemPresent = (bf_readBit(globs) == flag);
351
352 if (elemPresent)
353 {
354 if (melem[e_ref].optional)
355 {
356 /*
357 * For optional elements set the valid-flag.
358 */
359 globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE;
360 }
361
362 /*
363 * Flag is set, we must decode the element.
364 */
365 cdc_decodeElemvalue (e_ref, &repeat, globs);
366 /*
367 * process the epilogue expression for this element if there is any
368 */
369 if (num_prolog_steps)
370 {
371 if ( (calc[prolog_step_ref+1].operation EQ 'K')
372 || (calc[prolog_step_ref+1].operation EQ 'C')
373 || (calc[prolog_step_ref+1].operation EQ 's'))
374 {
375 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
376 }
377 }
378 }
379 }
380 }
381
382 return 1;
383 }
384 #endif /* !RUN_FLASH */
385
386 #ifndef RUN_FLASH
387 /*
388 +--------------------------------------------------------------------+
389 | PROJECT : CCD (6144) MODULE : CDC_GSM |
390 | STATE : code ROUTINE : cdc_csn1_sx_encode |
391 +--------------------------------------------------------------------+
392
393 PURPOSE : Encoding of the CSN1 element.
394 1) GSM Type CSN1 S1 element
395 This element consists of a 1 bit valid flag and a
396 value part. If the element is valid (the v_xxx
397 components is TRUE in the decoded message) a 1 bit will
398 be coded followed by the coding of the value part.
399 Otherwise a 0 bit will be coded.
400
401 2) GSM Type CSN1 S0 element
402 This element consists of a single bit valid flag and a
403 value part, too. But in this case the presence flag is
404 set to 0. If the element is present (the v_xxx component
405 is TRUE in the decoded message) a 0 bit will be coded
406 followed by the encoded value part. Otherwise a 1 bit
407 will be encoded.
408 */
409
410 SHORT cdc_csn1_sx_encode (int flag, const ULONG e_ref, T_CCD_Globs *globs)
411 {
412 ULONG i, repeat=1, amount=1;
413 USHORT cSize = 0, startOffset;
414 int elemPresent;
415 ULONG cix_ref, num_prolog_steps, prolog_step_ref;
416 #ifdef DYNAMIC_ARRAYS
417 U8 *old_pstruct = NULL;
418 #endif
419
420 #ifdef DEBUG_CCD
421 #ifndef CCD_SYMBOLS
422 TRACE_CCD (globs, "cdc_csn1_sx_encode()");
423 #else
424 TRACE_CCD (globs, "cdc_csn1_sx_encode() %s", ccddata_get_alias((USHORT) e_ref, 1));
425 #endif
426 #endif
427
428 cix_ref = melem[e_ref].calcIdxRef;
429 num_prolog_steps = calcidx[cix_ref].numPrologSteps;
430 prolog_step_ref = calcidx[cix_ref].prologStepRef;
431 /*
432 * If this element is conditional, check the condition.
433 */
434 if (calcidx[cix_ref].numCondCalcs NEQ 0
435 AND ! ccd_conditionOK (e_ref, globs))
436 return 1;
437
438 /*
439 * If this element has a defined prologue
440 * we have to process it before decoding the bitstream.
441 */
442 if (num_prolog_steps)
443 {
444 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
445 }
446
447 if (melem[e_ref].elemType NEQ 'S')
448 {
449 UBYTE act_continue_array;
450
451 act_continue_array = globs->continue_array;
452 globs->continue_array = TRUE;
453 /*
454 * Element is not a SPARE.
455 * Setup the offset into the C-structure for this element
456 */
457 globs->pstructOffs = melem[e_ref].structOffs;
458
459 if (melem[e_ref].optional)
460 {
461 /*
462 * For optional elements check the valid-flag in the C-struct.
463 * Spare elements does not have a corresponding valid flag.
464 */
465 /* Dynamic array addition.
466 * Postpone optional flag setting for non-code transparent
467 * pointer types ('P', 'Q', 'R').
468 * For these types, the optional flag is the pointer itself.
469 * These types cannot be set yet, as the pointer may be
470 * preceeded by a counter octet, a union tag id octet etc.
471 */
472 if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R')
473 {
474 if (globs->pstruct[globs->pstructOffs++] == FALSE)
475 {
476 /*
477 * The IE should not be present in the message so we code
478 * a single bit
479 * for CSN1_S1 as 0,
480 * for CSN1_S0 as 1 and
481 * for CSN1_SH as GET_HL(0)
482 */
483 if (flag == 0xFF)
484 elemPresent = GET_HL(0);
485 else
486 elemPresent = flag ^ 0x00000001;
487 bf_writeBit (elemPresent, globs);
488 return 1;
489 }
490 #ifdef DEBUG_CCD
491 else if (globs->pstruct [melem[e_ref].structOffs] != TRUE)
492 {
493 TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d",
494 e_ref);
495 }
496 #endif
497 }
498 }
499
500 /* As a default amount =1 due to initialization. */
501 if (melem[e_ref].repType EQ 'i')
502 {
503 /* The actual number of elements belonging to the array is unknown.
504 * The user should have written the desired number to the C-Structure
505 * (c_xxx). CCD reads the number of these variable repeatable elements
506 * out of this C-Structure (c_xxx) and encodes each element with a
507 * preceeding bit set to '0'. The last element is followed by a bit
508 * set to '1' to indicate the end of this array.
509 * If the number of repeats given by the C-Structure exceeds the
510 * allowed value (maxRepeat) CCD gives a warning!
511 */
512 if (melem[e_ref].maxRepeat > 255)
513 {
514 ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++));
515 repeat = MINIMUM (count, (ULONG) melem[e_ref].maxRepeat);
516 if (repeat < count)
517 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
518 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
519 }
520 else
521 {
522 repeat = (ULONG) MINIMUM (globs->pstruct[globs->pstructOffs],
523 melem[e_ref].maxRepeat);
524 if ( repeat < (ULONG) (globs->pstruct[globs->pstructOffs]) )
525 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
526 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
527 }
528 amount = 1;
529 globs->pstructOffs++;
530 }
531 else
532 if (melem[e_ref].repType EQ 'v')
533 {
534 /* The number of elements belonging to the array depends on the value
535 * of another element. The user should have written this number to the
536 * C-Structure (c_xxx).
537 * CCD reads the number of these variable repeatable elements out of
538 * this C-Structure (c_xxx).
539 * If the number of repetitions given by the C-Structure exceeds the
540 * allowed value (maxRepeat) CCD gives a warning!
541 */
542 if (melem[e_ref].maxRepeat > 255)
543 {
544 ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++));
545 amount = MINIMUM (count, (ULONG) melem[e_ref].maxRepeat);
546 if (amount < count)
547 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
548 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
549 }
550 else
551 {
552 amount = (ULONG)MINIMUM (globs->pstruct[globs->pstructOffs],
553 melem[e_ref].maxRepeat);
554 if ( amount < (ULONG) (globs->pstruct[globs->pstructOffs]) )
555 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
556 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
557 }
558 repeat = 1;
559 globs->pstructOffs++;
560 }
561 else
562 if (melem[e_ref].repType EQ 'c')
563 {
564 amount = (ULONG) melem[e_ref].maxRepeat;
565 repeat = 1;
566 }
567 else
568 if (melem[e_ref].repType == 's')
569 {
570 BOOL is_variable;
571 ULONG max_rep;
572
573 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs);
574 /* Substract one bit which will be spent on the (CSN.1) flag. */
575 amount = repeat - 1;
576 repeat = 1;
577 }
578 if (melem[e_ref].repType EQ 'v' OR melem[e_ref].repType EQ 'i')
579 {
580 cSize = (USHORT)((melem[e_ref].elemType EQ 'V' OR
581 melem[e_ref].elemType EQ 'R' OR melem[e_ref].elemType EQ 'F')
582 ? mvar[melem[e_ref].elemRef].cSize
583 : mcomp[melem[e_ref].elemRef].cSize
584 );
585
586 startOffset = (USHORT) globs->pstructOffs;
587 }
588
589 /* Dynamic array addition.
590 * Check for non-code transparent pointer types ('P', 'Q', 'R').
591 * For these types, the optional flag is the pointer itself.
592 * ASSUMPTION: The pointer may be preceeded by a counter octet,
593 * a union tag id octet etc., but it is up to CCDGEN to ensure
594 * word alignment (by inserting alignment bytes). Therefore
595 * we just read from globs->pstruct[globs->pstructOffs].
596 */
597 #ifdef DEBUG_CCD
598 /* Check pointer alignment and re-align if necessary (should never happen) */
599 if ( is_pointer_type(e_ref) AND ((globs->pstructOffs & 3) NEQ 0)) {
600 TRACE_CCD (globs, "cdc_csn1_sx_encode(): Pointer misaligned! pstruct=0x08x,"
601 " pstructOffs=0x%08x", globs->pstruct, globs->pstructOffs);
602 globs->pstructOffs = (globs->pstructOffs + 3) & 3;
603 }
604 #endif
605 #ifdef DYNAMIC_ARRAYS
606 /*
607 * Perform pointer dereference for pointer types.
608 * Also, check optionality for these types.
609 */
610 if ( is_pointer_type(e_ref) ) {
611 U8 *deref_pstruct;
612
613 /* Get pointer value */
614 deref_pstruct = *(U8 **)&globs->pstruct[globs->pstructOffs];
615
616 /*
617 * Strictly speaking the 'D' to 'F' types should not need this
618 * check (should have returned after the optionality check above),
619 * but it will catch stray NULL pointers (or uninitialized
620 * valid flags)
621 */
622 if (ccd_check_pointer(deref_pstruct) != ccdOK )
623 {
624 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref,
625 &globs->pstruct[globs->pstructOffs]);
626 return 1;
627 }
628 /*
629 * Pointer not NULL;
630 * 1. Save old globs->pstruct and assign pointer to globs->pstruct
631 * as new base.
632 * 2. Set pstructOffs to 0 (zero) as the next offset will start
633 * in the new memory area.
634 */
635 old_pstruct = globs->pstruct;
636 globs->pstruct = deref_pstruct;
637 startOffset = 0;
638 }
639 #endif /* DYNAMIC_ARRAYS */
640
641 for (i=0; i < repeat; i++)
642 {
643 /*
644 * The IE should be present in the message so we code 0 bit.
645 */
646 if (flag == 0xFF)
647 elemPresent = GET_HL(1);
648 else
649 elemPresent = flag;
650
651 bf_writeBit (elemPresent, globs);
652 if (cSize)
653 {
654 /*
655 * Calculate the offset if it is an array.
656 */
657 globs->pstructOffs = (USHORT)(startOffset + (i * cSize));
658 }
659 /*
660 * Encode the value.
661 */
662 cdc_encodeElemvalue (e_ref, amount, globs);
663 }
664
665 #ifdef DYNAMIC_ARRAYS
666 if ( old_pstruct NEQ NULL )
667 globs->pstruct = old_pstruct;
668 #endif
669
670 if ((melem[e_ref].repType == 'i') && (globs->continue_array == TRUE))
671 {
672 /*
673 * For fields of variable length we code a 1 flag
674 * to mark the end of the array.
675 */
676 if (flag == 0xFF)
677 elemPresent = GET_HL(0);
678 else
679 elemPresent = flag ^ 0x00000001;
680 bf_writeBit (elemPresent, globs);
681 }
682 globs->continue_array = act_continue_array;
683 }
684
685 return 1;
686 }
687 #endif /* !RUN_FLASH */