blob: 2d3f2421d5f52b84fe04a00bdcc3858467138d37 [file] [log] [blame]
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +02001/* csn1_dec.c
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31#include <assert.h>
32#include <string.h>
33#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
35#include "csn1.h"
36#include <gprs_debug.h>
37
38#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
40
41extern const unsigned char ixBitsTab[];
42guint8 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits);
43
44/**
45 * ================================================================================================
46 * Return TRUE if tag in bit stream indicates existence of next list element,
47 * otherwise return FALSE.
48 * Will work for tag values equal to both 0 and 1.
49 * ================================================================================================
50 */
51
52static gboolean
53existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
54{
55 int res = bitvec_get_bit_pos(vector, (*readIndex)++);
56 if (Tag == STANDARD_TAG)
57 {
58 return (res > 0);
59 }
60 return (res == 0);
61}
62
63
64gint16
65csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
66{
67 gint remaining_bits_len = ar->remaining_bits_len;
68 gint bit_offset = ar->bit_offset;
69 guint8* pui8 = NULL;
70 guint16* pui16;
71 guint32* pui32;
72 guint64* pui64;
73 guint8 Tag = STANDARD_TAG;
74 unsigned ib;
75
76 if (remaining_bits_len < 0)
77 {
78 return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
79 }
80
81 do
82 {
83 switch (pDescr->type)
84 {
85 case CSN_BIT:
86 {
87 if (remaining_bits_len > 0)
88 {
89 pui8 = pui8DATA(data, pDescr->offset);
90 *pui8 = bitvec_read_field(vector, readIndex, 1);
91 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
92 /* end add the bit value to protocol tree */
93 }
94 else if (pDescr->may_be_null)
95 {
96 pui8 = pui8DATA(data, pDescr->offset);
97 *pui8 = 0;
98 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
99 }
100 else
101 {
102 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
103 }
104
105 pDescr++;
106 remaining_bits_len--;
107 bit_offset++;
108 break;
109 }
110
111 case CSN_NULL:
112 { /* Empty member! */
113 bit_offset += pDescr->i;
114 pDescr++;
115 break;
116 }
117
118 case CSN_UINT:
119 {
120 guint8 no_of_bits = (guint8) pDescr->i;
121
122 if (remaining_bits_len >= no_of_bits)
123 {
124 if (no_of_bits <= 8)
125 {
126 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
127 pui8 = pui8DATA(data, pDescr->offset);
128 *pui8 = ui8;
129 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
130 }
131 else if (no_of_bits <= 16)
132 {
133 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
134 pui16 = pui16DATA(data, pDescr->offset);
135 *pui16 = ui16;
136 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
137 }
138 else if (no_of_bits <= 32)
139 {
140 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
141 pui32 = pui32DATA(data, pDescr->offset);
142 *pui32 = ui32;
143 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
144 }
145 else
146 {
147 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
148 }
149 remaining_bits_len -= no_of_bits;
150 bit_offset += no_of_bits;
151 }
152 else if (pDescr->may_be_null)
153 {
154 if (no_of_bits <= 8)
155 {
156 pui8 = pui8DATA(data, pDescr->offset);
157 *pui8 = 0;
158 }
159 else if (no_of_bits <= 16)
160 {
161 pui16 = pui16DATA(data, pDescr->offset);
162 *pui16 = 0;
163 }
164 else if (no_of_bits <= 32)
165 {
166 pui32 = pui32DATA(data, pDescr->offset);
167 *pui32 = 0;
168 }
169 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
170 }
171 else
172 {
173 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
174 }
175
176 pDescr++;
177 break;
178 }
179
180 case CSN_UINT_OFFSET:
181 {
182 guint8 no_of_bits = (guint8) pDescr->i;
183
184 if (remaining_bits_len >= no_of_bits)
185 {
186 if (no_of_bits <= 8)
187 {
188 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
189 pui8 = pui8DATA(data, pDescr->offset);
190 *pui8 = ui8 + (guint8)pDescr->descr.value;
191 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
192 }
193 else if (no_of_bits <= 16)
194 {
195 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
196 pui16 = pui16DATA(data, pDescr->offset);
197 *pui16 = ui16 + (guint16)pDescr->descr.value;
198 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
199 }
200 else if (no_of_bits <= 32)
201 {
202 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
203 pui32 = pui32DATA(data, pDescr->offset);
204 *pui32 = ui32 + (guint16)pDescr->descr.value;
205 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
206 }
207 else
208 {
209 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
210 }
211 }
212 else
213 {
214 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
215 }
216
217 remaining_bits_len -= no_of_bits;
218 bit_offset += no_of_bits;
219 pDescr++;
220 break;
221 }
222
223 case CSN_UINT_LH:
224 {
225 guint8 no_of_bits = (guint8) pDescr->i;
226
227 if (remaining_bits_len >= no_of_bits)
228 {
229 if (no_of_bits <= 8)
230 {
231 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
232 pui8 = pui8DATA(data, pDescr->offset);
233 *pui8 = ui8;
234 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
235 }
236 else
237 {/* Maybe we should support more than 8 bits ? */
238 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
239 }
240 }
241 else
242 {
243 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
244 }
245
246 remaining_bits_len -= no_of_bits;
247 bit_offset += no_of_bits;
248 pDescr++;
249 break;
250 }
251
252 case CSN_UINT_ARRAY:
253 {
254 guint8 no_of_bits = (guint8) pDescr->i;
255 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
256
257 if (pDescr->value != 0)
258 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
259 nCount = *pui16DATA(data, nCount);
260 }
261
262 if (remaining_bits_len >= (no_of_bits * nCount))
263 {
264 remaining_bits_len -= (no_of_bits*nCount);
265 if (no_of_bits <= 8)
266 {
267 pui8 = pui8DATA(data, pDescr->offset);
268 do
269 {
270 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
271 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
272 pui8++;
273 bit_offset += no_of_bits;
274 } while (--nCount > 0);
275 }
276 else if (no_of_bits <= 16)
277 {
278 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
279 }
280 else if (no_of_bits <= 32)
281 {
282 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
283 }
284 else
285 {
286 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
287 }
288 }
289 else
290 {
291 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
292 }
293 pDescr++;
294 break;
295 }
296
297 case CSN_VARIABLE_TARRAY_OFFSET:
298 case CSN_VARIABLE_TARRAY:
299 case CSN_TYPE_ARRAY:
300 {
301 gint16 Status;
302 csnStream_t arT = *ar;
303 gint16 nCount = pDescr->i;
304 guint16 nSize = (guint16)(gint32)pDescr->value;
305
306 pui8 = pui8DATA(data, pDescr->offset);
307 if (pDescr->type == CSN_VARIABLE_TARRAY)
308 { /* Count specified in field */
309 nCount = *pui8DATA(data, pDescr->i);
310 }
311 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
312 { /* Count specified in field */
313 nCount = *pui8DATA(data, pDescr->i);
314 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
315 }
316
317 while (nCount > 0)
318 { /* resulting array of length 0 is possible
319 * but no bits shall be read from bitstream
320 */
321
322 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
323 csnStreamInit(&arT, bit_offset, remaining_bits_len);
324 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
325 if (Status >= 0)
326 {
327 pui8 += nSize;
328 remaining_bits_len = arT.remaining_bits_len;
329 bit_offset = arT.bit_offset;
330 }
331 else
332 {
333 return Status;
334 }
335 nCount--;
336 }
337
338 pDescr++;
339 break;
340 }
341
342 case CSN_BITMAP:
343 { /* bitmap with given length. The result is left aligned! */
344 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
345
346 if (no_of_bits > 0)
347 {
348 if (no_of_bits > remaining_bits_len)
349 {
350 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
351 }
352
353 if (no_of_bits <= 32)
354 {
355 for(ib = 0; ib < 4; ib++)
356 {
357 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
358 pui8 = pui8DATA(data, pDescr->offset+ib);
359 *pui8 = ui8;
360 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
361 }
362 }
363 else if (no_of_bits <= 64)
364 {
365 for(ib = 0; ib < 8; ib++)
366 {
367 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
368 pui8 = pui8DATA(data, pDescr->offset+ib);
369 *pui8 = ui8;
370 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
371 }
372 }
373 else
374 {
375 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
376 }
377
378 remaining_bits_len -= no_of_bits;
379 bit_offset += no_of_bits;
380 }
381 /* bitmap was successfully extracted or it was empty */
382
383 pDescr++;
384 break;
385 }
386
387 case CSN_TYPE:
388 {
389 gint16 Status;
390 csnStream_t arT = *ar;
391 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
392 csnStreamInit(&arT, bit_offset, remaining_bits_len);
393 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
394 LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
395 if (Status >= 0)
396 {
397 remaining_bits_len = arT.remaining_bits_len;
398 bit_offset = arT.bit_offset;
399 pDescr++;
400 }
401 else
402 {
403 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
404 return Status;
405 }
406
407 break;
408 }
409
410 case CSN_CHOICE:
411 {
412 gint16 count = pDescr->i;
413 guint8 i = 0;
414 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
415
416 /* Make sure that the list of choice items is not empty */
417 if (!count)
418 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
419 else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
420 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
421
422 while (count > 0)
423 {
424 guint8 no_of_bits = pChoice->bits;
425 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
426 if (value == pChoice->value)
427 {
428 CSN_DESCR descr[2];
429 gint16 Status;
430 csnStream_t arT = *ar;
431
432 descr[0] = pChoice->descr;
433 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
434 descr[1].type = CSN_END;
435 pui8 = pui8DATA(data, pDescr->offset);
436 *pui8 = i;
437 LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
438 if (!pChoice->keep_bits) {
439 bit_offset += no_of_bits;
440 remaining_bits_len -= no_of_bits;
441 }
442
443 csnStreamInit(&arT, bit_offset, remaining_bits_len);
444 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
445
446 if (Status >= 0)
447 {
448 remaining_bits_len = arT.remaining_bits_len;
449 bit_offset = arT.bit_offset;
450 }
451 else
452 {
453 return Status;
454 }
455 break;
456 }
457
458 *readIndex -= no_of_bits;
459 count--;
460 pChoice++;
461 i++;
462 }
463
464 /* Neither of the choice items matched => unknown value */
465 if (!count)
466 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
467
468 pDescr++;
469 break;
470 }
471
472 case CSN_SERIALIZE:
473 {
474 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
475 csnStream_t arT = *ar;
476 guint8 length_len = pDescr->i;
477 gint16 Status = -1;
478
479 guint8 length = bitvec_read_field(vector, readIndex, length_len);
480
481 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
482 bit_offset += length_len;
483 remaining_bits_len -= length_len;
484
485 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
486 arT.direction = 1;
487 LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
488 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
489
490 if (Status >= 0)
491 {
492 if (length > 0) {
493 remaining_bits_len -= length;
494 bit_offset += length;
495 } else {
496 remaining_bits_len = arT.remaining_bits_len;
497 bit_offset = arT.bit_offset;
498 }
499
500 /* Skip bits not handled by serialize(), if any */
501 if (Status > 0) {
502 LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
503 *readIndex += Status;
504 }
505
506 pDescr++;
507 }
508 else
509 {
510 /* Has already been processed: */
511 return Status;
512 }
513
514 break;
515 }
516
517 case CSN_UNION_LH:
518 case CSN_UNION:
519 {
520 gint16 Bits;
521 guint8 index;
522 gint16 count = pDescr->i;
523 const CSN_DESCR* pDescrNext = pDescr;
524
525 pDescrNext += count + 1; /* now this is next after the union */
526 if ((count <= 0) || (count > 16))
527 {
528 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
529 }
530
531 /* Now get the bits to extract the index */
532 Bits = ixBitsTab[count];
533 index = 0;
534
535 while (Bits > 0)
536 {
537 index <<= 1;
538
539 if (CSN_UNION_LH == pDescr->type)
540 {
541 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
542 }
543 else
544 {
545 index |= bitvec_read_field(vector, readIndex, 1);
546 }
547 remaining_bits_len--;
548 bit_offset++;
549 Bits--;
550 }
551
552 /* Assign UnionType */
553 pui8 = pui8DATA(data, pDescr->offset);
554 *pui8 = index;
555
556
557 /* script index to continue on, limited in case we do not have a power of 2 */
558 pDescr += (MIN(index + 1, count));
559 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
560
561 switch (pDescr->type)
562 { /* get the right element of the union based on computed index */
563
564 case CSN_BIT:
565 {
566 pui8 = pui8DATA(data, pDescr->offset);
567 *pui8 = 0x00;
568 if (bitvec_read_field(vector, readIndex, 1) > 0)
569 {
570 *pui8 = 0x01;
571 }
572 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
573 remaining_bits_len -= 1;
574 bit_offset++;
575 pDescr++;
576 break;
577 }
578
579 case CSN_NULL:
580 { /* Empty member! */
581 bit_offset += pDescr->i;
582 pDescr++;
583 break;
584 }
585
586 case CSN_UINT:
587 {
588 guint8 no_of_bits = (guint8) pDescr->i;
589 if (remaining_bits_len >= no_of_bits)
590 {
591 if (no_of_bits <= 8)
592 {
593 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
594 pui8 = pui8DATA(data, pDescr->offset);
595 *pui8 = ui8;
596 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
597 }
598 else if (no_of_bits <= 16)
599 {
600 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
601 pui16 = pui16DATA(data, pDescr->offset);
602 *pui16 = ui16;
603 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
604 }
605 else if (no_of_bits <= 32)
606 {
607 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
608 pui32 = pui32DATA(data, pDescr->offset);
609 *pui32 = ui32;
610 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
611 }
612 else
613 {
614 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
615 }
616 }
617 else
618 {
619 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
620 }
621
622 remaining_bits_len -= no_of_bits;
623 bit_offset += no_of_bits;
624 pDescr++;
625 break;
626 }
627
628 case CSN_UINT_OFFSET:
629 {
630 guint8 no_of_bits = (guint8) pDescr->i;
631
632 if (remaining_bits_len >= no_of_bits)
633 {
634 if (no_of_bits <= 8)
635 {
636 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
637 pui8 = pui8DATA(data, pDescr->offset);
638 *pui8 = ui8 + (guint8)pDescr->descr.value;
639 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
640 }
641 else if (no_of_bits <= 16)
642 {
643 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
644 pui16 = pui16DATA(data, pDescr->offset);
645 *pui16 = ui16 + (guint16)pDescr->descr.value;
646 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
647 }
648 else if (no_of_bits <= 32)
649 {
650 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
651 pui32 = pui32DATA(data, pDescr->offset);
652 *pui32 = ui32 + (guint16)pDescr->descr.value;
653 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
654 }
655 else
656 {
657 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
658 }
659 }
660 else
661 {
662 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
663 }
664
665 remaining_bits_len -= no_of_bits;
666 bit_offset += no_of_bits;
667 pDescr++;
668 break;
669 }
670
671 case CSN_UINT_LH:
672 {
673 guint8 no_of_bits = (guint8) pDescr->i;
674
675 if (remaining_bits_len >= no_of_bits)
676 {
677 if (no_of_bits <= 8)
678 {
679 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
680 pui8 = pui8DATA(data, pDescr->offset);
681 *pui8 = ui8;
682 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
683 }
684 else
685 { /* Maybe we should support more than 8 bits ? */
686 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
687 }
688 }
689 else
690 {
691 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
692 }
693
694 remaining_bits_len -= no_of_bits;
695 bit_offset += no_of_bits;
696 pDescr++;
697 break;
698 }
699
700 case CSN_UINT_ARRAY:
701 {
702 guint8 no_of_bits = (guint8) pDescr->i;
703 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
704
705 if (pDescr->value != 0)
706 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
707 nCount = *pui16DATA(data, nCount);
708 }
709
710 if (remaining_bits_len >= (no_of_bits * nCount))
711 {
712 remaining_bits_len -= (no_of_bits * nCount);
713 if (no_of_bits <= 8)
714 {
715 pui8 = pui8DATA(data, pDescr->offset);
716
717 while (nCount > 0)
718 {
719 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
720 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
721 pui8++;
722 bit_offset += no_of_bits;
723 nCount--;
724 }
725 }
726 else if (no_of_bits <= 16)
727 {
728 pui16 = pui16DATA(data, pDescr->offset);
729
730 while (nCount > 0)
731 {
732 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
733 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
734 pui16++;
735 bit_offset += no_of_bits;
736 nCount--;
737 }
738 }
739 else if (no_of_bits <= 32)
740 { /* not supported */
741 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
742 }
743 else
744 {
745 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
746 }
747 }
748 else
749 {
750 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
751 }
752
753 pDescr++;
754 break;
755 }
756
757 case CSN_VARIABLE_TARRAY_OFFSET:
758 case CSN_VARIABLE_TARRAY:
759 case CSN_TYPE_ARRAY:
760 {
761 gint16 Status;
762 csnStream_t arT = *ar;
763 guint16 nCount = (guint16) pDescr->i;
764 guint16 nSize = (guint16)(guint32)pDescr->value;
765
766 pui8 = pui8DATA(data, pDescr->offset);
767
768 if (CSN_VARIABLE_TARRAY == pDescr->type)
769 { /* Count specified in field */
770 nCount = *pui8DATA(data, pDescr->i);
771 }
772 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
773 { /* Count specified in field */
774 nCount = *pui8DATA(data, pDescr->i);
775 nCount--; /* Offset 1 */
776 }
777
778 while (nCount--) /* Changed to handle length = 0. */
779 {
780 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
781 csnStreamInit(&arT, bit_offset, remaining_bits_len);
782 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
783 if (Status >= 0)
784 {
785 pui8 += nSize;
786 remaining_bits_len = arT.remaining_bits_len;
787 bit_offset = arT.bit_offset;
788 }
789 else
790 {
791 return Status;
792 }
793 }
794
795 pDescr++;
796 break;
797 }
798
799 case CSN_BITMAP:
800 { /* bitmap with given length. The result is left aligned! */
801 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
802
803 if (no_of_bits > 0)
804 {
805 if (no_of_bits > remaining_bits_len)
806 {
807 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
808 }
809
810 if (no_of_bits <= 32)
811 {
812 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
813 pui32 = pui32DATA(data, pDescr->offset);
814 *pui32 = ui32;
815 }
816 else if (no_of_bits <= 64)
817 {
818 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
819 pui64 = pui64DATA(data, pDescr->offset);
820 *pui64 = ui64;
821 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
822 }
823 else
824 {
825 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
826 }
827
828 remaining_bits_len -= no_of_bits;
829 bit_offset += no_of_bits;
830 }
831 /* bitmap was successfully extracted or it was empty */
832
833 pDescr++;
834 break;
835 }
836
837 case CSN_TYPE:
838 {
839 gint16 Status;
840 csnStream_t arT = *ar;
841 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
842 csnStreamInit(&arT, bit_offset, remaining_bits_len);
843 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
844 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
845 if (Status >= 0)
846 {
847 remaining_bits_len = arT.remaining_bits_len;
848 bit_offset = arT.bit_offset;
849 pDescr++;
850 }
851 else
852 { /* return error code Has already been processed: */
853 return Status;
854 }
855
856 break;
857 }
858
859 default:
860 { /* descriptions of union elements other than above are illegal */
861 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
862 }
863 }
864
865 pDescr = pDescrNext;
866 break;
867 }
868
869 case CSN_EXIST:
870 case CSN_EXIST_LH:
871 {
872 guint8 fExist;
873
874 pui8 = pui8DATA(data, pDescr->offset);
875
876 if (CSN_EXIST_LH == pDescr->type)
877 {
878 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
879 }
880 else
881 {
882 fExist = bitvec_read_field(vector, readIndex, 1);
883 }
884
885 *pui8 = fExist;
886 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
887 pDescr++;
888 bit_offset++;
889 remaining_bits_len -= 1;
890
891 if (!fExist)
892 {
893 ar->remaining_bits_len = remaining_bits_len;
894 ar->bit_offset = bit_offset;
895 return remaining_bits_len;
896 }
897
898 break;
899 }
900
901 case CSN_NEXT_EXIST:
902 {
903 guint8 fExist;
904
905 pui8 = pui8DATA(data, pDescr->offset);
906
907 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
908 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
909 { /* no more bits to decode is fine here - end of message detected and allowed */
910
911 /* Skip i entries + this entry */
912 pDescr += pDescr->i + 1;
913
914 /* Set the data member to "not exist" */
915 *pui8 = 0;
916 break;
917 }
918
919 /* the "regular" M_NEXT_EXIST description element */
920
921 fExist = 0x00;
922 if (bitvec_read_field(vector, readIndex, 1))
923 {
924 fExist = 0x01;
925 }
926
927 *pui8 = fExist;
928 remaining_bits_len -= 1;
929 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
930 ++bit_offset;
931
932 if (fExist == 0)
933 { /* Skip 'i' entries */
934 pDescr += pDescr->i;
935 }
936
937 pDescr++;
938 break;
939 }
940
941 case CSN_NEXT_EXIST_LH:
942 {
943 guint8 fExist;
944 pui8 = pui8DATA(data, pDescr->offset);
945
946 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
947 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
948 { /* no more bits to decode is fine here - end of message detected and allowed */
949
950 /* skip 'i' entries + this entry */
951 pDescr += pDescr->i + 1;
952
953 /* set the data member to "not exist" */
954 *pui8 = 0;
955 break;
956 }
957
958 /* the "regular" M_NEXT_EXIST_LH description element */
959 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
960 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
961 *pui8++ = fExist;
962 remaining_bits_len -= 1;
963
964 bit_offset++;
965
966 if (fExist == 0)
967 { /* Skip 'i' entries */
968 pDescr += pDescr->i;
969 }
970 pDescr++;
971
972 break;
973 }
974
975 case CSN_VARIABLE_BITMAP_1:
976 { /* Bitmap from here and to the end of message */
977
978 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
979
980 /*no break -
981 * with a length set we have a regular variable length bitmap so we continue */
982 }
983 /* FALL THROUGH */
984 case CSN_VARIABLE_BITMAP:
985 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
986 * <N: bit (5)> <bitmap: bit(N + offset)>
987 * Bit array with length (in bits) specified in parameter (pDescr->descr)
988 * The result is right aligned!
989 */
990 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
991
992 no_of_bits += pDescr->i; /* adjusted by offset */
993
994 if (no_of_bits > 0)
995 {
996 remaining_bits_len -= no_of_bits;
997
998 if (remaining_bits_len < 0)
999 {
1000 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1001 }
1002
1003 { /* extract bits */
1004 guint8* pui8 = pui8DATA(data, pDescr->offset);
1005 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1006
1007 if (nB1 > 0)
1008 { /* take care of the first byte - it will be right aligned */
1009 *pui8 = bitvec_read_field(vector, readIndex, nB1);
1010 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1011 pui8++;
1012 no_of_bits -= nB1;
1013 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1014 }
1015
1016 /* remaining no_of_bits is a multiple of 8 or 0 */
1017 while (no_of_bits > 0)
1018 {
1019 *pui8 = bitvec_read_field(vector, readIndex, 8);
1020 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1021 pui8++;
1022 no_of_bits -= 8;
1023 }
1024 }
1025 }
1026 pDescr++;
1027 break;
1028 }
1029
1030 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1031 { /* Bitmap from here and to the end of message */
1032
1033 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1034
1035 /* no break -
1036 * with a length set we have a regular left aligned variable length bitmap so we continue
1037 */
1038 }
1039 /* FALL THROUGH */
1040 case CSN_LEFT_ALIGNED_VAR_BMP:
1041 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1042 * <N: bit (5)> <bitmap: bit(N + offset)>
1043 * bit array with length (in bits) specified in parameter (pDescr->descr)
1044 */
1045 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1046
1047 no_of_bits += pDescr->i;/* size adjusted by offset */
1048
1049 if (no_of_bits > 0)
1050 {
1051 remaining_bits_len -= no_of_bits;
1052
1053 if (remaining_bits_len < 0)
1054 {
1055 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1056 }
1057
1058 { /* extract bits */
1059 guint8* pui8 = pui8DATA(data, pDescr->offset);
1060
1061 while (no_of_bits >= 8)
1062 {
1063 *pui8 = bitvec_read_field(vector, readIndex, 8);
1064 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1065 pui8++;
1066 no_of_bits -= 8;
1067 }
1068 if (no_of_bits > 0)
1069 {
1070 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
1071 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1072 pui8++;
1073 bit_offset += no_of_bits;
1074 no_of_bits = 0;
1075 }
1076 }
1077 }
1078
1079 /* bitmap was successfully extracted or it was empty */
1080 pDescr++;
1081 break;
1082 }
1083
1084 case CSN_PADDING_BITS:
1085 { /* Padding from here and to the end of message */
1086 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
1087 if (remaining_bits_len > 0)
1088 {
1089 while (remaining_bits_len > 0)
1090 {
1091 guint bits_to_handle = remaining_bits_len%8;
1092 if (bits_to_handle > 0)
1093 {
1094 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
1095 remaining_bits_len -= bits_to_handle;
1096 bit_offset += bits_to_handle;
1097 }
1098 else if (bits_to_handle == 0)
1099 {
1100 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
1101 remaining_bits_len -= 8;
1102 bit_offset += 8;
1103 }
1104 }
1105 }
1106 if (remaining_bits_len < 0)
1107 {
1108 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1109 }
1110
1111 /* Padding was successfully extracted or it was empty */
1112 pDescr++;
1113 break;
1114 }
1115
1116 case CSN_VARIABLE_ARRAY:
1117 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1118 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1119 * Array with length specified in parameter:
1120 * <count: bit (x)>
1121 * <list: octet(count + offset)>
1122 */
1123 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1124
1125 count += pDescr->i; /* Adjusted by offset */
1126
1127 if (count > 0)
1128 {
1129 remaining_bits_len -= count * 8;
1130
1131 if (remaining_bits_len < 0)
1132 {
1133 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1134 }
1135
1136 pui8 = pui8DATA(data, pDescr->offset);
1137
1138 while (count > 0)
1139 {
1140 *pui8 = bitvec_read_field(vector, readIndex, 8);
1141 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
1142 pui8++;
1143 bit_offset += 8;
1144 count--;
1145 }
1146 }
1147
1148 pDescr++;
1149 break;
1150 }
1151
1152 case CSN_RECURSIVE_ARRAY:
1153 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1154 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1155 * where <element> ::= bit(value)
1156 * <tag> ::= 0 | 1
1157 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1158 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1159 * REMARK: recursive way to specify an array but an iterative implementation!
1160 */
1161 gint16 no_of_bits = pDescr->i;
1162 guint8 ElementCount = 0;
1163
1164 pui8 = pui8DATA(data, pDescr->offset);
1165
1166 while (existNextElement(vector, readIndex, Tag))
1167 { /* tag control shows existence of next list elements */
1168 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
1169 bit_offset++;
1170 remaining_bits_len--;
1171
1172 /* extract and store no_of_bits long element from bitstream */
1173 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
1174 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1175 pui8++;
1176 remaining_bits_len -= no_of_bits;
1177 ElementCount++;
1178
1179 if (remaining_bits_len < 0)
1180 {
1181 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1182 }
1183
1184 bit_offset += no_of_bits;
1185 }
1186
1187 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
1188 /* existNextElement() returned FALSE, 1 bit consumed */
1189 bit_offset++;
1190 remaining_bits_len--;
1191
1192 /* Store the counted number of elements of the array */
1193 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1194
1195 pDescr++;
1196 break;
1197 }
1198
1199 case CSN_RECURSIVE_TARRAY:
1200 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1201 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1202 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
1203 */
1204 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
1205 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
1206 guint8 ElementCount = 0;
1207 pui8 = pui8DATA(data, pDescr->offset);
1208
1209 while (existNextElement(vector, readIndex, Tag))
1210 { /* tag control shows existence of next list elements */
1211 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
1212 /* existNextElement() returned TRUE, 1 bit consumed */
1213 bit_offset++;
1214 remaining_bits_len--;
1215 ElementCount++;
1216
1217 if (ElementCount > nSizeArray)
1218 {
1219 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1220 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1221 }
1222
1223 { /* unpack the following data structure */
1224 csnStream_t arT = *ar;
1225 gint16 Status;
1226 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1227 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
1228
1229 if (Status >= 0)
1230 { /* successful completion */
1231 pui8 += nSizeElement; /* -> to next data element */
1232 remaining_bits_len = arT.remaining_bits_len;
1233 bit_offset = arT.bit_offset;
1234 }
1235 else
1236 { /* something went awry */
1237 return Status;
1238 }
1239 }
1240
1241 if (remaining_bits_len < 0)
1242 {
1243 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1244 }
1245 }
1246
1247 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
1248
1249 /* existNextElement() returned FALSE, 1 bit consumed */
1250 remaining_bits_len--;
1251 bit_offset++;
1252
1253 /* Store the counted number of elements of the array */
1254 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1255
1256 pDescr++;
1257 break;
1258 }
1259
1260 case CSN_RECURSIVE_TARRAY_2:
1261 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1262
1263 Tag = REVERSED_TAG;
1264
1265 /* NO break -
1266 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1267 */
1268 }
1269 /* FALL THROUGH */
1270 case CSN_RECURSIVE_TARRAY_1:
1271 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1272 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1273 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
1274 */
1275 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
1276 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
1277 guint8 ElementCount = 0;
1278 csnStream_t arT = *ar;
1279 gboolean EndOfList = FALSE;
1280 gint16 Status;
1281 pui8 = pui8DATA(data, pDescr->offset);
1282
1283 do
1284 { /* get data element */
1285 ElementCount++;
1286
1287 if (ElementCount > nSizeArray)
1288 {
1289 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1290 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1291 }
1292
1293 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
1294
1295 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1296 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
1297
1298 if (Status >= 0)
1299 { /* successful completion */
1300 pui8 += nSizeElement; /* -> to next */
1301 remaining_bits_len = arT.remaining_bits_len;
1302 bit_offset = arT.bit_offset;
1303 }
1304 else
1305 { /* something went awry */
1306 return Status;
1307 }
1308
1309 if (remaining_bits_len < 0)
1310 {
1311 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1312 }
1313
1314 /* control of next element's tag */
1315 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
1316 EndOfList = !(existNextElement(vector, readIndex, Tag));
1317
1318 bit_offset++;
1319 remaining_bits_len--; /* 1 bit consumed (tag) */
1320 } while (!EndOfList);
1321
1322
1323 /* Store the count of the array */
1324 *pui8DATA(data, pDescr->i) = ElementCount;
1325 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1326 pDescr++;
1327 break;
1328 }
1329
1330 case CSN_FIXED:
1331 { /* Verify the fixed bits */
1332 guint8 no_of_bits = (guint8) pDescr->i;
1333 guint32 ui32;
1334
1335 if (no_of_bits <= 32)
1336 {
1337 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
1338 }
1339 else
1340 {
1341 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1342 }
1343 if (ui32 != (unsigned)(gint32)pDescr->offset)
1344 {
1345 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1346 }
1347
1348 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
1349 remaining_bits_len -= no_of_bits;
1350 bit_offset += no_of_bits;
1351 pDescr++;
1352 break;
1353 }
1354
1355 case CSN_CALLBACK:
1356 {
1357 guint16 no_of_bits;
1358 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1359 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
1360 no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
1361 remaining_bits_len -= no_of_bits;
1362 bit_offset += no_of_bits;
1363 pDescr++;
1364 break;
1365 }
1366
1367 case CSN_TRAP_ERROR:
1368 {
1369 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1370 }
1371
1372 case CSN_END:
1373 {
1374 ar->remaining_bits_len = remaining_bits_len;
1375 ar->bit_offset = bit_offset;
1376 return remaining_bits_len;
1377 }
1378
1379 default:
1380 {
1381 assert(0);
1382 }
1383
1384
1385 }
1386
1387 } while (remaining_bits_len >= 0);
1388
1389 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1390}