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