blob: 6892dde211c52ef92db19b15c774224aba0ac944 [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;
Pau Espin Pedrolebdc0d82021-10-19 16:48:16 +0200391 if (pDescr->may_be_null && remaining_bits_len == 0)
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200392 {
Pau Espin Pedrolebdc0d82021-10-19 16:48:16 +0200393 LOGPC(DCSN1, LOGL_DEBUG, " : %s = NULL | ", pDescr->sz);
394 } else {
395 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
396 csnStreamInit(&arT, bit_offset, remaining_bits_len);
397 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
398 LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
399 if (Status >= 0)
400 {
401 remaining_bits_len = arT.remaining_bits_len;
402 bit_offset = arT.bit_offset;
403 }
404 else
405 {
406 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
407 return Status;
408 }
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200409 }
Pau Espin Pedrolebdc0d82021-10-19 16:48:16 +0200410 pDescr++;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200411 break;
412 }
413
414 case CSN_CHOICE:
415 {
416 gint16 count = pDescr->i;
417 guint8 i = 0;
418 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
419
420 /* Make sure that the list of choice items is not empty */
421 if (!count)
422 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
423 else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
424 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
425
426 while (count > 0)
427 {
428 guint8 no_of_bits = pChoice->bits;
429 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
430 if (value == pChoice->value)
431 {
432 CSN_DESCR descr[2];
433 gint16 Status;
434 csnStream_t arT = *ar;
435
436 descr[0] = pChoice->descr;
437 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
438 descr[1].type = CSN_END;
439 pui8 = pui8DATA(data, pDescr->offset);
440 *pui8 = i;
441 LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
442 if (!pChoice->keep_bits) {
443 bit_offset += no_of_bits;
444 remaining_bits_len -= no_of_bits;
445 }
446
447 csnStreamInit(&arT, bit_offset, remaining_bits_len);
448 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
449
450 if (Status >= 0)
451 {
452 remaining_bits_len = arT.remaining_bits_len;
453 bit_offset = arT.bit_offset;
454 }
455 else
456 {
457 return Status;
458 }
459 break;
460 }
461
462 *readIndex -= no_of_bits;
463 count--;
464 pChoice++;
465 i++;
466 }
467
468 /* Neither of the choice items matched => unknown value */
469 if (!count)
470 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
471
472 pDescr++;
473 break;
474 }
475
476 case CSN_SERIALIZE:
477 {
478 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
479 csnStream_t arT = *ar;
480 guint8 length_len = pDescr->i;
481 gint16 Status = -1;
482
483 guint8 length = bitvec_read_field(vector, readIndex, length_len);
484
485 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
486 bit_offset += length_len;
487 remaining_bits_len -= length_len;
488
489 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
490 arT.direction = 1;
491 LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
492 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
493
494 if (Status >= 0)
495 {
496 if (length > 0) {
497 remaining_bits_len -= length;
498 bit_offset += length;
499 } else {
500 remaining_bits_len = arT.remaining_bits_len;
501 bit_offset = arT.bit_offset;
502 }
503
504 /* Skip bits not handled by serialize(), if any */
505 if (Status > 0) {
506 LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
507 *readIndex += Status;
508 }
509
510 pDescr++;
511 }
512 else
513 {
514 /* Has already been processed: */
515 return Status;
516 }
517
518 break;
519 }
520
521 case CSN_UNION_LH:
522 case CSN_UNION:
523 {
524 gint16 Bits;
525 guint8 index;
526 gint16 count = pDescr->i;
527 const CSN_DESCR* pDescrNext = pDescr;
528
529 pDescrNext += count + 1; /* now this is next after the union */
530 if ((count <= 0) || (count > 16))
531 {
532 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
533 }
534
535 /* Now get the bits to extract the index */
536 Bits = ixBitsTab[count];
537 index = 0;
538
539 while (Bits > 0)
540 {
541 index <<= 1;
542
543 if (CSN_UNION_LH == pDescr->type)
544 {
545 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
546 }
547 else
548 {
549 index |= bitvec_read_field(vector, readIndex, 1);
550 }
551 remaining_bits_len--;
552 bit_offset++;
553 Bits--;
554 }
555
556 /* Assign UnionType */
557 pui8 = pui8DATA(data, pDescr->offset);
558 *pui8 = index;
559
560
561 /* script index to continue on, limited in case we do not have a power of 2 */
562 pDescr += (MIN(index + 1, count));
563 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
564
565 switch (pDescr->type)
566 { /* get the right element of the union based on computed index */
567
568 case CSN_BIT:
569 {
570 pui8 = pui8DATA(data, pDescr->offset);
571 *pui8 = 0x00;
572 if (bitvec_read_field(vector, readIndex, 1) > 0)
573 {
574 *pui8 = 0x01;
575 }
576 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
577 remaining_bits_len -= 1;
578 bit_offset++;
579 pDescr++;
580 break;
581 }
582
583 case CSN_NULL:
584 { /* Empty member! */
585 bit_offset += pDescr->i;
586 pDescr++;
587 break;
588 }
589
590 case CSN_UINT:
591 {
592 guint8 no_of_bits = (guint8) pDescr->i;
593 if (remaining_bits_len >= no_of_bits)
594 {
595 if (no_of_bits <= 8)
596 {
597 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
598 pui8 = pui8DATA(data, pDescr->offset);
599 *pui8 = ui8;
600 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
601 }
602 else if (no_of_bits <= 16)
603 {
604 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
605 pui16 = pui16DATA(data, pDescr->offset);
606 *pui16 = ui16;
607 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
608 }
609 else if (no_of_bits <= 32)
610 {
611 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
612 pui32 = pui32DATA(data, pDescr->offset);
613 *pui32 = ui32;
614 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
615 }
616 else
617 {
618 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
619 }
620 }
621 else
622 {
623 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
624 }
625
626 remaining_bits_len -= no_of_bits;
627 bit_offset += no_of_bits;
628 pDescr++;
629 break;
630 }
631
632 case CSN_UINT_OFFSET:
633 {
634 guint8 no_of_bits = (guint8) pDescr->i;
635
636 if (remaining_bits_len >= no_of_bits)
637 {
638 if (no_of_bits <= 8)
639 {
640 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
641 pui8 = pui8DATA(data, pDescr->offset);
642 *pui8 = ui8 + (guint8)pDescr->descr.value;
643 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
644 }
645 else if (no_of_bits <= 16)
646 {
647 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
648 pui16 = pui16DATA(data, pDescr->offset);
649 *pui16 = ui16 + (guint16)pDescr->descr.value;
650 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
651 }
652 else if (no_of_bits <= 32)
653 {
654 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
655 pui32 = pui32DATA(data, pDescr->offset);
656 *pui32 = ui32 + (guint16)pDescr->descr.value;
657 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
658 }
659 else
660 {
661 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
662 }
663 }
664 else
665 {
666 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
667 }
668
669 remaining_bits_len -= no_of_bits;
670 bit_offset += no_of_bits;
671 pDescr++;
672 break;
673 }
674
675 case CSN_UINT_LH:
676 {
677 guint8 no_of_bits = (guint8) pDescr->i;
678
679 if (remaining_bits_len >= no_of_bits)
680 {
681 if (no_of_bits <= 8)
682 {
683 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
684 pui8 = pui8DATA(data, pDescr->offset);
685 *pui8 = ui8;
686 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
687 }
688 else
689 { /* Maybe we should support more than 8 bits ? */
690 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
691 }
692 }
693 else
694 {
695 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
696 }
697
698 remaining_bits_len -= no_of_bits;
699 bit_offset += no_of_bits;
700 pDescr++;
701 break;
702 }
703
704 case CSN_UINT_ARRAY:
705 {
706 guint8 no_of_bits = (guint8) pDescr->i;
707 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
708
709 if (pDescr->value != 0)
710 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
711 nCount = *pui16DATA(data, nCount);
712 }
713
714 if (remaining_bits_len >= (no_of_bits * nCount))
715 {
716 remaining_bits_len -= (no_of_bits * nCount);
717 if (no_of_bits <= 8)
718 {
719 pui8 = pui8DATA(data, pDescr->offset);
720
721 while (nCount > 0)
722 {
723 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
724 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
725 pui8++;
726 bit_offset += no_of_bits;
727 nCount--;
728 }
729 }
730 else if (no_of_bits <= 16)
731 {
732 pui16 = pui16DATA(data, pDescr->offset);
733
734 while (nCount > 0)
735 {
736 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
737 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
738 pui16++;
739 bit_offset += no_of_bits;
740 nCount--;
741 }
742 }
743 else if (no_of_bits <= 32)
744 { /* not supported */
745 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
746 }
747 else
748 {
749 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
750 }
751 }
752 else
753 {
754 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
755 }
756
757 pDescr++;
758 break;
759 }
760
761 case CSN_VARIABLE_TARRAY_OFFSET:
762 case CSN_VARIABLE_TARRAY:
763 case CSN_TYPE_ARRAY:
764 {
765 gint16 Status;
766 csnStream_t arT = *ar;
767 guint16 nCount = (guint16) pDescr->i;
768 guint16 nSize = (guint16)(guint32)pDescr->value;
769
770 pui8 = pui8DATA(data, pDescr->offset);
771
772 if (CSN_VARIABLE_TARRAY == pDescr->type)
773 { /* Count specified in field */
774 nCount = *pui8DATA(data, pDescr->i);
775 }
776 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
777 { /* Count specified in field */
778 nCount = *pui8DATA(data, pDescr->i);
779 nCount--; /* Offset 1 */
780 }
781
782 while (nCount--) /* Changed to handle length = 0. */
783 {
784 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
785 csnStreamInit(&arT, bit_offset, remaining_bits_len);
786 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
787 if (Status >= 0)
788 {
789 pui8 += nSize;
790 remaining_bits_len = arT.remaining_bits_len;
791 bit_offset = arT.bit_offset;
792 }
793 else
794 {
795 return Status;
796 }
797 }
798
799 pDescr++;
800 break;
801 }
802
803 case CSN_BITMAP:
804 { /* bitmap with given length. The result is left aligned! */
805 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
806
807 if (no_of_bits > 0)
808 {
809 if (no_of_bits > remaining_bits_len)
810 {
811 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
812 }
813
814 if (no_of_bits <= 32)
815 {
816 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
817 pui32 = pui32DATA(data, pDescr->offset);
818 *pui32 = ui32;
819 }
820 else if (no_of_bits <= 64)
821 {
822 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
823 pui64 = pui64DATA(data, pDescr->offset);
824 *pui64 = ui64;
825 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
826 }
827 else
828 {
829 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
830 }
831
832 remaining_bits_len -= no_of_bits;
833 bit_offset += no_of_bits;
834 }
835 /* bitmap was successfully extracted or it was empty */
836
837 pDescr++;
838 break;
839 }
840
841 case CSN_TYPE:
842 {
843 gint16 Status;
844 csnStream_t arT = *ar;
Pau Espin Pedrolebdc0d82021-10-19 16:48:16 +0200845 if (pDescr->may_be_null && remaining_bits_len == 0)
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200846 {
Pau Espin Pedrolebdc0d82021-10-19 16:48:16 +0200847 LOGPC(DCSN1, LOGL_DEBUG, " : %s = NULL | ", pDescr->sz);
848 } else {
849 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
850 csnStreamInit(&arT, bit_offset, remaining_bits_len);
851 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
852 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
853 if (Status >= 0)
854 {
855 remaining_bits_len = arT.remaining_bits_len;
856 bit_offset = arT.bit_offset;
857 }
858 else
859 { /* return error code Has already been processed: */
860 return Status;
861 }
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200862 }
Pau Espin Pedrolebdc0d82021-10-19 16:48:16 +0200863 pDescr++;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200864 break;
865 }
866
867 default:
868 { /* descriptions of union elements other than above are illegal */
869 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
870 }
871 }
872
873 pDescr = pDescrNext;
874 break;
875 }
876
877 case CSN_EXIST:
878 case CSN_EXIST_LH:
879 {
880 guint8 fExist;
881
882 pui8 = pui8DATA(data, pDescr->offset);
883
884 if (CSN_EXIST_LH == pDescr->type)
885 {
886 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
887 }
888 else
889 {
890 fExist = bitvec_read_field(vector, readIndex, 1);
891 }
892
893 *pui8 = fExist;
894 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
895 pDescr++;
896 bit_offset++;
897 remaining_bits_len -= 1;
898
899 if (!fExist)
900 {
901 ar->remaining_bits_len = remaining_bits_len;
902 ar->bit_offset = bit_offset;
903 return remaining_bits_len;
904 }
905
906 break;
907 }
908
909 case CSN_NEXT_EXIST:
910 {
911 guint8 fExist;
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200912 guint8 isnull;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200913
914 pui8 = pui8DATA(data, pDescr->offset);
915
916 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
917 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
918 { /* no more bits to decode is fine here - end of message detected and allowed */
919
920 /* Skip i entries + this entry */
921 pDescr += pDescr->i + 1;
922
923 /* Set the data member to "not exist" */
924 *pui8 = 0;
925 break;
926 }
927
928 /* the "regular" M_NEXT_EXIST description element */
929
930 fExist = 0x00;
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200931 isnull = 1;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200932 if (bitvec_read_field(vector, readIndex, 1))
933 {
934 fExist = 0x01;
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200935 if (remaining_bits_len == 1) {
936 /* If { 1 < end > } and all next items may be null, store it as { 0 } */
937 const CSN_DESCR* pDescrNext = pDescr + 1;
938 guint8 i;
939 for (i = 0; i < pDescr->i; i++, pDescrNext++)
940 {
941 if (!pDescrNext->may_be_null)
942 isnull = 0;
943 }
944 } else {
945 isnull = 0;
946 }
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200947 }
948
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200949 *pui8 = !isnull;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200950 remaining_bits_len -= 1;
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200951 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u%s | ", pDescr->sz, (unsigned)fExist, fExist && isnull ? " (NULL)" : "");
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200952 ++bit_offset;
953
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200954 if (isnull)
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200955 { /* Skip 'i' entries */
956 pDescr += pDescr->i;
957 }
958
959 pDescr++;
960 break;
961 }
962
963 case CSN_NEXT_EXIST_LH:
964 {
965 guint8 fExist;
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200966 guint8 isnull;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +0200967 pui8 = pui8DATA(data, pDescr->offset);
968
969 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
970 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
971 { /* no more bits to decode is fine here - end of message detected and allowed */
972
973 /* skip 'i' entries + this entry */
974 pDescr += pDescr->i + 1;
975
976 /* set the data member to "not exist" */
977 *pui8 = 0;
978 break;
979 }
980
981 /* the "regular" M_NEXT_EXIST_LH description element */
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +0200982 isnull = 1;
983 if ((fExist = get_masked_bits8(vector, readIndex, bit_offset, 1)))
984 {
985 if (remaining_bits_len == 1) {
986 /* If { 1 < end > } and all next items may be null, store it as { 0 } */
987 const CSN_DESCR* pDescrNext = pDescr + 1;
988 guint8 i;
989 for (i = 0; i < pDescr->i; i++, pDescrNext++)
990 {
991 if (!pDescrNext->may_be_null)
992 isnull = 0;
993 }
994 } else {
995 isnull = 0;
996 }
997 }
998 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u%s | ", pDescr->sz , (unsigned)fExist, fExist && isnull ? " (NULL)" : "");
Pau Espin Pedrol9ecdc112021-10-20 17:21:34 +0200999 *pui8++ = !isnull;
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +02001000 remaining_bits_len -= 1;
1001
1002 bit_offset++;
1003
Pau Espin Pedrol1859ec32021-10-19 17:39:03 +02001004 if (isnull)
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +02001005 { /* Skip 'i' entries */
1006 pDescr += pDescr->i;
1007 }
1008 pDescr++;
1009
1010 break;
1011 }
1012
1013 case CSN_VARIABLE_BITMAP_1:
1014 { /* Bitmap from here and to the end of message */
1015
1016 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1017
1018 /*no break -
1019 * with a length set we have a regular variable length bitmap so we continue */
1020 }
1021 /* FALL THROUGH */
1022 case CSN_VARIABLE_BITMAP:
1023 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1024 * <N: bit (5)> <bitmap: bit(N + offset)>
1025 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1026 * The result is right aligned!
1027 */
1028 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1029
1030 no_of_bits += pDescr->i; /* adjusted by offset */
1031
1032 if (no_of_bits > 0)
1033 {
1034 remaining_bits_len -= no_of_bits;
1035
1036 if (remaining_bits_len < 0)
1037 {
1038 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1039 }
1040
1041 { /* extract bits */
1042 guint8* pui8 = pui8DATA(data, pDescr->offset);
1043 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1044
1045 if (nB1 > 0)
1046 { /* take care of the first byte - it will be right aligned */
1047 *pui8 = bitvec_read_field(vector, readIndex, nB1);
1048 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1049 pui8++;
1050 no_of_bits -= nB1;
1051 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1052 }
1053
1054 /* remaining no_of_bits is a multiple of 8 or 0 */
1055 while (no_of_bits > 0)
1056 {
1057 *pui8 = bitvec_read_field(vector, readIndex, 8);
1058 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1059 pui8++;
1060 no_of_bits -= 8;
1061 }
1062 }
1063 }
1064 pDescr++;
1065 break;
1066 }
1067
1068 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1069 { /* Bitmap from here and to the end of message */
1070
1071 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1072
1073 /* no break -
1074 * with a length set we have a regular left aligned variable length bitmap so we continue
1075 */
1076 }
1077 /* FALL THROUGH */
1078 case CSN_LEFT_ALIGNED_VAR_BMP:
1079 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1080 * <N: bit (5)> <bitmap: bit(N + offset)>
1081 * bit array with length (in bits) specified in parameter (pDescr->descr)
1082 */
1083 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1084
1085 no_of_bits += pDescr->i;/* size adjusted by offset */
1086
1087 if (no_of_bits > 0)
1088 {
1089 remaining_bits_len -= no_of_bits;
1090
1091 if (remaining_bits_len < 0)
1092 {
1093 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1094 }
1095
1096 { /* extract bits */
1097 guint8* pui8 = pui8DATA(data, pDescr->offset);
1098
1099 while (no_of_bits >= 8)
1100 {
1101 *pui8 = bitvec_read_field(vector, readIndex, 8);
1102 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1103 pui8++;
1104 no_of_bits -= 8;
1105 }
1106 if (no_of_bits > 0)
1107 {
1108 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
1109 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1110 pui8++;
1111 bit_offset += no_of_bits;
1112 no_of_bits = 0;
1113 }
1114 }
1115 }
1116
1117 /* bitmap was successfully extracted or it was empty */
1118 pDescr++;
1119 break;
1120 }
1121
1122 case CSN_PADDING_BITS:
1123 { /* Padding from here and to the end of message */
1124 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
1125 if (remaining_bits_len > 0)
1126 {
1127 while (remaining_bits_len > 0)
1128 {
1129 guint bits_to_handle = remaining_bits_len%8;
1130 if (bits_to_handle > 0)
1131 {
1132 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
1133 remaining_bits_len -= bits_to_handle;
1134 bit_offset += bits_to_handle;
1135 }
1136 else if (bits_to_handle == 0)
1137 {
1138 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
1139 remaining_bits_len -= 8;
1140 bit_offset += 8;
1141 }
1142 }
1143 }
1144 if (remaining_bits_len < 0)
1145 {
1146 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1147 }
1148
1149 /* Padding was successfully extracted or it was empty */
1150 pDescr++;
1151 break;
1152 }
1153
1154 case CSN_VARIABLE_ARRAY:
1155 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1156 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1157 * Array with length specified in parameter:
1158 * <count: bit (x)>
1159 * <list: octet(count + offset)>
1160 */
1161 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1162
1163 count += pDescr->i; /* Adjusted by offset */
1164
1165 if (count > 0)
1166 {
1167 remaining_bits_len -= count * 8;
1168
1169 if (remaining_bits_len < 0)
1170 {
1171 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1172 }
1173
1174 pui8 = pui8DATA(data, pDescr->offset);
1175
1176 while (count > 0)
1177 {
1178 *pui8 = bitvec_read_field(vector, readIndex, 8);
1179 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
1180 pui8++;
1181 bit_offset += 8;
1182 count--;
1183 }
1184 }
1185
1186 pDescr++;
1187 break;
1188 }
1189
1190 case CSN_RECURSIVE_ARRAY:
1191 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1192 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1193 * where <element> ::= bit(value)
1194 * <tag> ::= 0 | 1
1195 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1196 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1197 * REMARK: recursive way to specify an array but an iterative implementation!
1198 */
1199 gint16 no_of_bits = pDescr->i;
1200 guint8 ElementCount = 0;
1201
1202 pui8 = pui8DATA(data, pDescr->offset);
1203
1204 while (existNextElement(vector, readIndex, Tag))
1205 { /* tag control shows existence of next list elements */
1206 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
1207 bit_offset++;
1208 remaining_bits_len--;
1209
1210 /* extract and store no_of_bits long element from bitstream */
1211 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
1212 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1213 pui8++;
1214 remaining_bits_len -= no_of_bits;
1215 ElementCount++;
1216
1217 if (remaining_bits_len < 0)
1218 {
1219 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1220 }
1221
1222 bit_offset += no_of_bits;
1223 }
1224
1225 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
1226 /* existNextElement() returned FALSE, 1 bit consumed */
1227 bit_offset++;
1228 remaining_bits_len--;
1229
1230 /* Store the counted number of elements of the array */
1231 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1232
1233 pDescr++;
1234 break;
1235 }
1236
1237 case CSN_RECURSIVE_TARRAY:
1238 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1239 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1240 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
1241 */
1242 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
1243 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
1244 guint8 ElementCount = 0;
1245 pui8 = pui8DATA(data, pDescr->offset);
1246
1247 while (existNextElement(vector, readIndex, Tag))
1248 { /* tag control shows existence of next list elements */
1249 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
1250 /* existNextElement() returned TRUE, 1 bit consumed */
1251 bit_offset++;
1252 remaining_bits_len--;
1253 ElementCount++;
1254
1255 if (ElementCount > nSizeArray)
1256 {
1257 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1258 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1259 }
1260
1261 { /* unpack the following data structure */
1262 csnStream_t arT = *ar;
1263 gint16 Status;
1264 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1265 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
1266
1267 if (Status >= 0)
1268 { /* successful completion */
1269 pui8 += nSizeElement; /* -> to next data element */
1270 remaining_bits_len = arT.remaining_bits_len;
1271 bit_offset = arT.bit_offset;
1272 }
1273 else
1274 { /* something went awry */
1275 return Status;
1276 }
1277 }
1278
1279 if (remaining_bits_len < 0)
1280 {
1281 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1282 }
1283 }
1284
1285 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
1286
1287 /* existNextElement() returned FALSE, 1 bit consumed */
1288 remaining_bits_len--;
1289 bit_offset++;
1290
1291 /* Store the counted number of elements of the array */
1292 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1293
1294 pDescr++;
1295 break;
1296 }
1297
1298 case CSN_RECURSIVE_TARRAY_2:
1299 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1300
1301 Tag = REVERSED_TAG;
1302
1303 /* NO break -
1304 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1305 */
1306 }
1307 /* FALL THROUGH */
1308 case CSN_RECURSIVE_TARRAY_1:
1309 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1310 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1311 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
1312 */
1313 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
1314 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
1315 guint8 ElementCount = 0;
1316 csnStream_t arT = *ar;
1317 gboolean EndOfList = FALSE;
1318 gint16 Status;
1319 pui8 = pui8DATA(data, pDescr->offset);
1320
1321 do
1322 { /* get data element */
1323 ElementCount++;
1324
1325 if (ElementCount > nSizeArray)
1326 {
1327 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1328 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1329 }
1330
1331 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
1332
1333 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1334 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
1335
1336 if (Status >= 0)
1337 { /* successful completion */
1338 pui8 += nSizeElement; /* -> to next */
1339 remaining_bits_len = arT.remaining_bits_len;
1340 bit_offset = arT.bit_offset;
1341 }
1342 else
1343 { /* something went awry */
1344 return Status;
1345 }
1346
1347 if (remaining_bits_len < 0)
1348 {
1349 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1350 }
1351
1352 /* control of next element's tag */
1353 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
1354 EndOfList = !(existNextElement(vector, readIndex, Tag));
1355
1356 bit_offset++;
1357 remaining_bits_len--; /* 1 bit consumed (tag) */
1358 } while (!EndOfList);
1359
1360
1361 /* Store the count of the array */
1362 *pui8DATA(data, pDescr->i) = ElementCount;
1363 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1364 pDescr++;
1365 break;
1366 }
1367
1368 case CSN_FIXED:
1369 { /* Verify the fixed bits */
1370 guint8 no_of_bits = (guint8) pDescr->i;
1371 guint32 ui32;
1372
1373 if (no_of_bits <= 32)
1374 {
1375 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
1376 }
1377 else
1378 {
1379 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1380 }
1381 if (ui32 != (unsigned)(gint32)pDescr->offset)
1382 {
1383 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1384 }
1385
1386 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
1387 remaining_bits_len -= no_of_bits;
1388 bit_offset += no_of_bits;
1389 pDescr++;
1390 break;
1391 }
1392
1393 case CSN_CALLBACK:
1394 {
1395 guint16 no_of_bits;
1396 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1397 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
1398 no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
1399 remaining_bits_len -= no_of_bits;
1400 bit_offset += no_of_bits;
1401 pDescr++;
1402 break;
1403 }
1404
1405 case CSN_TRAP_ERROR:
1406 {
1407 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1408 }
1409
1410 case CSN_END:
1411 {
1412 ar->remaining_bits_len = remaining_bits_len;
1413 ar->bit_offset = bit_offset;
1414 return remaining_bits_len;
1415 }
1416
1417 default:
1418 {
1419 assert(0);
1420 }
1421
1422
1423 }
1424
1425 } while (remaining_bits_len >= 0);
1426
1427 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1428}