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