comparison gsm-fw/ccd/cdc_std.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_std.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 non protocol specific encoding and decoding
19 | functions
20 +-----------------------------------------------------------------------------
21 */
22
23 #define CCD_STD_C
24
25 #ifdef _MSDOS
26 #include <dos.h>
27 #include <conio.h>
28 #endif
29
30 /*
31 * standard definitions like UCHAR, ERROR etc.
32 */
33 #include "typedefs.h"
34 #include "header.h"
35 #include <string.h>
36
37 /*
38 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
39 * look at ccdapi.h.
40 */
41 #undef USE_DRIVER
42 #include "ccdapi.h"
43
44 /*
45 * Types and functions for bit access and manipulation
46 */
47 #include "ccd_globs.h"
48 #include "bitfun.h"
49
50 /*
51 * Declaration of coder/decoder tables and/or functions to access them
52 */
53 #include "ccdtable.h"
54 #include "ccddata.h"
55
56 /*
57 * Prototypes of ccd internal functions
58 */
59 #include "ccd.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 /*
70 +--------------------------------------------------------------------+
71 | PROJECT : CCD (6144) MODULE : CCD |
72 | STATE : code ROUTINE : cdc_decodeElemvalue |
73 +--------------------------------------------------------------------+
74
75 PURPOSE : Performs a standard decoding for a given elem table entry.
76 This means for non structured elements that 1-n bits are
77 read from the bitstream and write to a C-Variable
78 in a machine dependent format. For structured elements
79 an (indirect) recursive call to cc_decodeComposition()
80 is performed. If the element is a bitbuffer with variable
81 size, the repeat value gives the number of bits to read
82 from the bitstream into the buffer. The maxBitpos
83 indicates the maximum valid position for the
84 readpointer of the bitstream while decoding this element.
85 If the readpointer break this boundary, this element will
86 not be decoded.
87 */
88
89 void cdc_decodeElemvalue (ULONG e_ref, ULONG *repeat, T_CCD_Globs *globs)
90 {
91 UBYTE *ActStructpos;
92 ULONG i;
93 UBYTE spareLen;
94
95 /*
96 * element is a bit field of variable length
97 */
98 if ((melem[e_ref].repType == 'b') || (melem[e_ref].repType == 's'))
99 {
100 if (*repeat > (ULONG) (globs->maxBitpos-globs->bitpos))
101 {
102 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
103 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
104 *repeat = MINIMUM (*repeat, (ULONG) (globs->maxBitpos-globs->bitpos));
105 }
106 if (melem[e_ref].repType == 'b')
107 {
108 if (mvar[melem[e_ref].elemRef].cType EQ 'X')
109 bf_readBitChunk (*repeat, globs);
110 else
111 bf_readBits (*repeat, globs);
112 }
113 else
114 {
115 U16 finalBP = globs->bitpos + (USHORT) *repeat;
116 /* Store the limit. This comp may contain other comps as bitstring. */
117 globs->maxBitpos = finalBP;
118 ActStructpos = globs->pstruct;
119 globs->pstruct += globs->pstructOffs;
120 #ifdef DEBUG_CCD
121 #ifdef CCD_SYMBOLS
122 TRACE_CCD (globs, "decoding composition %s as a bit array",
123 mcomp[melem[e_ref].elemRef].name);
124 #else
125 TRACE_CCD (globs, "decoding composition %d", melem[e_ref].elemRef);
126 #endif
127 #endif
128
129 ccd_decodeComposition ((ULONG) (melem[e_ref].elemRef), globs);
130 if (finalBP < globs->bitpos)
131 {
132 ccd_recordFault (globs, ERR_BITSTR_COMP, CONTINUE, (USHORT) e_ref,
133 globs->pstruct + globs->pstructOffs);
134 }
135 bf_setBitpos (finalBP, globs);
136 /* Update maxBitpos to avoid an early end of decoding. */
137 globs->maxBitpos = globs->buflen;
138 globs->pstruct = ActStructpos;
139 }
140 }
141 else
142 {
143 /*
144 * For pointer types, globs->pstruct is already set to point to
145 * the new memory area, and these types are not treated differently
146 * from non-pointer types.
147 */
148 i=0;
149 switch (melem[e_ref].elemType)
150 {
151 case 'R': /* Pointer to (possible array of) basetype */
152 case 'F': /* Code-transparent pointer to (possible array of) basetype */
153 case 'V':
154 while (i < *repeat)
155 {
156 if (globs->bitpos < globs->maxBitpos)
157 {
158 #ifdef DEBUG_CCD
159 #ifdef CCD_SYMBOLS
160 TRACE_CCD (globs, "decoding var %s",
161 ccddata_get_alias((USHORT) e_ref, 1));
162 #else
163 TRACE_CCD (globs, "decoding var %d", melem[e_ref].elemRef);
164 #endif
165 #endif
166 if (mvar[melem[e_ref].elemRef].cType EQ 'X')
167 bf_readBitChunk (mvar[melem[e_ref].elemRef].bSize, globs);
168 else
169 bf_readBits (mvar[melem[e_ref].elemRef].bSize, globs);
170
171 globs->pstructOffs += mvar[melem[e_ref].elemRef].cSize;
172
173 i++;
174 }
175 else
176 {
177 if (melem[e_ref].repType != 'i')
178 {
179 ccd_recordFault (globs, ERR_ELEM_LEN, CONTINUE, (USHORT) e_ref,
180 globs->pstruct + globs->pstructOffs);
181 }
182 break;
183 }
184 }
185 break;
186
187 case 'D': /* Pointer to a composition */
188 case 'P': /* Code transparent pointer to a comp */
189 case 'C': /* Element is a composition. */
190 case 'U': /* Element is a union. */
191 /*
192 * Store the actual structure position.
193 */
194 ActStructpos = globs->pstruct;
195
196 globs->pstruct += globs->pstructOffs;
197
198 while (i < *repeat)
199 {
200 if (globs->bitpos < globs->maxBitpos)
201 {
202 #ifdef DEBUG_CCD
203 #ifdef CCD_SYMBOLS
204 TRACE_CCD (globs, "decoding composition %s",
205 mcomp[melem[e_ref].elemRef].name);
206 #else
207 TRACE_CCD (globs, "decoding composition %d", melem[e_ref].elemRef);
208 #endif
209 #endif
210 /*
211 * recursiv call
212 */
213 ccd_decodeComposition ((ULONG) (melem[e_ref].elemRef), globs);
214 globs->pstruct += mcomp[melem[e_ref].elemRef].cSize;
215
216 i++;
217 }
218 else
219 {
220 if (melem[e_ref].repType != 'i')
221 {
222 ccd_recordFault (globs, ERR_ELEM_LEN, CONTINUE, (USHORT) e_ref,
223 globs->pstruct + globs->pstructOffs);
224 }
225 break;
226 }
227 }
228 /*
229 * restore the write pointer
230 */
231 globs->pstruct = ActStructpos;
232 break;
233
234 case 'S': /* Element is a spare. */
235 {
236 spareLen = spare[melem[e_ref].elemRef].bSize;
237 /*
238 * Do not decode padding bits. They are not relevant.
239 * Just adjust the position pointer in the bit stream buffer.
240 */
241 while (i < *repeat)
242 {
243 if (globs->bitpos < globs->maxBitpos)
244 {
245 #ifdef DEBUG_CCD
246 TRACE_CCD (globs, "decoding spare");
247 #endif
248 bf_incBitpos (spareLen, globs);
249 i++;
250 }
251 else
252 break;
253 }
254 break;
255 }
256 }
257 *repeat = i;
258 }
259 }
260 #endif /* !RUN_FLASH */
261
262 #ifndef RUN_FLASH
263 /*
264 +--------------------------------------------------------------------+
265 | PROJECT : CCD (6144) MODULE : CCD |
266 | STATE : code ROUTINE : cdc_encodeElemvalue |
267 +--------------------------------------------------------------------+
268
269 PURPOSE : Performs a standard encoding for a given elem table entry.
270 This means for non structured elements that 1-n bits are
271 read from the bitstream and write to a C-Variable
272 in a machine dependent format. For structured elements
273 an (indirect) recursive call to cc_decodeComposition()
274 is performed. If the element is a bitbuffer with variable
275 size, the repeat value gives the number of bits to write
276 from the buffer into the bitstream.
277 */
278
279 void cdc_encodeElemvalue (ULONG e_ref, ULONG repeat, T_CCD_Globs *globs)
280 {
281 UBYTE *ActStructpos = NULL;
282 ULONG i;
283 UBYTE spareLen;
284
285 /*
286 * Element is a bit field of variable length.
287 */
288 if (melem[e_ref].repType == 'b')
289 {
290 if (mvar[melem[e_ref].elemRef].cType EQ 'X')
291 bf_writeBitChunk (repeat, globs);
292 else
293 bf_writeBits (repeat, globs);
294 }
295 /*
296 * Element is a structured IE defined as bit string.
297 */
298 else if (melem[e_ref].repType == 's')
299 {
300 U16 finalBP = (USHORT) (globs->bitpos + repeat);
301 ActStructpos = globs->pstruct;
302 globs->pstruct += globs->pstructOffs;
303 #ifdef DEBUG_CCD
304 #ifdef CCD_SYMBOLS
305 TRACE_CCD (globs, "encoding composition %s as a bit array",
306 mcomp[melem[e_ref].elemRef].name);
307 #else
308 TRACE_CCD (globs, "encoding composition %d", melem[e_ref].elemRef);
309 #endif
310 #endif
311
312 ccd_encodeComposition ((ULONG) melem[e_ref].elemRef, globs);
313 if (finalBP < globs->bitpos)
314 {
315 ccd_recordFault (globs, ERR_BITSTR_COMP, CONTINUE, (USHORT) e_ref,
316 globs->pstruct + globs->pstructOffs);
317 }
318 bf_setBitpos (finalBP, globs);
319 globs->pstruct = ActStructpos;
320 }
321 else
322 {
323 /*
324 * For pointer types, globs->pstruct is already set to point to
325 * the new memory area, and these types are not treated differently
326 * from non-pointer types.
327 */
328 switch(melem[e_ref].elemType)
329 {
330 case 'R': /* Pointer to (possible array of) basetype */
331 case 'F': /* Code-transparent pointer to (possible array of) basetype */
332 case 'V':
333 for (i=0; i<repeat; i++)
334 {
335 #ifdef DEBUG_CCD
336 #ifdef CCD_SYMBOLS
337 TRACE_CCD (globs, "encoding var %s",
338 ccddata_get_alias((USHORT) e_ref, 1));
339 #else
340 TRACE_CCD (globs, "encoding var %s", melem[e_ref].elemRef);
341 #endif
342 #endif
343 if (mvar[melem[e_ref].elemRef].cType EQ 'X')
344 bf_writeBitChunk (mvar[melem[e_ref].elemRef].bSize, globs);
345 else
346 bf_writeBits (mvar[melem[e_ref].elemRef].bSize, globs);
347
348 globs->pstructOffs += mvar[melem[e_ref].elemRef].cSize;
349 }
350 break;
351
352 case 'D': /* Pointer to a composition (already dereferenced) */
353 case 'P': /* Code transparent pointer to a comp (already dereferenced) */
354 case 'C': /* Element is a composition. */
355 case 'U': /* Element is a union. */
356 /*
357 * store the actual structure position
358 */
359 ActStructpos = globs->pstruct;
360
361 globs->pstruct += globs->pstructOffs;
362
363 for (i=0; i<repeat; i++)
364 {
365 #ifdef DEBUG_CCD
366 #ifdef CCD_SYMBOLS
367 TRACE_CCD (globs, "encoding composition %s",
368 mcomp[melem[e_ref].elemRef].name);
369 #else
370 TRACE_CCD (globs, "encoding composition %d", melem[e_ref].elemRef);
371 #endif
372 #endif
373 ccd_encodeComposition ((ULONG) melem[e_ref].elemRef, globs); /* recursiv call */
374 globs->pstruct += mcomp[melem[e_ref].elemRef].cSize;
375 }
376 /*
377 * restore the write pointer
378 */
379 globs->pstruct = ActStructpos;
380 break;
381
382 case 'S': /* element is a spare */
383 {
384 spareLen = spare[melem[e_ref].elemRef].bSize;
385
386 /*
387 * encode the spare
388 */
389 for (i=0; i < repeat; i++)
390 {
391 #ifdef DEBUG_CCD
392 TRACE_CCD (globs, "encoding spare");
393 #endif
394 bf_codeLongNumber (spareLen, spare[melem[e_ref].elemRef].value, globs);
395 }
396 break;
397 }
398 }
399 }
400 }
401 #endif /* !RUN_FLASH */
402
403 #ifndef RUN_FLASH
404 /*
405 +--------------------------------------------------------------------+
406 | PROJECT : CCD (6144) MODULE : CCD |
407 | STATE : code ROUTINE : cdc_STD_decode |
408 +--------------------------------------------------------------------+
409
410 PURPOSE : Performs a standard decoding for a given elem table entry.
411 This means for non structured elements that 1-n bits are
412 read from the bitstream and write to a C-Variable
413 in a machine dependent format. For structured elements
414 an (indirect) recursive call to cc_decodeComposition()
415 is performed.
416 The element may be conditional and/or repeatable.
417 */
418
419 SHORT cdc_std_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
420 {
421 ULONG repeat, amount, act_offset;
422 BOOL is_variable;
423 U8 *old_pstruct = NULL;
424 ULONG cix_ref, num_prolog_steps, prolog_step_ref;
425
426 #ifdef DEBUG_CCD
427 #ifndef CCD_SYMBOLS
428 TRACE_CCD (globs, "cdc_std_decode()");
429 #else
430 TRACE_CCD (globs, "cdc_std_decode() %s", ccddata_get_alias((USHORT) e_ref, 1));
431 #endif
432 #endif
433
434 cix_ref = melem[e_ref].calcIdxRef;
435 num_prolog_steps = calcidx[cix_ref].numPrologSteps;
436 prolog_step_ref = calcidx[cix_ref].prologStepRef;
437
438 /*
439 * if this element is conditional, check the condition
440 */
441 if (calcidx[cix_ref].numCondCalcs NEQ 0
442 AND ! ccd_conditionOK (e_ref, globs))
443 return 1;
444
445 /*
446 * if this element has a defined prologue
447 * we have to process it before decoding the bitstream
448 * If there are some epilogue expressions to be processed for this element
449 * (rare cases) the result here will be a reading of 0 to an internal
450 * register. The valid processing of expression takes place after the
451 * decoding of the element.
452 */
453 if (num_prolog_steps)
454 {
455 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
456 }
457
458 /*
459 * if this element is repeatable, and the number of
460 * repeats depends on another element, calculate the repeater
461 */
462 if (melem[e_ref].repType NEQ ' ')
463 {
464 is_variable = ccd_calculateRep (e_ref, &repeat, &act_offset, globs);
465 }
466 else
467 {
468 repeat = 1;
469 is_variable = FALSE;
470 }
471
472 if (melem[e_ref].elemType NEQ 'S')
473 {
474 /*
475 * Element is not a SPARE.
476 * Setup the offset into the C-structure for this element
477 */
478 globs->pstructOffs = melem[e_ref].structOffs;
479
480 if (melem[e_ref].optional)
481 {
482 /* 20010621 MVJ: Dynamic array addition.
483 * Postpone optional flag setting for non-code transparent
484 * pointer types ('P', 'Q', 'R').
485 * For these types, the optional flag is the pointer itself.
486 * These types cannot be set yet, as the pointer may be
487 * preceeded by a counter octet, a union tag id octet etc.
488 */
489 if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R')
490 globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE;
491 }
492
493 if (is_variable)
494 {
495 /*
496 * for variable sized elements store the min-value
497 * as counter into the C-Structure (c_xxx).
498 */
499 if (act_offset > 65535)
500 *(ULONG *) (globs->pstruct + globs->pstructOffs++) = repeat;
501 else if (act_offset > 255)
502 *(USHORT *) (globs->pstruct + globs->pstructOffs++) = (USHORT) repeat;
503 else
504 globs->pstruct[globs->pstructOffs] = (UBYTE) repeat;
505
506 globs->pstructOffs++;
507 }
508 }
509 #ifdef DYNAMIC_ARRAYS
510 /*
511 * MVJ: Dynamic array addition.
512 * Check for pointer types; allocate memory if necessary.
513 */
514 if ( is_pointer_type(e_ref) ) {
515 U32 cSize;
516 U8 *addr;
517
518 /*
519 * Find size to allocate;
520 * - Read from mcomp or mvar according to type
521 */
522 cSize = (ULONG)((melem[e_ref].elemType EQ 'V' OR
523 melem[e_ref].elemType EQ 'R')
524 ? mvar[melem[e_ref].elemRef].cSize
525 : mcomp[melem[e_ref].elemRef].cSize
526 ) * repeat;
527
528 /*
529 * Allocate additional memory
530 */
531 addr = (U8 *)DP_ALLOC( cSize, globs->alloc_head, DP_NO_FRAME_GUESS);
532
533 /* If no memory, log error and return immediately */
534 if (addr EQ NULL) {
535 ccd_setError (globs, ERR_NO_MEM,
536 BREAK,
537 (USHORT) -1);
538 return 1;
539 }
540 else
541 memset (addr, 0, (size_t)cSize);
542
543 /*
544 * Memory allocated;
545 * 1. Save old "globs->pstruct" variables
546 * 2. Store pointer to freshly allocated memory area in structure
547 * 3. Initialize pstruct to point to the freshly allocated memory area.
548 * 4. Initialize pstructOffs to 0 to start decoding at offset 0
549 * in the new memory area.
550 */
551 old_pstruct = globs->pstruct;
552 *(U8 **)(globs->pstruct + globs->pstructOffs) = addr;
553 globs->pstruct = addr;
554 globs->pstructOffs = 0;
555 }
556 #endif
557
558 amount = repeat;
559
560 cdc_decodeElemvalue (e_ref, &amount, globs);
561
562 /*
563 * process the epilogue expression for this element if there is any
564 */
565 if (num_prolog_steps)
566 {
567 if ( (calc[prolog_step_ref+1].operation EQ 'K')
568 || (calc[prolog_step_ref+1].operation EQ 'C')
569 || (calc[prolog_step_ref+1].operation EQ 's'))
570 {
571 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
572 }
573 }
574
575 #ifdef DYNAMIC_ARRAYS
576 /*
577 * Restore globs->pstruct for possible use below
578 */
579 if (old_pstruct NEQ NULL)
580 {
581 globs->pstruct = old_pstruct;
582 }
583 #endif
584 if (amount NEQ repeat AND is_variable)
585 {
586 /*
587 * if the decoded elements are not equal the specified
588 * repeat value, because the bitstream or the IE ended,
589 * store the new c_xxx value.
590 */
591 globs->pstructOffs = melem[e_ref].structOffs;
592
593 if (melem[e_ref].optional)
594 globs->pstructOffs++;
595
596 if (act_offset > 65535)
597 *(ULONG *) (globs->pstruct + globs->pstructOffs) = amount;
598 else if (act_offset > 255)
599 *(USHORT *) (globs->pstruct + globs->pstructOffs) = (USHORT) amount;
600 else
601 globs->pstruct[globs->pstructOffs] = (UBYTE) amount;
602
603 if (melem[e_ref].repType NEQ 'i')
604 {
605 /*
606 * if this element is not of the repeat style 'interval'
607 * ([X..Y] where X and Y are constants) we have to generate
608 * an ccd error because some outstanding repeats are missing.
609 */
610 ccd_setError (globs, ERR_MAND_ELEM_MISS, CONTINUE, (USHORT) -1);
611 }
612 }
613
614 return 1;
615 }
616 #endif /* !RUN_FLASH */
617
618 #ifndef RUN_FLASH
619 /*
620 +--------------------------------------------------------------------+
621 | PROJECT : CCD (6144) MODULE : CCD |
622 | STATE : code ROUTINE : cdc_std_encode |
623 +--------------------------------------------------------------------+
624
625 PURPOSE : Performs a standard encoding for a given elem table entry.
626 This means for non structured elements that m bytes read
627 from the C-Variable, converted to MSB-first format and
628 write 1-n bits at the end of the bitstream.
629 For structured elements an (indirect) recursive call
630 to ccd_encodeComposition() is performed.
631 The element may be conditional and/or repeatable.
632 */
633
634 SHORT cdc_std_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
635 {
636 ULONG repeat, max_rep;
637 BOOL is_variable;
638 ULONG cix_ref, num_prolog_steps, prolog_step_ref;
639 #ifdef DYNAMIC_ARRAYS
640 U8 *old_pstruct = NULL;
641 #endif
642
643 #ifdef DEBUG_CCD
644 #ifndef CCD_SYMBOLS
645 TRACE_CCD (globs, "cdc_std_encode()");
646 #else
647 TRACE_CCD (globs, "cdc_std_encode() %s", ccddata_get_alias((USHORT) e_ref, 1));
648 #endif
649 #endif
650
651 cix_ref = melem[e_ref].calcIdxRef;
652 num_prolog_steps = calcidx[cix_ref].numPrologSteps;
653 prolog_step_ref = calcidx[cix_ref].prologStepRef;
654 /*
655 * if this element is conditional, check the condition
656 */
657 if (calcidx[cix_ref].numCondCalcs NEQ 0
658 AND ! ccd_conditionOK (e_ref, globs))
659 return 1;
660
661 /*
662 * if this element have a defined Prolog
663 * we have to process it before decoding the bitstream
664 */
665 if (num_prolog_steps)
666 {
667 ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
668 }
669
670 if (melem[e_ref].elemType NEQ 'S')
671 {
672 /*
673 * Element is not a SPARE.
674 * Setup the readpointer into the C-structure for this element
675 * MVJ: In case of pointer types, the pstructOffs must be
676 * the offset into the memory area pointed to. CCDGEN must
677 * ensure this holds true.
678 */
679 globs->pstructOffs = melem[e_ref].structOffs;
680
681 if (melem[e_ref].optional)
682 {
683 /*
684 * for optional elements check the valid-flag in the C-struct.
685 * Spare elements does not have a corresponding valid flag. For
686 * the spare elements we have to calculate and check the
687 * condition to decide if this elements have to be coded.
688 */
689 /* 20010621 MVJ: Dynamic array addition.
690 * Postpone optional check for non-code transparent pointer
691 * types ('P', 'Q', 'R').
692 * For these types, the optional flag is the pointer itself.
693 * These types cannot be checked yet, as the pointer may be
694 * preceeded by a counter octet, a union tag id octet etc.
695 */
696 if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R')
697 {
698 if (globs->pstruct[globs->pstructOffs++] == FALSE)
699 {
700 return 1;
701 }
702 #ifdef DEBUG_CCD
703 else if (globs->pstruct [melem[e_ref].structOffs] != TRUE)
704 {
705 TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d",
706 e_ref);
707 }
708 #endif
709 }
710 }
711
712 if ((melem[e_ref].repType EQ 'v' OR melem[e_ref].repType EQ 'i'))
713 {
714 /*
715 * for variable sized elements read the amount
716 * of repeats out of the C-Structure (c_xxx).
717 * If the number of repeats given by the C-Structure
718 * exceeds the allowed value (maxRepeat) CCD gives a warning!
719 */
720 if (melem[e_ref].maxRepeat > 255)
721 {
722 ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++));
723 repeat = MINIMUM (count, (ULONG) melem[e_ref].maxRepeat);
724 if (repeat < count)
725 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
726 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
727 }
728 else
729 {
730 repeat = (ULONG)MINIMUM (globs->pstruct[globs->pstructOffs],
731 melem[e_ref].maxRepeat);
732 if ( repeat < (ULONG) (globs->pstruct[globs->pstructOffs]) )
733 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE,
734 (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
735 }
736 globs->pstructOffs++;
737 }
738 else
739 if (melem[e_ref].repType EQ 'c')
740 {
741 repeat = (ULONG) melem[e_ref].maxRepeat;
742 }
743 else
744 if (melem[e_ref].repType == 's' || melem[e_ref].repType == 'b')
745 {
746 switch (melem[e_ref].elemType)
747 {
748 case 'R': /* Pointer to (possible array of) basetype */
749 case 'F': /* Code-transparent pointer to (possible array of) basetype */
750 case 'V':
751 globs->maxBitpos = globs->bitpos + mvar[melem[e_ref].elemRef].bSize;
752 break;
753 case 'D': /* Pointer to a composition */
754 case 'P': /* Code transparent pointer to a comp */
755 case 'C': /* Element is a composition. */
756 case 'E': /* Pointer to a union */
757 case 'Q': /* Code transparent pointer to a union */
758 case 'U': /* Element is a union. */
759 globs->maxBitpos = globs->bitpos + mcomp[melem[e_ref].elemRef].bSize;
760 break;
761 }
762
763 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs);
764 }
765 else
766 repeat = 1;
767
768 /* 20010621 MVJ: Dynamic array addition.
769 * Check for non-code transparent pointer types ('P', 'Q', 'R').
770 * For these types, the optional flag is the pointer itself.
771 * ASSUMPTION: The pointer may be preceeded by a counter octet,
772 * a union tag id octet etc., but it is up to CCDGEN to ensure
773 * word alignment (by inserting alignment bytes). Therefore
774 * we just read from globs->pstruct[globs->pstructOffs].
775 */
776 #ifdef DEBUG_CCD
777 /* Check pointer alignment and re-align if necessary (should never happen) */
778 if ( is_pointer_type(e_ref) AND ((globs->pstructOffs & 3) NEQ 0)) {
779 TRACE_CCD (globs, "cdc_STD_encode(): Pointer misaligned! pstruct=0x08x,"
780 " pstructOffs=0x%08x", globs->pstruct, globs->pstructOffs);
781 globs->pstructOffs = (globs->pstructOffs + 3) & 3;
782 }
783 #endif
784 #ifdef DYNAMIC_ARRAYS
785 /*
786 * MVJ: Perform pointer dereference for pointer types.
787 * Also, check optionality for these types.
788 */
789 if ( is_pointer_type(e_ref) ) {
790 U8 *deref_pstruct;
791
792 /* Get pointer value */
793 deref_pstruct = *(U8 **)&globs->pstruct[globs->pstructOffs];
794
795 /*
796 * Strictly speaking the 'D' to 'F' types should not need this
797 * check (should have returned after the optionality check above),
798 * but it will catch stray NULL pointers (or uninitialized
799 * valid flags)
800 */
801 if (ccd_check_pointer(deref_pstruct) != ccdOK )
802 {
803 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref,
804 &globs->pstruct[globs->pstructOffs]);
805 return 1;
806 }
807 /*
808 * Pointer not NULL;
809 * 1. Save old globs->pstruct and assign pointer to globs->pstruct
810 * as new base.
811 * 2. Set pstructOffs to 0 (zero) as the next offset will start
812 * in the new memory area.
813 */
814 old_pstruct = globs->pstruct;
815 globs->pstruct = deref_pstruct;
816 globs->pstructOffs = 0;
817 }
818 #endif /* DYNAMIC_ARRAYS */
819 }
820 else
821 {
822 /*
823 * for spare elements we have to calculate the conditions
824 * and the repetitions because there are no valid-flags and
825 * c_xxx variables in the C-structure to read.
826 */
827 if (melem[e_ref].optional)
828 {
829 /*
830 * Spare elements does not have a corresponding valid flag.
831 * For the spare elements we have to calculate and check the
832 * condition to decide if this elements have to be coded.
833 */
834 if (calcidx[cix_ref].numCondCalcs NEQ 0
835 AND ! ccd_conditionOK (e_ref, globs))
836 return 1;
837 }
838 /*
839 * if this spare is repeatable, calculate the amount of
840 * repeats because there is no corresponding c_xxx element
841 * in the C-Structure.
842 */
843 if (melem[e_ref].repType NEQ ' ')
844 {
845 globs->maxBitpos = globs->bitpos + spare[melem[e_ref].elemRef].bSize;
846 is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs);
847 }
848 else
849 repeat = 1;
850 }
851
852 cdc_encodeElemvalue (e_ref, repeat, globs);
853
854 #ifdef DYNAMIC_ARRAYS
855 if ( old_pstruct NEQ NULL )
856 globs->pstruct = old_pstruct;
857 #endif
858
859 return 1;
860 }
861 #endif /* !RUN_FLASH */
862
863 /*
864 * some elementary bitfunctions
865 */
866
867 /* LSB,MSB Definitions for the CPUs */
868
869 #ifdef M_INTEL
870 #define MSB_POS 1
871 #define LSB_POS 0
872 #define MSW_POS 2
873 #define LSW_POS 0
874 #else /* M_INTEL */
875 #ifdef M_MOTOROLA
876 #define MSB_POS 0
877 #define LSB_POS 1
878 #define MSW_POS 0
879 #define LSW_POS 2
880 #endif /* M_MOTOROLA */
881 #endif /* M_INTEL */
882
883 extern const ULONG ccd_bitfun_mask[];
884
885 /*
886 * Table of one-bit values (2^X)
887 * This unused variable is commented now in order to avoid some compiler
888 * warnings like: variable "shift" (line xxx) is not used
889
890 LOCAL const UBYTE shift[] =
891 {
892 128, 64, 32, 16, 8, 4, 2, 1
893 };
894 */
895
896 #ifndef RUN_FLASH
897 /*
898 +--------------------------------------------------------------------+
899 | PROJECT : CCD (6144) MODULE : CCD |
900 | STATE : code ROUTINE : ccd_codeByte |
901 +--------------------------------------------------------------------+
902
903 PURPOSE: encodes the value of (value) into a CPU-dependent
904 bitstring. The length of the bitstring is specified
905 throu (bitlen). The function copies the bitstring into
906 the buffer (bitstream) at bit position (startbit).
907 The bitlen may be between 1 and 8.
908
909 */
910
911 BYTE CCDDATA_PREF(ccd_codeByte) (UBYTE * bitstream,
912 USHORT startbit,
913 USHORT bitlen,
914 UBYTE value)
915 {
916 union
917 { /* Conversion structure 2 Byte <-> unsigned short */
918 UBYTE c[2];
919 USHORT s;
920 }
921 conv;
922
923 UBYTE *p, lshift;
924
925 USHORT m;
926
927 p = bitstream + (startbit >> 3);
928
929 lshift = (16 - ((startbit & 7) + bitlen));
930
931 conv.c[MSB_POS] = p[0];
932
933 conv.c[LSB_POS] = p[1];
934
935 m = ((USHORT) ccd_bitfun_mask[bitlen]) << lshift;
936
937 conv.s &= ~m;
938
939 conv.s |= ((value << lshift) & m);
940
941 p[0] = conv.c[MSB_POS];
942
943 p[1] = conv.c[LSB_POS];
944
945 return ccdOK;
946 }
947 #endif /* !RUN_FLASH */
948
949 #ifndef RUN_FLASH
950 /*
951 +--------------------------------------------------------------------+
952 | PROJECT : CCD (6144) MODULE : CCD |
953 | STATE : code ROUTINE : ccd_decodeByte |
954 +--------------------------------------------------------------------+
955
956 PURPOSE: decodes (bitlen) bits from the (bitstream) at position
957 (startbit) and converts them to a numeric value (value)
958 The bitlen may be between 1 and 8.
959
960 */
961
962 BYTE CCDDATA_PREF(ccd_decodeByte) (UBYTE *bitstream,
963 USHORT startbit,
964 USHORT bitlen,
965 UBYTE *value)
966 {
967 union
968 { /* Conversion structure 2 Byte <-> unsigned short */
969 UBYTE c[2];
970 USHORT s;
971 }
972 conv;
973
974 UBYTE *p;
975
976 p = bitstream + (startbit >> 3);
977
978 conv.c[MSB_POS] = *p++;
979
980 conv.c[LSB_POS] = *p;
981
982 conv.s >>= (16 - ((startbit & 7) + bitlen));
983
984 conv.s &= (USHORT) ccd_bitfun_mask[bitlen];
985
986 *value = (UBYTE) conv.s;
987
988 return ccdOK;
989 }
990 #endif /* !RUN_FLASH */
991
992 #ifndef RUN_FLASH
993 /*
994 +--------------------------------------------------------------------+
995 | PROJECT : CCD (6144) MODULE : CCD |
996 | STATE : code ROUTINE : ccd_codeLong |
997 +--------------------------------------------------------------------+
998
999 PURPOSE: encodes the value of (value) into a CPU-dependent
1000 bitstring. The length of the bitstring is specified
1001 throu (bitlen). The function copies the bitstring into
1002 the buffer (bitstream) at bit position (startbit).
1003 The bitlen may be between 1 and 32.
1004
1005 */
1006
1007 BYTE CCDDATA_PREF(ccd_codeLong) (UBYTE *bitstream,
1008 USHORT startbit,
1009 USHORT bitlen,
1010 ULONG value)
1011 {
1012 UBYTE *p;
1013
1014 union
1015 { /* Conversion structure 4 Byte <-> unsigned long */
1016 UBYTE c[4];
1017 ULONG l;
1018 }
1019 conv;
1020
1021 p = bitstream + (startbit >> 3);
1022 startbit &= 7;
1023
1024 conv.l = value & ccd_bitfun_mask[bitlen];
1025 conv.l <<= (32-bitlen-startbit);
1026
1027 p[0] &= (UCHAR)~ccd_bitfun_mask[8-startbit];
1028
1029 switch ((USHORT)(startbit+bitlen-1) >> 3)
1030 {
1031 case 0:
1032 p[0] |= conv.c[MSW_POS+MSB_POS];
1033 break;
1034 case 1:
1035 p[0] |= conv.c[MSW_POS+MSB_POS];
1036 p[1] = conv.c[MSW_POS+LSB_POS];
1037 break;
1038 case 2:
1039 p[0] |= conv.c[MSW_POS+MSB_POS];
1040 p[1] = conv.c[MSW_POS+LSB_POS];
1041 p[2] = conv.c[LSW_POS+MSB_POS];
1042 break;
1043 case 3:
1044 p[0] |= conv.c[MSW_POS+MSB_POS];
1045 p[1] = conv.c[MSW_POS+LSB_POS];
1046 p[2] = conv.c[LSW_POS+MSB_POS];
1047 p[3] = conv.c[LSW_POS+LSB_POS];
1048 break;
1049 default:
1050 p[0] |= conv.c[MSW_POS+MSB_POS];
1051 p[1] = conv.c[MSW_POS+LSB_POS];
1052 p[2] = conv.c[LSW_POS+MSB_POS];
1053 p[3] = conv.c[LSW_POS+LSB_POS];
1054 p[4] = (UBYTE) ((value & 0xff) << (8-startbit));
1055 break;
1056 }
1057 return ccdOK;
1058 }
1059 #endif /* !RUN_FLASH */
1060
1061 #ifndef RUN_FLASH
1062 /*
1063 +--------------------------------------------------------------------+
1064 | PROJECT : CCD (6144) MODULE : CCD |
1065 | STATE : code ROUTINE : ccd_decodeLong |
1066 +--------------------------------------------------------------------+
1067
1068 PURPOSE: decodes (bitlen) bits from the (bitstream) at position
1069 (startbit) and converts them to a numeric value (value)
1070 The bitlen may be between 1 and 32.
1071
1072 */
1073
1074 BYTE CCDDATA_PREF(ccd_decodeLong) (UBYTE *bitstream,
1075 USHORT startbit,
1076 USHORT bitlen,
1077 ULONG *value)
1078 {
1079 UBYTE *p;
1080
1081 union
1082 { /* Conversion structure 4 Byte <-> unsigned long */
1083 UBYTE c[4];
1084 ULONG l;
1085 }
1086 conv;
1087
1088 p = bitstream + (startbit >> 3);
1089 startbit &= 7;
1090
1091 conv.l = 0L;
1092 switch ((USHORT)(startbit+bitlen-1) >> 3)
1093 {
1094 case 0:
1095 conv.c[MSW_POS+MSB_POS] = p[0];
1096 conv.l <<= startbit;
1097 conv.l >>= (32-bitlen);
1098 break;
1099 case 1:
1100 conv.c[MSW_POS+MSB_POS] = p[0];
1101 conv.c[MSW_POS+LSB_POS] = p[1];
1102 conv.l <<= startbit;
1103 conv.l >>= (32-bitlen);
1104 break;
1105 case 2:
1106 conv.c[MSW_POS+MSB_POS] = p[0];
1107 conv.c[MSW_POS+LSB_POS] = p[1];
1108 conv.c[LSW_POS+MSB_POS] = p[2];
1109 conv.l <<= startbit;
1110 conv.l >>= (32-bitlen);
1111 break;
1112 case 3:
1113 conv.c[MSW_POS+MSB_POS] = p[0];
1114 conv.c[MSW_POS+LSB_POS] = p[1];
1115 conv.c[LSW_POS+MSB_POS] = p[2];
1116 conv.c[LSW_POS+LSB_POS] = p[3];
1117 conv.l <<= startbit;
1118 conv.l >>= (32-bitlen);
1119 break;
1120 default:
1121 conv.c[MSW_POS+MSB_POS] = p[0];
1122 conv.c[MSW_POS+LSB_POS] = p[1];
1123 conv.c[LSW_POS+MSB_POS] = p[2];
1124 conv.c[LSW_POS+LSB_POS] = p[3];
1125 conv.l <<= startbit;
1126 conv.l >>= (32-bitlen);
1127 conv.c[LSW_POS+LSB_POS] |= (p[4] >> (8-startbit));
1128 break;
1129 }
1130 *value = conv.l & ccd_bitfun_mask[bitlen];
1131 return ccdOK;
1132 }
1133 #endif /* !RUN_FLASH */
1134
1135 #ifndef RUN_FLASH
1136 /*
1137 +--------------------------------------------------------------------+
1138 | PROJECT : CCD (6144) MODULE : CCD |
1139 | STATE : code ROUTINE : ccd_bitcopy |
1140 +--------------------------------------------------------------------+
1141
1142 PURPOSE: copys bitlen bits from the source buffer to the destination
1143 buffer. offset contains the position of the first bit in
1144 the source bitfield. This function may perform a leftshift
1145 to adjust the most significant bit on byte boundarys of the
1146 first byte in dest.
1147
1148 */
1149
1150 void CCDDATA_PREF(ccd_bitcopy) (UBYTE *dest,
1151 UBYTE *source,
1152 USHORT bitlen,
1153 USHORT offset)
1154 {
1155 union
1156 { /* Conversion structure 2 Byte <-> unsigned short */
1157 UBYTE c[2];
1158 USHORT s;
1159 }
1160 conv;
1161
1162 USHORT l_shift = offset & 7;
1163 USHORT bytes_to_copy = (bitlen >> 3);
1164
1165 /*
1166 * go to the byte that contains the first valid bit.
1167 */
1168 source += (offset >> 3);
1169
1170
1171 if (l_shift)
1172 {
1173 /*
1174 * shift and copy each byte
1175 */
1176 while (bytes_to_copy--)
1177 {
1178 conv.c[MSB_POS] = *source;
1179 source++;
1180 conv.c[LSB_POS] = *source;
1181 conv.s <<= l_shift;
1182 *dest = conv.c[MSB_POS];
1183 dest++;
1184 }
1185 }
1186 else
1187 {
1188 /*
1189 * no shift operation, do a memcopy;
1190 */
1191 while (bytes_to_copy--)
1192 {
1193 *dest = *source;
1194 dest++;
1195 source++;
1196 }
1197 }
1198 /*
1199 * cutoff the garbage at the end of the bitstream
1200 */
1201
1202 *(dest-1) &= (UCHAR)(~ccd_bitfun_mask[(8-(bitlen&7))&7]);
1203 }
1204 #endif /* !RUN_FLASH */