blob: 8dbbde4d4c76fb4e39f1453c32617ba1daac37a1 [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
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 <iostream>
32#include <cstdlib>
33#include "csn1.h"
34
35
36#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
37#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
38#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
39#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
40#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
41/* used to tag existence of next element in variable length lists */
42#define STANDARD_TAG 1
43#define REVERSED_TAG 0
44#define LOG(INFO) cout
45
46using namespace std;
47static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
48
49
50/* Returns no_of_bits (up to 8) masked with 0x2B */
51
52static guint8
53get_masked_bits8( BitVector *vector, size_t& readIndex, gint bit_offset, const gint no_of_bits)
54{
55 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
56 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
57 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
58 guint8 result;
59 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
60 readIndex -= relative_bit_offset;
61 if (bit_shift >= 0)
62 {
63 result = (0x2B ^ ((guint8)vector->readField(readIndex, 8))) >> bit_shift;
64 readIndex-= bit_shift;
65 result &= maskBits[no_of_bits];
66 }
67 else
68 {
69 guint8 hight_part = (0x2B ^ ((guint8)vector->readField(readIndex, 8))) & maskBits[8 - relative_bit_offset];
70 hight_part = (guint8) (hight_part << (-bit_shift));
71 result = (0x2B ^ ((guint8)vector->readField(readIndex, 8))) >> (8 + bit_shift);
72 readIndex = readIndex - (8 - (-bit_shift));
73 result |= hight_part;
74 }
75 return result;
76}
77
78/**
79 * ================================================================================================
80 * set initial/start values in help data structure used for packing/unpacking operation
81 * ================================================================================================
82 */
83void
84csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
85{
86 ar->remaining_bits_len = remaining_bits_len;
87 ar->bit_offset = bit_offset;
88}
89
90static const char* ErrCodes[] =
91{
92 "General 0",
93 "General -1",
94 "DATA_NOT VALID",
95 "IN SCRIPT",
96 "INVALID UNION INDEX",
97 "NEED_MORE BITS TO UNPACK",
98 "ILLEGAL BIT VALUE",
99 "Internal",
100 "STREAM_NOT_SUPPORTED",
101 "MESSAGE_TOO_LONG"
102};
103
104static gint16
105ProcessError( size_t readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
106{
107 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
108 if (i >= 0)
109 {
110 LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
111 }
112 else
113 {
114 LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
115 }
116 return err;
117}
118
119//#if 0
120static const char* CSN_DESCR_type[]=
121{
122 "CSN_END",
123 "CSN_BIT",
124 "CSN_UINT",
125 "CSN_TYPE",
126 "CSN_CHOICE",
127 "CSN_UNION",
128 "CSN_UNION_LH",
129 "CSN_UINT_ARRAY",
130 "CSN_TYPE_ARRAY",
131 "CSN_BITMAP",
132 "CSN_VARIABLE_BITMAP",
133 "CSN_VARIABLE_BITMAP_1",
134 "CSN_LEFT_ALIGNED_VAR_BMP",
135 "CSN_LEFT_ALIGNED_VAR_BMP_1",
136 "CSN_VARIABLE_ARRAY",
137 "CSN_VARIABLE_TARRAY",
138 "CSN_VARIABLE_TARRAY_OFFSET",
139 "CSN_RECURSIVE_ARRAY",
140 "CSN_RECURSIVE_TARRAY",
141 "CSN_RECURSIVE_TARRAY_1",
142 "CSN_RECURSIVE_TARRAY_2",
143 "CSN_EXIST",
144 "CSN_EXIST_LH",
145 "CSN_NEXT_EXIST",
146 "CSN_NEXT_EXIST_LH",
147 "CSN_NULL",
148 "CSN_FIXED",
149 "CSN_CALLBACK",
150 "CSN_UINT_OFFSET",
151 "CSN_UINT_LH",
152 "CSN_SERIALIZE",
153 "CSN_TRAP_ERROR"
154 "CSN_???"
155};
156//#endif
157
158/**
159 * ================================================================================================
160 * Return TRUE if tag in bit stream indicates existence of next list element,
161 * otherwise return FALSE.
162 * Will work for tag values equal to both 0 and 1.
163 * ================================================================================================
164 */
165
166static gboolean
167existNextElement(BitVector *vector, size_t& readIndex, guint8 Tag)
168{
169 guint8 res = vector->readField(readIndex, 1);
170 //LOG(INFO) << "EXIST TAG = " << (unsigned)res;
171 if (Tag == STANDARD_TAG)
172 {
173 return (res > 0);
174 }
175 return (res == 0);
176}
177
178
179gint16
180csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, BitVector *vector, size_t& readIndex, void* data)
181{
182 gint remaining_bits_len = ar->remaining_bits_len;
183 gint bit_offset = ar->bit_offset;
184 guint8* pui8;
185 guint16* pui16;
186 guint32* pui32;
187 guint64* pui64;
188 guint8 Tag = STANDARD_TAG;
189
190 if (remaining_bits_len <= 0)
191 {
192 return 0;
193 }
194
195 do
196 {
197 switch (pDescr->type)
198 {
199 case CSN_BIT:
200 {
201 if (remaining_bits_len > 0)
202 {
203 pui8 = pui8DATA(data, pDescr->offset);
204 *pui8 = vector->readField(readIndex, 1);
205 LOG(INFO) << pDescr->sz << " = " <<(unsigned)*pui8 << "\n";
206 /* end add the bit value to protocol tree */
207 }
208 else
209 {
210 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
211 }
212
213 pDescr++;
214 remaining_bits_len--;
215 bit_offset++;
216 break;
217 }
218
219 case CSN_NULL:
220 { /* Empty member! */
221 pDescr++;
222 break;
223 }
224
225 case CSN_UINT:
226 {
227 guint8 no_of_bits = (guint8) pDescr->i;
228
229 if (remaining_bits_len >= no_of_bits)
230 {
231 if (no_of_bits <= 8)
232 {
233 guint8 ui8 = vector->readField(readIndex, no_of_bits);
234 pui8 = pui8DATA(data, pDescr->offset);
235 *pui8 = ui8;
236 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
237 }
238 else if (no_of_bits <= 16)
239 {
240 guint16 ui16 = vector->readField(readIndex, no_of_bits);
241 pui16 = pui16DATA(data, pDescr->offset);
242 *pui16 = ui16;
243 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";;
244 }
245 else if (no_of_bits <= 32)
246 {
247 guint32 ui32 = vector->readField(readIndex, no_of_bits);
248 pui32 = pui32DATA(data, pDescr->offset);
249 *pui32 = ui32;
250 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
251 }
252 else
253 {
254 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
255 }
256 }
257 else
258 {
259 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
260 }
261
262 remaining_bits_len -= no_of_bits;
263 bit_offset += no_of_bits;
264 pDescr++;
265 break;
266 }
267
268 case CSN_UINT_OFFSET:
269 {
270 guint8 no_of_bits = (guint8) pDescr->i;
271
272 if (remaining_bits_len >= no_of_bits)
273 {
274 if (no_of_bits <= 8)
275 {
276 guint8 ui8 = vector->readField(readIndex, no_of_bits);
277 pui8 = pui8DATA(data, pDescr->offset);
278 *pui8 = ui8 + (guint8)pDescr->descr.value;
279 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
280 }
281 else if (no_of_bits <= 16)
282 {
283 guint16 ui16 = vector->readField(readIndex, no_of_bits);
284 pui16 = pui16DATA(data, pDescr->offset);
285 *pui16 = ui16 + (guint16)pDescr->descr.value;
286 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";;
287 }
288 else if (no_of_bits <= 32)
289 {
290 guint32 ui32 = vector->readField(readIndex, no_of_bits);
291 pui32 = pui32DATA(data, pDescr->offset);
292 *pui32 = ui32 + (guint16)pDescr->descr.value;
293 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
294 }
295 else
296 {
297 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
298 }
299 }
300 else
301 {
302 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
303 }
304
305 remaining_bits_len -= no_of_bits;
306 bit_offset += no_of_bits;
307 pDescr++;
308 break;
309 }
310
311 case CSN_UINT_LH:
312 {
313 guint8 no_of_bits = (guint8) pDescr->i;
314
315 if (remaining_bits_len >= no_of_bits)
316 {
317 remaining_bits_len -= no_of_bits;
318 if (no_of_bits <= 8)
319 {
320 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
321 pui8 = pui8DATA(data, pDescr->offset);
322 *pui8 = ui8;
323 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
324 }
325 else
326 {/* Maybe we should support more than 8 bits ? */
327 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
328 }
329 }
330 else
331 {
332 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
333 }
334
335 remaining_bits_len -= no_of_bits;
336 bit_offset += no_of_bits;
337 pDescr++;
338 break;
339 }
340
341 case CSN_UINT_ARRAY:
342 {
343 guint8 no_of_bits = (guint8) pDescr->i;
344 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
345
346 if (pDescr->serialize.value != 0)
347 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
348 nCount = *pui16DATA(data, nCount);
349 }
350
351 if (remaining_bits_len >= no_of_bits)
352 {
353 remaining_bits_len -= (no_of_bits*nCount);
354 if (no_of_bits <= 8)
355 {
356 pui8 = pui8DATA(data, pDescr->offset);
357 do
358 {
359 *pui8 = vector->readField(readIndex, no_of_bits);
360 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
361 pui8++;
362 bit_offset += no_of_bits;
363 } while (--nCount > 0);
364 }
365 else if (no_of_bits <= 16)
366 {
367 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
368 }
369 else if (no_of_bits <= 32)
370 {
371 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
372 }
373 else
374 {
375 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
376 }
377 }
378 else
379 {
380 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
381 }
382 pDescr++;
383 break;
384 }
385
386 case CSN_VARIABLE_TARRAY_OFFSET:
387 case CSN_VARIABLE_TARRAY:
388 case CSN_TYPE_ARRAY:
389 {
390 gint16 Status;
391 csnStream_t arT = *ar;
392 gint16 nCount = pDescr->i;
393 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
394
395 pui8 = pui8DATA(data, pDescr->offset);
396 if (pDescr->type == CSN_VARIABLE_TARRAY)
397 { /* Count specified in field */
398 nCount = *pui8DATA(data, pDescr->i);
399 }
400 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
401 { /* Count specified in field */
402 nCount = *pui8DATA(data, pDescr->i);
403 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
404 }
405
406 while (nCount > 0)
407 { /* resulting array of length 0 is possible
408 * but no bits shall be read from bitstream
409 */
410
411 LOG(INFO) << pDescr->sz << "\n";
412 csnStreamInit(&arT, bit_offset, remaining_bits_len);
413 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
414 if (Status >= 0)
415 {
416 pui8 += nSize;
417 remaining_bits_len = arT.remaining_bits_len;
418 bit_offset = arT.bit_offset;
419 }
420 else
421 {
422 return Status;
423 }
424 nCount--;
425 }
426
427 pDescr++;
428 break;
429 }
430
431 case CSN_BITMAP:
432 { /* bitmap with given length. The result is left aligned! */
433 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
434
435 if (no_of_bits > 0)
436 {
437
438 if (no_of_bits <= 32)
439 {
440 guint32 ui32 = vector->readField(readIndex, no_of_bits);
441 pui32 = pui32DATA(data, pDescr->offset);
442 *pui32 = ui32;
443 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
444 }
445 else if (no_of_bits <= 64)
446 {
447 guint64 ui64 = vector->readField(readIndex, no_of_bits);
448 pui64 = pui64DATA(data, pDescr->offset);
449 *pui64 = ui64;
450 LOG(INFO) << pDescr->sz << " = " << *pui64 << "\n";
451 }
452 else
453 {
454 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
455 }
456
457 remaining_bits_len -= no_of_bits;
458 assert(remaining_bits_len >= 0);
459 bit_offset += no_of_bits;
460 }
461 /* bitmap was successfully extracted or it was empty */
462
463 pDescr++;
464 break;
465 }
466
467 case CSN_TYPE:
468 {
469 gint16 Status;
470 csnStream_t arT = *ar;
471 LOG(INFO) << ": " << pDescr->sz << "\n";
472 csnStreamInit(&arT, bit_offset, remaining_bits_len);
473 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
474 LOG(INFO) << ": End " << pDescr->sz << "\n";
475 if (Status >= 0)
476 {
477 remaining_bits_len = arT.remaining_bits_len;
478 bit_offset = arT.bit_offset;
479 pDescr++;
480 }
481 else
482 {
483 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
484 return Status;
485 }
486
487 break;
488 }
489
490 case CSN_CHOICE:
491 {
492 gint16 count = pDescr->i;
493 guint8 i = 0;
494 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
495
496 while (count > 0)
497 {
498 guint8 no_of_bits = pChoice->bits;
499 guint8 value = vector->readField(readIndex, no_of_bits);
500 if (value == pChoice->value)
501 {
502 CSN_DESCR descr[2];
503 gint16 Status;
504 csnStream_t arT = *ar;
505
506 descr[0] = pChoice->descr;
507 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
508 descr[1].type = CSN_END;
509 pui8 = pui8DATA(data, pDescr->offset);
510 *pui8 = i;
511 LOG(INFO) << "Choice " << pDescr->sz << " = " << (unsigned)value << "\n";
512 bit_offset += no_of_bits;
513 remaining_bits_len -= no_of_bits;
514
515 csnStreamInit(&arT, bit_offset, remaining_bits_len);
516 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
517
518 if (Status >= 0)
519 {
520 remaining_bits_len = arT.remaining_bits_len;
521 bit_offset = arT.bit_offset;
522 }
523 else
524 {
525 return Status;
526 }
527 break;
528 }
529
530 readIndex -= no_of_bits;
531 count--;
532 pChoice++;
533 i++;
534 }
535
536 pDescr++;
537 break;
538 }
539
540 case CSN_SERIALIZE:
541 {
542 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
543 csnStream_t arT = *ar;
544 gint16 Status = -1;
545
546 LOG(INFO) << pDescr->sz << " length = " << vector->readField(readIndex, 7) << "\n";
547 arT.direction = 1;
548 bit_offset += 7;
549 remaining_bits_len -= 7;
550
551 csnStreamInit(&arT, bit_offset, remaining_bits_len);
552 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
553
554 if (Status >= 0)
555 {
556 remaining_bits_len = arT.remaining_bits_len;
557 bit_offset = arT.bit_offset;
558 pDescr++;
559 }
560 else
561 {
562 /* Has already been processed: */
563 return Status;
564 }
565
566 break;
567 }
568
569 case CSN_UNION_LH:
570 case CSN_UNION:
571 {
572 gint16 Bits;
573 guint8 index;
574 gint16 count = pDescr->i;
575 const CSN_DESCR* pDescrNext = pDescr;
576
577 pDescrNext += count + 1; /* now this is next after the union */
578 if ((count <= 0) || (count > 16))
579 {
580 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
581 }
582
583 /* Now get the bits to extract the index */
584 Bits = ixBitsTab[count];
585 index = 0;
586
587 while (Bits > 0)
588 {
589 index <<= 1;
590
591 if (CSN_UNION_LH == pDescr->type)
592 {
593 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
594 }
595 else
596 {
597 index |= vector->readField(readIndex, 1);
598 }
599 remaining_bits_len--;
600 bit_offset++;
601 Bits--;
602 }
603
604 /* Assign UnionType */
605 pui8 = pui8DATA(data, pDescr->offset);
606 *pui8 = index;
607
608
609 /* script index to continue on, limited in case we do not have a power of 2 */
610 pDescr += (MIN(index + 1, count));
611 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
612
613 switch (pDescr->type)
614 { /* get the right element of the union based on computed index */
615
616 case CSN_BIT:
617 {
618 pui8 = pui8DATA(data, pDescr->offset);
619 *pui8 = 0x00;
620 if (vector->readField(readIndex, 1) > 0)
621 {
622 *pui8 = 0x01;
623 }
624 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
625 remaining_bits_len -= 1;
626 bit_offset++;
627 pDescr++;
628 break;
629 }
630
631 case CSN_NULL:
632 { /* Empty member! */
633 pDescr++;
634 break;
635 }
636
637 case CSN_UINT:
638 {
639 guint8 no_of_bits = (guint8) pDescr->i;
640 if (remaining_bits_len >= no_of_bits)
641 {
642 remaining_bits_len -= no_of_bits;
643
644 if (no_of_bits <= 8)
645 {
646 guint8 ui8 = vector->readField(readIndex, no_of_bits);
647 pui8 = pui8DATA(data, pDescr->offset);
648 *pui8 = ui8;
649 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
650 }
651 else if (no_of_bits <= 16)
652 {
653 guint16 ui16 = vector->readField(readIndex, no_of_bits);
654 pui16 = pui16DATA(data, pDescr->offset);
655 *pui16 = ui16;
656 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";
657 }
658 else if (no_of_bits <= 32)
659 {
660 guint32 ui32 = vector->readField(readIndex, no_of_bits);
661 pui32 = pui32DATA(data, pDescr->offset);
662 *pui32 = ui32;
663 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
664 }
665 else
666 {
667 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
668 }
669 }
670 else
671 {
672 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
673 }
674
675 bit_offset += no_of_bits;
676 pDescr++;
677 break;
678 }
679
680 case CSN_UINT_OFFSET:
681 {
682 guint8 no_of_bits = (guint8) pDescr->i;
683
684 if (remaining_bits_len >= no_of_bits)
685 {
686 if (no_of_bits <= 8)
687 {
688 guint8 ui8 = vector->readField(readIndex, no_of_bits);
689 pui8 = pui8DATA(data, pDescr->offset);
690 *pui8 = ui8 + (guint8)pDescr->descr.value;
691 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
692 }
693 else if (no_of_bits <= 16)
694 {
695 guint16 ui16 = vector->readField(readIndex, no_of_bits);
696 pui16 = pui16DATA(data, pDescr->offset);
697 *pui16 = ui16 + (guint16)pDescr->descr.value;
698 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";
699 }
700 else if (no_of_bits <= 32)
701 {
702 guint32 ui32 = vector->readField(readIndex, no_of_bits);
703 pui32 = pui32DATA(data, pDescr->offset);
704 *pui32 = ui32 + (guint16)pDescr->descr.value;
705 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
706 }
707 else
708 {
709 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
710 }
711 }
712 else
713 {
714 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
715 }
716
717 bit_offset += no_of_bits;
718 pDescr++;
719 break;
720 }
721
722 case CSN_UINT_LH:
723 {
724 guint8 no_of_bits = (guint8) pDescr->i;
725
726 if (remaining_bits_len >= no_of_bits)
727 {
728 if (no_of_bits <= 8)
729 {
730 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
731 pui8 = pui8DATA(data, pDescr->offset);
732 *pui8 = ui8;
733 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
734 }
735 else
736 { /* Maybe we should support more than 8 bits ? */
737 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
738 }
739 }
740 else
741 {
742 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
743 }
744
745 bit_offset += no_of_bits;
746 pDescr++;
747 break;
748 }
749
750 case CSN_UINT_ARRAY:
751 {
752 guint8 no_of_bits = (guint8) pDescr->i;
753 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
754
755 if (pDescr->serialize.value != 0)
756 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
757 nCount = *pui16DATA(data, nCount);
758 }
759
760 if (remaining_bits_len >= no_of_bits)
761 {
762 remaining_bits_len -= (no_of_bits * nCount);
763 if (no_of_bits <= 8)
764 {
765 pui8 = pui8DATA(data, pDescr->offset);
766
767 while (nCount > 0)
768 {
769 *pui8 = vector->readField(readIndex, no_of_bits);
770 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
771 pui8++;
772 bit_offset += no_of_bits;
773 nCount--;
774 }
775 }
776 else if (no_of_bits <= 16)
777 {
778 pui16 = pui16DATA(data, pDescr->offset);
779
780 while (nCount > 0)
781 {
782 *pui16 = vector->readField(readIndex, no_of_bits);
783 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";
784 pui16++;
785 bit_offset += no_of_bits;
786 nCount--;
787 }
788 }
789 else if (no_of_bits <= 32)
790 { /* not supported */
791 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
792 }
793 else
794 {
795 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
796 }
797 }
798 else
799 {
800 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
801 }
802
803 pDescr++;
804 break;
805 }
806
807 case CSN_VARIABLE_TARRAY_OFFSET:
808 case CSN_VARIABLE_TARRAY:
809 case CSN_TYPE_ARRAY:
810 {
811 gint16 Status;
812 csnStream_t arT = *ar;
813 guint16 nCount = (guint16) pDescr->i;
814 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
815
816 pui8 = pui8DATA(data, pDescr->offset);
817
818 if (CSN_VARIABLE_TARRAY == pDescr->type)
819 { /* Count specified in field */
820 nCount = *pui8DATA(data, pDescr->i);
821 }
822 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
823 { /* Count specified in field */
824 nCount = *pui8DATA(data, pDescr->i);
825 nCount--; /* Offset 1 */
826 }
827
828 while (nCount--) /* Changed to handle length = 0. */
829 {
830 LOG(INFO) << pDescr->sz << "\n";
831 csnStreamInit(&arT, bit_offset, remaining_bits_len);
832 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
833 if (Status >= 0)
834 {
835 pui8 += nSize;
836 remaining_bits_len = arT.remaining_bits_len;
837 bit_offset = arT.bit_offset;
838 }
839 else
840 {
841 return Status;
842 }
843 }
844
845 pDescr++;
846 break;
847 }
848
849 case CSN_BITMAP:
850 { /* bitmap with given length. The result is left aligned! */
851 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
852
853 if (no_of_bits > 0)
854 {
855
856 if (no_of_bits <= 32)
857 {
858 guint32 ui32 = vector->readField(readIndex, no_of_bits);
859 pui32 = pui32DATA(data, pDescr->offset);
860 *pui32 = ui32;
861 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
862 }
863 else if (no_of_bits <= 64)
864 {
865 guint64 ui64 = vector->readField(readIndex, no_of_bits);
866 pui64 = pui64DATA(data, pDescr->offset);
867 *pui64 = ui64;
868 LOG(INFO) << pDescr->sz << " = " << *pui64 << "\n";
869 }
870 else
871 {
872 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
873 }
874
875 remaining_bits_len -= no_of_bits;
876 assert(remaining_bits_len >= 0);
877 bit_offset += no_of_bits;
878 }
879 /* bitmap was successfully extracted or it was empty */
880
881 pDescr++;
882 break;
883 }
884
885 case CSN_TYPE:
886 {
887 gint16 Status;
888 csnStream_t arT = *ar;
889 LOG(INFO) << ": " << pDescr->sz << "\n";
890 csnStreamInit(&arT, bit_offset, remaining_bits_len);
891 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
892 LOG(INFO) << ": End " << pDescr->sz << "\n";
893 if (Status >= 0)
894 {
895 remaining_bits_len = arT.remaining_bits_len;
896 bit_offset = arT.bit_offset;
897 pDescr++;
898 }
899 else
900 { /* return error code Has already been processed: */
901 return Status;
902 }
903
904 break;
905 }
906
907 default:
908 { /* descriptions of union elements other than above are illegal */
909 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
910 }
911 }
912
913 pDescr = pDescrNext;
914 break;
915 }
916
917 case CSN_EXIST:
918 case CSN_EXIST_LH:
919 {
920 guint8 fExist;
921
922 pui8 = pui8DATA(data, pDescr->offset);
923
924 if (CSN_EXIST_LH == pDescr->type)
925 {
926 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
927 }
928 else
929 {
930 fExist = vector->readField(readIndex, 1);
931 }
932
933 *pui8 = fExist;
934 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 <<"\n";
935 pDescr++;
936 remaining_bits_len -= 1;
937
938 if (!fExist)
939 {
940 ar->remaining_bits_len = remaining_bits_len;
941 ar->bit_offset = bit_offset;
942 return remaining_bits_len;
943 }
944
945 break;
946 }
947
948 case CSN_NEXT_EXIST:
949 {
950 guint8 fExist;
951
952 pui8 = pui8DATA(data, pDescr->offset);
953
954 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
955 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
956 { /* no more bits to decode is fine here - end of message detected and allowed */
957
958 /* Skip i entries + this entry */
959 pDescr += pDescr->i + 1;
960
961 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
962 if ( pDescr->type != CSN_END )
963 { /* Substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
964 remaining_bits_len--;
965 }
966
967 /* Set the data member to "not exist" */
968 *pui8 = 0;
969 break;
970 }
971
972 /* the "regular" M_NEXT_EXIST description element */
973
974 fExist = 0x00;
975 if (vector->readField(readIndex, 1))
976 {
977 fExist = 0x01;
978 }
979
980 *pui8 = fExist;
981 remaining_bits_len -= 1;
982 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
983 ++bit_offset;
984
985 if (fExist == 0)
986 { /* Skip 'i' entries */
987 pDescr += pDescr->i;
988 }
989
990 pDescr++;
991 break;
992 }
993
994 case CSN_NEXT_EXIST_LH:
995 {
996 guint8 fExist;
997 pui8 = pui8DATA(data, pDescr->offset);
998
999 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1000 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1001 { /* no more bits to decode is fine here - end of message detected and allowed */
1002
1003 /* skip 'i' entries + this entry */
1004 pDescr += pDescr->i + 1;
1005
1006 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1007 if ( pDescr->type != CSN_END )
1008 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1009 remaining_bits_len--;
1010 }
1011
1012 /* set the data member to "not exist" */
1013 *pui8 = 0;
1014 break;
1015 }
1016
1017 /* the "regular" M_NEXT_EXIST_LH description element */
1018 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
1019 LOG(INFO) << pDescr->sz << " = " << (unsigned)fExist << "\n" ;
1020 *pui8++ = fExist;
1021 remaining_bits_len -= 1;
1022
1023 bit_offset++;
1024
1025 if (fExist == 0)
1026 { /* Skip 'i' entries */
1027 pDescr += pDescr->i;
1028 }
1029 pDescr++;
1030
1031 break;
1032 }
1033
1034 case CSN_VARIABLE_BITMAP_1:
1035 { /* Bitmap from here and to the end of message */
1036
1037 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1038
1039 /*no break -
1040 * with a length set we have a regular variable length bitmap so we continue */
1041 }
1042
1043 case CSN_VARIABLE_BITMAP:
1044 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1045 * <N: bit (5)> <bitmap: bit(N + offset)>
1046 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1047 * The result is right aligned!
1048 */
1049 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1050
1051 no_of_bits += pDescr->i; /* adjusted by offset */
1052
1053 if (no_of_bits > 0)
1054 {
1055 remaining_bits_len -= no_of_bits;
1056
1057 if (remaining_bits_len < 0)
1058 {
1059 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1060 }
1061
1062 { /* extract bits */
1063 guint8* pui8 = pui8DATA(data, pDescr->offset);
1064 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1065
1066 if (nB1 > 0)
1067 { /* take care of the first byte - it will be right aligned */
1068 *pui8 = vector->readField(readIndex, nB1);
1069 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
1070 pui8++;
1071 no_of_bits -= nB1;
1072 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1073 }
1074
1075 /* remaining no_of_bits is a multiple of 8 or 0 */
1076 while (no_of_bits > 0)
1077 {
1078 *pui8 = vector->readField(readIndex, 8);
1079 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
1080 pui8++;
1081 no_of_bits -= 8;
1082 }
1083 }
1084 }
1085 pDescr++;
1086 break;
1087 }
1088
1089 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1090 { /* Bitmap from here and to the end of message */
1091
1092 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1093
1094 /* no break -
1095 * with a length set we have a regular left aligned variable length bitmap so we continue
1096 */
1097 }
1098
1099 case CSN_LEFT_ALIGNED_VAR_BMP:
1100 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1101 * <N: bit (5)> <bitmap: bit(N + offset)>
1102 * bit array with length (in bits) specified in parameter (pDescr->descr)
1103 */
1104 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1105
1106 no_of_bits += pDescr->i;/* size adjusted by offset */
1107
1108 if (no_of_bits > 0)
1109 {
1110 remaining_bits_len -= no_of_bits;
1111
1112 if (remaining_bits_len < 0)
1113 {
1114 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1115 }
1116
1117 { /* extract bits */
1118 guint8* pui8 = pui8DATA(data, pDescr->offset);
1119 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1120
1121 while (no_of_bits > 0)
1122 {
1123 *pui8 = vector->readField(readIndex, 8);
1124 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
1125 pui8++;
1126 no_of_bits -= 8;
1127 }
1128 if (nB1 > 0)
1129 {
1130 *pui8 = vector->readField(readIndex, nB1);
1131 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
1132 pui8++;
1133 no_of_bits -= nB1;
1134 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1135 }
1136 }
1137 }
1138
1139 /* bitmap was successfully extracted or it was empty */
1140 pDescr++;
1141 break;
1142 }
1143
1144 case CSN_VARIABLE_ARRAY:
1145 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1146 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1147 * Array with length specified in parameter:
1148 * <count: bit (x)>
1149 * <list: octet(count + offset)>
1150 */
1151 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1152
1153 count += pDescr->i; /* Adjusted by offset */
1154
1155 if (count > 0)
1156 {
1157 remaining_bits_len -= count * 8;
1158
1159 if (remaining_bits_len < 0)
1160 {
1161 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1162 }
1163
1164 pui8 = pui8DATA(data, pDescr->offset);
1165
1166 while (count > 0)
1167 {
1168 readIndex -= 8;
1169 *pui8 = vector->readField(readIndex, 8);
1170 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1171 pui8++;
1172 bit_offset += 8;
1173 count--;
1174 }
1175 }
1176
1177 pDescr++;
1178 break;
1179 }
1180
1181 case CSN_RECURSIVE_ARRAY:
1182 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1183 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1184 * where <element> ::= bit(value)
1185 * <tag> ::= 0 | 1
1186 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1187 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1188 * REMARK: recursive way to specify an array but an iterative implementation!
1189 */
1190 gint16 no_of_bits = pDescr->i;
1191 guint8 ElementCount = 0;
1192
1193 pui8 = pui8DATA(data, pDescr->offset);
1194
1195 while (existNextElement(vector, readIndex, Tag))
1196 { /* tag control shows existence of next list elements */
1197 LOG(INFO) << pDescr->sz << " = Exist \n" ;
1198 bit_offset++;
1199 remaining_bits_len--;
1200
1201 /* extract and store no_of_bits long element from bitstream */
1202 *pui8 = vector->readField(readIndex, no_of_bits);
1203 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1204 pui8++;
1205 remaining_bits_len -= no_of_bits;
1206 ElementCount++;
1207
1208 if (remaining_bits_len < 0)
1209 {
1210 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1211 }
1212
1213 bit_offset += no_of_bits;
1214 }
1215
1216 LOG(INFO) << pDescr->sz << " = " << vector->readField(readIndex, 1) << "\n";
1217 /* existNextElement() returned FALSE, 1 bit consumed */
1218 bit_offset++;
1219
1220 /* Store the counted number of elements of the array */
1221 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1222
1223 pDescr++;
1224 break;
1225 }
1226
1227 case CSN_RECURSIVE_TARRAY:
1228 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1229 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1230 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1231 */
1232 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1233 guint8 ElementCount = 0;
1234 pui8 = pui8DATA(data, pDescr->offset);
1235
1236 while (existNextElement(vector, readIndex, Tag))
1237 { /* tag control shows existence of next list elements */
1238 LOG(INFO) << pDescr->sz << " = Exist \n" ;
1239 /* existNextElement() returned TRUE, 1 bit consumed */
1240 bit_offset++;
1241 remaining_bits_len--;
1242 ElementCount++;
1243
1244 { /* unpack the following data structure */
1245 csnStream_t arT = *ar;
1246 gint16 Status;
1247 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1248 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1249
1250 if (Status >= 0)
1251 { /* successful completion */
1252 pui8 += nSizeElement; /* -> to next data element */
1253 remaining_bits_len = arT.remaining_bits_len;
1254 bit_offset = arT.bit_offset;
1255 }
1256 else
1257 { /* something went awry */
1258 return Status;
1259 }
1260 }
1261
1262 if (remaining_bits_len < 0)
1263 {
1264 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1265 }
1266 }
1267
1268 LOG(INFO) << pDescr->sz << " = " << vector->readField(readIndex, 1) << "\n";
1269
1270 /* existNextElement() returned FALSE, 1 bit consumed */
1271 bit_offset++;
1272
1273 /* Store the counted number of elements of the array */
1274 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1275
1276 pDescr++;
1277 break;
1278 }
1279
1280 case CSN_RECURSIVE_TARRAY_2:
1281 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1282
1283 Tag = REVERSED_TAG;
1284
1285 /* NO break -
1286 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1287 */
1288 }
1289
1290 case CSN_RECURSIVE_TARRAY_1:
1291 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1292 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1293 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1294 */
1295 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1296 guint8 ElementCount = 0;
1297 csnStream_t arT = *ar;
1298 gboolean EndOfList = FALSE;
1299 gint16 Status;
1300 pui8 = pui8DATA(data, pDescr->offset);
1301
1302 do
1303 { /* get data element */
1304 ElementCount++;
1305
1306 LOG(INFO) << pDescr->sz << " { \n";
1307 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1308 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
1309
1310 if (Status >= 0)
1311 { /* successful completion */
1312 pui8 += nSizeElement; /* -> to next */
1313 remaining_bits_len = arT.remaining_bits_len;
1314 bit_offset = arT.bit_offset;
1315 }
1316 else
1317 { /* something went awry */
1318 return Status;
1319 }
1320
1321 if (remaining_bits_len < 0)
1322 {
1323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1324 }
1325
1326 /* control of next element's tag */
1327 LOG(INFO) << pDescr->sz << " } \n";
1328 EndOfList = !(existNextElement(vector, readIndex, Tag));
1329
1330 bit_offset++;
1331 remaining_bits_len--; /* 1 bit consumed (tag) */
1332 } while (!EndOfList);
1333
1334
1335 /* Store the count of the array */
1336 *pui8DATA(data, pDescr->i) = ElementCount;
1337 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1338 pDescr++;
1339 break;
1340 }
1341
1342 case CSN_FIXED:
1343 { /* Verify the fixed bits */
1344 guint8 no_of_bits = (guint8) pDescr->i;
1345 guint32 ui32;
1346
1347 if (no_of_bits <= 32)
1348 {
1349 ui32 = vector->readField(readIndex, no_of_bits);
1350 }
1351 else
1352 {
1353 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1354 }
1355 if (ui32 != (unsigned)(gint32)pDescr->offset)
1356 {
1357 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1358 }
1359
1360 LOG(INFO) << pDescr->sz<< " = " << ui32 << "\n";
1361 remaining_bits_len -= no_of_bits;
1362 bit_offset += no_of_bits;
1363 pDescr++;
1364 break;
1365 }
1366
1367 case CSN_CALLBACK:
1368 {
1369 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1370 break;
1371 }
1372
1373 case CSN_TRAP_ERROR:
1374 {
1375 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1376 }
1377
1378 case CSN_END:
1379 {
1380 ar->remaining_bits_len = remaining_bits_len;
1381 ar->bit_offset = bit_offset;
1382 return remaining_bits_len;
1383 }
1384
1385 default:
1386 {
1387 assert(0);
1388 }
1389
1390
1391 }
1392
1393 } while (remaining_bits_len >= 0);
1394
1395 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1396}
1397
1398
1399
1400
1401gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, BitVector *vector, size_t& writeIndex, void* data)
1402{
1403 gint remaining_bits_len = ar->remaining_bits_len;
1404 gint bit_offset = ar->bit_offset;
1405 guint8* pui8;
1406 guint16* pui16;
1407 guint32* pui32;
1408 guint64* pui64;
1409
1410 guint8 Tag = STANDARD_TAG;
1411
1412 if (remaining_bits_len <= 0)
1413 {
1414 return 0;
1415 }
1416
1417 do
1418 {
1419 switch (pDescr->type)
1420 {
1421 case CSN_BIT:
1422 {
1423 if (remaining_bits_len > 0)
1424 {
1425 pui8 = pui8DATA(data, pDescr->offset);
1426 vector->writeField(writeIndex, *pui8, 1);
1427 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1428 /* end add the bit value to protocol tree */
1429 }
1430 else
1431 {
1432 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1433 }
1434
1435 pDescr++;
1436 remaining_bits_len--;
1437 bit_offset++;
1438 break;
1439 }
1440
1441 case CSN_NULL:
1442 { /* Empty member! */
1443 pDescr++;
1444 break;
1445 }
1446
1447 case CSN_UINT:
1448 {
1449 guint8 no_of_bits = (guint8) pDescr->i;
1450
1451 if (remaining_bits_len >= no_of_bits)
1452 {
1453 if (no_of_bits <= 8)
1454 {
1455 pui8 = pui8DATA(data, pDescr->offset);
1456 vector->writeField(writeIndex, *pui8, no_of_bits);
1457 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1458 }
1459 else if (no_of_bits <= 16)
1460 {
1461 pui16 = pui16DATA(data, pDescr->offset);
1462 vector->writeField(writeIndex, *pui16, no_of_bits);
1463 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";
1464 }
1465 else if (no_of_bits <= 32)
1466 {
1467 pui32 = pui32DATA(data, pDescr->offset);
1468 vector->writeField(writeIndex, *pui32, no_of_bits);
1469 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
1470 }
1471 else
1472 {
1473 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1474 }
1475 }
1476 else
1477 {
1478 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1479 }
1480
1481 remaining_bits_len -= no_of_bits;
1482 bit_offset += no_of_bits;
1483 pDescr++;
1484 break;
1485 }
1486
1487 case CSN_UINT_OFFSET:
1488 {
1489 guint8 no_of_bits = (guint8) pDescr->i;
1490
1491 if (remaining_bits_len >= no_of_bits)
1492 {
1493 if (no_of_bits <= 8)
1494 {
1495 pui8 = pui8DATA(data, pDescr->offset);
1496 vector->writeField(writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
1497 LOG(INFO) << pDescr->sz << " = " << (unsigned)(*pui8 - (guint8)pDescr->descr.value) << "\n";
1498 }
1499 else if (no_of_bits <= 16)
1500 {
1501 pui16 = pui16DATA(data, pDescr->offset);
1502 vector->writeField(writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
1503 LOG(INFO) << pDescr->sz << " = " << *pui16 - (guint16)pDescr->descr.value << "\n";
1504 }
1505 else if (no_of_bits <= 32)
1506 {
1507 pui32 = pui32DATA(data, pDescr->offset);
1508 vector->writeField(writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
1509 LOG(INFO) << pDescr->sz << " = " << *pui32 - (guint16)pDescr->descr.value << "\n";
1510 }
1511 else
1512 {
1513 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1514 }
1515 }
1516 else
1517 {
1518 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1519 }
1520
1521 remaining_bits_len -= no_of_bits;
1522 bit_offset += no_of_bits;
1523 pDescr++;
1524 break;
1525 }
1526
1527 case CSN_UINT_LH:
1528 {
1529 guint8 no_of_bits = (guint8) pDescr->i;
1530
1531 if (remaining_bits_len >= no_of_bits)
1532 {
1533 remaining_bits_len -= no_of_bits;
1534 if (no_of_bits <= 8)
1535 {
1536 pui8 = pui8DATA(data, pDescr->offset);
1537 vector->writeField(writeIndex, *pui8, no_of_bits);
1538 // TODO : Change get_masked_bits8()
1539 writeIndex -= no_of_bits;
1540 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1541 writeIndex -= no_of_bits;
1542 vector->writeField(writeIndex, ui8, no_of_bits);
1543 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1544
1545 }
1546 else
1547 {/* Maybe we should support more than 8 bits ? */
1548 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1549 }
1550 }
1551 else
1552 {
1553 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1554 }
1555
1556 remaining_bits_len -= no_of_bits;
1557 bit_offset += no_of_bits;
1558 pDescr++;
1559 break;
1560 }
1561
1562 case CSN_UINT_ARRAY:
1563 {
1564 guint8 no_of_bits = (guint8) pDescr->i;
1565 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1566
1567 if (pDescr->serialize.value != 0)
1568 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1569 nCount = *pui16DATA(data, nCount);
1570 }
1571
1572 if (remaining_bits_len >= no_of_bits)
1573 {
1574 remaining_bits_len -= (no_of_bits*nCount);
1575 if (no_of_bits <= 8)
1576 {
1577 pui8 = pui8DATA(data, pDescr->offset);
1578 do
1579 {
1580 vector->writeField(writeIndex, *pui8, no_of_bits);
1581 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1582 pui8++;
1583 bit_offset += no_of_bits;
1584 } while (--nCount > 0);
1585 }
1586 else if (no_of_bits <= 16)
1587 {
1588 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1589 }
1590 else if (no_of_bits <= 32)
1591 {
1592 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1593 }
1594 else
1595 {
1596 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1597 }
1598 }
1599 else
1600 {
1601 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1602 }
1603 pDescr++;
1604 break;
1605 }
1606
1607 case CSN_VARIABLE_TARRAY_OFFSET:
1608 case CSN_VARIABLE_TARRAY:
1609 case CSN_TYPE_ARRAY:
1610 {
1611 gint16 Status;
1612 csnStream_t arT = *ar;
1613 gint16 nCount = pDescr->i;
1614 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1615
1616 pui8 = pui8DATA(data, pDescr->offset);
1617 if (pDescr->type == CSN_VARIABLE_TARRAY)
1618 { /* Count specified in field */
1619 nCount = *pui8DATA(data, pDescr->i);
1620 }
1621 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1622 { /* Count specified in field */
1623 nCount = *pui8DATA(data, pDescr->i);
1624 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1625 }
1626
1627 while (nCount > 0)
1628 { /* resulting array of length 0 is possible
1629 * but no bits shall be read from bitstream
1630 */
1631
1632 LOG(INFO) << pDescr->sz << " : \n";
1633 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1634 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1635 if (Status >= 0)
1636 {
1637 pui8 += nSize;
1638 remaining_bits_len = arT.remaining_bits_len;
1639 bit_offset = arT.bit_offset;
1640
1641 }
1642 else
1643 {
1644 return Status;
1645 }
1646 nCount--;
1647 }
1648
1649 pDescr++;
1650 break;
1651 }
1652
1653 case CSN_BITMAP:
1654 { /* bitmap with given length. The result is left aligned! */
1655 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1656
1657 if (no_of_bits > 0)
1658 {
1659
1660 if (no_of_bits <= 32)
1661 {
1662 pui32 = pui32DATA(data, pDescr->offset);
1663 vector->writeField(writeIndex, *pui32, no_of_bits);
1664 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
1665 }
1666 else if (no_of_bits <= 64)
1667 {
1668 pui64 = pui64DATA(data, pDescr->offset);
1669 vector->writeField(writeIndex, *pui64, no_of_bits);
1670 LOG(INFO) << pDescr->sz << " = " << *pui64 << "\n";
1671 }
1672 else
1673 {
1674 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1675 }
1676
1677 remaining_bits_len -= no_of_bits;
1678 assert(remaining_bits_len >= 0);
1679 bit_offset += no_of_bits;
1680 }
1681 /* bitmap was successfully extracted or it was empty */
1682
1683 pDescr++;
1684 break;
1685 }
1686
1687 case CSN_TYPE:
1688 {
1689 gint16 Status;
1690 csnStream_t arT = *ar;
1691 LOG(INFO) << ": " << pDescr->sz << "\n";
1692 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1693 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
1694 LOG(INFO) << ": End " << pDescr->sz << "\n";
1695 if (Status >= 0)
1696 {
1697
1698 remaining_bits_len = arT.remaining_bits_len;
1699 bit_offset = arT.bit_offset;
1700 pDescr++;
1701 }
1702 else
1703 {
1704 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1705 return Status;
1706 }
1707
1708 break;
1709 }
1710
1711 case CSN_CHOICE:
1712 {
1713 //gint16 count = pDescr->i;
1714 guint8 i = 0;
1715 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1716
1717 pui8 = pui8DATA(data, pDescr->offset);
1718 i = *pui8;
1719 pChoice += i;
1720 guint8 no_of_bits = pChoice->bits;
1721 guint8 value = pChoice->value;
1722 LOG(INFO) << pChoice->descr.sz << " = " << (unsigned)value << "\n";
1723 vector->writeField(writeIndex, value, no_of_bits);
1724
1725 CSN_DESCR descr[2];
1726 gint16 Status;
1727 csnStream_t arT = *ar;
1728
1729 descr[0] = pChoice->descr;
1730 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1731 descr[1].type = CSN_END;
1732 bit_offset += no_of_bits;
1733 remaining_bits_len -= no_of_bits;
1734
1735 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1736 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1737
1738 if (Status >= 0)
1739 {
1740 remaining_bits_len = arT.remaining_bits_len;
1741 bit_offset = arT.bit_offset;
1742 }
1743 else
1744 {
1745 return Status;
1746 }
1747
1748 pDescr++;
1749 break;
1750 }
1751
1752 case CSN_SERIALIZE:
1753 {
1754 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1755 csnStream_t arT = *ar;
1756 gint16 Status = -1;
1757 size_t lengthIndex;
1758
1759 // store writeIndex for length value (7 bit)
1760 lengthIndex = writeIndex;
1761 writeIndex += 7;
1762 bit_offset += 7;
1763 remaining_bits_len -= 7;
1764 arT.direction = 0;
1765 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1766 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
1767
1768 vector->writeField(lengthIndex, writeIndex-lengthIndex-7, 7);
1769 LOG(INFO) << pDescr->sz << " length = " << writeIndex-lengthIndex << "\n";
1770
1771 if (Status >= 0)
1772 {
1773 remaining_bits_len = arT.remaining_bits_len;
1774 bit_offset = arT.bit_offset;
1775 pDescr++;
1776 }
1777 else
1778 {
1779 // Has already been processed:
1780 return Status;
1781 }
1782
1783 break;
1784 }
1785
1786 case CSN_UNION_LH:
1787 case CSN_UNION:
1788 {
1789 gint16 Bits;
1790 guint8 index;
1791 gint16 count = pDescr->i;
1792 const CSN_DESCR* pDescrNext = pDescr;
1793
1794 pDescrNext += count + 1; /* now this is next after the union */
1795 if ((count <= 0) || (count > 16))
1796 {
1797 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1798 }
1799
1800 /* Now get the bits to extract the index */
1801 Bits = ixBitsTab[count];
1802 index = 0;
1803
1804 /* Assign UnionType */
1805 pui8 = pui8DATA(data, pDescr->offset);
1806 //read index from data and write to vector
1807 vector->writeField(writeIndex, *pui8, Bits);
1808
1809 //decode index
1810 writeIndex -= Bits;
1811
1812 while (Bits > 0)
1813 {
1814 index <<= 1;
1815
1816 if (CSN_UNION_LH == pDescr->type)
1817 {
1818 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1819 }
1820 else
1821 {
1822 index |= vector->readField(writeIndex, 1);
1823 }
1824
1825 remaining_bits_len--;
1826 bit_offset++;
1827 Bits--;
1828 }
1829
1830 writeIndex -= Bits;
1831 vector->writeField(writeIndex, index, Bits);
1832
1833
1834 /* script index to continue on, limited in case we do not have a power of 2 */
1835 pDescr += (MIN(index + 1, count));
1836 LOG(INFO) << pDescr->sz << " = " << (unsigned)index << "\n";
1837
1838 switch (pDescr->type)
1839 { /* get the right element of the union based on computed index */
1840
1841 case CSN_BIT:
1842 {
1843 pui8 = pui8DATA(data, pDescr->offset);
1844 vector->writeField(writeIndex, *pui8, 1);
1845 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1846 remaining_bits_len -= 1;
1847 bit_offset++;
1848 pDescr++;
1849 break;
1850 }
1851
1852 case CSN_NULL:
1853 { /* Empty member! */
1854 pDescr++;
1855 break;
1856 }
1857
1858 case CSN_UINT:
1859 {
1860 guint8 no_of_bits = (guint8) pDescr->i;
1861 if (remaining_bits_len >= no_of_bits)
1862 {
1863 remaining_bits_len -= no_of_bits;
1864
1865 if (no_of_bits <= 8)
1866 {
1867 pui8 = pui8DATA(data, pDescr->offset);
1868 vector->writeField(writeIndex, *pui8, no_of_bits);
1869 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1870 }
1871 else if (no_of_bits <= 16)
1872 {
1873 pui16 = pui16DATA(data, pDescr->offset);
1874 vector->writeField(writeIndex, *pui16, no_of_bits);
1875 LOG(INFO) << pDescr->sz << " = " << *pui16 << "\n";
1876 }
1877 else if (no_of_bits <= 32)
1878 {
1879 pui32 = pui32DATA(data, pDescr->offset);
1880 vector->writeField(writeIndex, *pui32, no_of_bits);
1881 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
1882 }
1883 else
1884 {
1885 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1886 }
1887 }
1888 else
1889 {
1890 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1891 }
1892
1893 bit_offset += no_of_bits;
1894 pDescr++;
1895 break;
1896 }
1897
1898 case CSN_UINT_OFFSET:
1899 {
1900 guint8 no_of_bits = (guint8) pDescr->i;
1901
1902 if (remaining_bits_len >= no_of_bits)
1903 {
1904 if (no_of_bits <= 8)
1905 {
1906 pui8 = pui8DATA(data, pDescr->offset);
1907 vector->writeField(writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
1908 LOG(INFO) << pDescr->sz << " = " << (unsigned)(*pui8 - (guint8)pDescr->descr.value) << "\n";
1909 }
1910 else if (no_of_bits <= 16)
1911 {
1912 pui16 = pui16DATA(data, pDescr->offset);
1913 vector->writeField(writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
1914 LOG(INFO) << pDescr->sz << " = " << *pui16 - (guint16)pDescr->descr.value << "\n";
1915 }
1916 else if (no_of_bits <= 32)
1917 {
1918 pui32 = pui32DATA(data, pDescr->offset);
1919 vector->writeField(writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
1920 LOG(INFO) << pDescr->sz << " = " << *pui32 - (guint16)pDescr->descr.value << "\n";
1921 }
1922 else
1923 {
1924 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1925 }
1926 }
1927 else
1928 {
1929 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1930 }
1931
1932 remaining_bits_len -= no_of_bits;
1933 bit_offset += no_of_bits;
1934 pDescr++;
1935 break;
1936 }
1937
1938 case CSN_UINT_LH:
1939 {
1940 guint8 no_of_bits = (guint8) pDescr->i;
1941
1942 if (remaining_bits_len >= no_of_bits)
1943 {
1944 remaining_bits_len -= no_of_bits;
1945 if (no_of_bits <= 8)
1946 {
1947 pui8 = pui8DATA(data, pDescr->offset);
1948 vector->writeField(writeIndex, *pui8, no_of_bits);
1949 // TODO : Change get_masked_bits8()
1950 writeIndex -= no_of_bits;
1951 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1952 writeIndex -= no_of_bits;
1953 vector->writeField(writeIndex, ui8, no_of_bits);
1954 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1955
1956 }
1957 else
1958 {/* Maybe we should support more than 8 bits ? */
1959 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1960 }
1961 }
1962 else
1963 {
1964 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1965 }
1966
1967 remaining_bits_len -= no_of_bits;
1968 bit_offset += no_of_bits;
1969 pDescr++;
1970 break;
1971 }
1972
1973 case CSN_UINT_ARRAY:
1974 {
1975 guint8 no_of_bits = (guint8) pDescr->i;
1976 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1977
1978 if (pDescr->serialize.value != 0)
1979 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1980 nCount = *pui16DATA(data, nCount);
1981 }
1982
1983 if (remaining_bits_len >= no_of_bits)
1984 {
1985 remaining_bits_len -= (no_of_bits*nCount);
1986 if (no_of_bits <= 8)
1987 {
1988 pui8 = pui8DATA(data, pDescr->offset);
1989 do
1990 {
1991 vector->writeField(writeIndex, *pui8, no_of_bits);
1992 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
1993 pui8++;
1994 bit_offset += no_of_bits;
1995 } while (--nCount > 0);
1996 }
1997 else if (no_of_bits <= 16)
1998 {
1999 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2000 }
2001 else if (no_of_bits <= 32)
2002 {
2003 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2004 }
2005 else
2006 {
2007 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2008 }
2009 }
2010 else
2011 {
2012 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2013 }
2014 pDescr++;
2015 break;
2016 }
2017
2018 case CSN_VARIABLE_TARRAY_OFFSET:
2019 case CSN_VARIABLE_TARRAY:
2020 case CSN_TYPE_ARRAY:
2021 {
2022 gint16 Status;
2023 csnStream_t arT = *ar;
2024 gint16 nCount = pDescr->i;
2025 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2026
2027 pui8 = pui8DATA(data, pDescr->offset);
2028 if (pDescr->type == CSN_VARIABLE_TARRAY)
2029 { /* Count specified in field */
2030 nCount = *pui8DATA(data, pDescr->i);
2031 }
2032 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2033 { /* Count specified in field */
2034 nCount = *pui8DATA(data, pDescr->i);
2035 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2036 }
2037
2038 while (nCount > 0)
2039 { /* resulting array of length 0 is possible
2040 * but no bits shall be read from bitstream
2041 */
2042
2043 LOG(INFO) << pDescr->sz << " : \n";
2044 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2045 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2046 if (Status >= 0)
2047 {
2048 pui8 += nSize;
2049 remaining_bits_len = arT.remaining_bits_len;
2050 bit_offset = arT.bit_offset;
2051 }
2052 else
2053 {
2054 return Status;
2055 }
2056 nCount--;
2057 }
2058
2059 pDescr++;
2060 break;
2061 }
2062
2063 case CSN_BITMAP:
2064 { /* bitmap with given length. The result is left aligned! */
2065 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2066
2067 if (no_of_bits > 0)
2068 {
2069
2070 if (no_of_bits <= 32)
2071 {
2072 pui32 = pui32DATA(data, pDescr->offset);
2073 vector->writeField(writeIndex, *pui32, no_of_bits);
2074 LOG(INFO) << pDescr->sz << " = " << *pui32 << "\n";
2075 }
2076 else if (no_of_bits <= 64)
2077 {
2078 pui64 = pui64DATA(data, pDescr->offset);
2079 vector->writeField(writeIndex, *pui64, no_of_bits);
2080 LOG(INFO) << pDescr->sz << " = " << *pui64 << "\n";
2081 }
2082 else
2083 {
2084 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2085 }
2086
2087 remaining_bits_len -= no_of_bits;
2088 assert(remaining_bits_len >= 0);
2089 bit_offset += no_of_bits;
2090 }
2091 /* bitmap was successfully extracted or it was empty */
2092
2093 pDescr++;
2094 break;
2095 }
2096
2097 case CSN_TYPE:
2098 {
2099 gint16 Status;
2100 csnStream_t arT = *ar;
2101 LOG(INFO) << ": " << pDescr->sz << "\n";
2102 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2103 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
2104 LOG(INFO) << ": End " << pDescr->sz << "\n";
2105 if (Status >= 0)
2106 {
2107 remaining_bits_len = arT.remaining_bits_len;
2108 bit_offset = arT.bit_offset;
2109 pDescr++;
2110 }
2111 else
2112 {
2113 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2114 return Status;
2115 }
2116
2117 break;
2118 }
2119
2120 default:
2121 { /* descriptions of union elements other than above are illegal */
2122 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2123 }
2124 }
2125
2126 pDescr = pDescrNext;
2127 break;
2128 }
2129
2130 case CSN_EXIST:
2131 case CSN_EXIST_LH:
2132 {
2133 guint8 fExist;
2134 unsigned exist = 0;
2135 pui8 = pui8DATA(data, pDescr->offset);
2136 exist = *pui8;
2137 vector->writeField(writeIndex, *pui8, 1);
2138 writeIndex--;
2139 if (CSN_EXIST_LH == pDescr->type)
2140 {
2141 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2142 }
2143 else
2144 {
2145 fExist = vector->readField(writeIndex, 1);
2146 }
2147 writeIndex--;
2148 vector->writeField(writeIndex, fExist, 1);
2149 LOG(INFO) << pDescr->sz << " = " << (unsigned)fExist << "\n";
2150 pDescr++;
2151 remaining_bits_len -= 1;
2152
2153 if (!exist)
2154 {
2155 ar->remaining_bits_len = remaining_bits_len;
2156 ar->bit_offset = bit_offset;
2157 return remaining_bits_len;
2158 }
2159 break;
2160 }
2161
2162 case CSN_NEXT_EXIST:
2163 {
2164 guint8 fExist;
2165
2166 pui8 = pui8DATA(data, pDescr->offset);
2167
2168 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
2169 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2170 { /* no more bits to decode is fine here - end of message detected and allowed */
2171
2172 /* Skip i entries + this entry */
2173 pDescr += pDescr->i + 1;
2174
2175 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2176 if ( pDescr->type != CSN_END )
2177 { /* Substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2178 remaining_bits_len--;
2179 }
2180
2181 break;
2182 }
2183
2184 vector->writeField(writeIndex, *pui8, 1);
2185 fExist = *pui8;
2186 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n";
2187 remaining_bits_len -= 1;
2188
2189 ++bit_offset;
2190
2191 if (fExist == 0)
2192 { /* Skip 'i' entries */
2193 pDescr += pDescr->i;
2194 }
2195
2196 pDescr++;
2197 break;
2198 }
2199
2200 case CSN_NEXT_EXIST_LH:
2201 {
2202 guint8 fExist;
2203 pui8 = pui8DATA(data, pDescr->offset);
2204
2205 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2206 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2207 { /* no more bits to decode is fine here - end of message detected and allowed */
2208
2209 /* skip 'i' entries + this entry */
2210 pDescr += pDescr->i + 1;
2211
2212 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2213 if ( pDescr->type != CSN_END )
2214 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2215 remaining_bits_len--;
2216 }
2217
2218 /* set the data member to "not exist" */
2219 //*pui8 = 0;
2220 break;
2221 }
2222
2223 /* the "regular" M_NEXT_EXIST_LH description element */
2224 vector->writeField(writeIndex, *pui8, 1);
2225 writeIndex--;
2226 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2227 writeIndex--;
2228 vector->writeField(writeIndex, fExist, 1);
2229 pui8++;
2230 remaining_bits_len -= 1;
2231
2232 bit_offset++;
2233
2234 if (fExist == 0)
2235 { /* Skip 'i' entries */
2236 pDescr += pDescr->i;
2237 }
2238 pDescr++;
2239
2240 break;
2241 }
2242
2243 case CSN_VARIABLE_BITMAP_1:
2244 { /* Bitmap from here and to the end of message */
2245
2246 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2247
2248 /*no break -
2249 * with a length set we have a regular variable length bitmap so we continue */
2250 }
2251
2252 case CSN_VARIABLE_BITMAP:
2253 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2254 * <N: bit (5)> <bitmap: bit(N + offset)>
2255 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2256 * The result is right aligned!
2257 */
2258 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2259
2260 no_of_bits += pDescr->i; /* adjusted by offset */
2261
2262 if (no_of_bits > 0)
2263 {
2264 remaining_bits_len -= no_of_bits;
2265
2266 if (remaining_bits_len < 0)
2267 {
2268 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2269 }
2270
2271 { /* extract bits */
2272 guint8* pui8 = pui8DATA(data, pDescr->offset);
2273 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2274
2275 if (nB1 > 0)
2276 { /* take care of the first byte - it will be right aligned */
2277 vector->writeField(writeIndex, *pui8, nB1);
2278 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
2279 pui8++;
2280 no_of_bits -= nB1;
2281 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2282 }
2283
2284 /* remaining no_of_bits is a multiple of 8 or 0 */
2285 while (no_of_bits > 0)
2286 {
2287 vector->writeField(writeIndex, *pui8, 8);
2288 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
2289 pui8++;
2290 no_of_bits -= 8;
2291 }
2292 }
2293 }
2294 pDescr++;
2295 break;
2296 }
2297
2298 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2299 { /* Bitmap from here and to the end of message */
2300
2301 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2302
2303 /* no break -
2304 * with a length set we have a regular left aligned variable length bitmap so we continue
2305 */
2306 }
2307
2308 case CSN_LEFT_ALIGNED_VAR_BMP:
2309 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2310 * <N: bit (5)> <bitmap: bit(N + offset)>
2311 * bit array with length (in bits) specified in parameter (pDescr->descr)
2312 */
2313
2314 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2315
2316 no_of_bits += pDescr->i;/* size adjusted by offset */
2317
2318 if (no_of_bits > 0)
2319 {
2320 remaining_bits_len -= no_of_bits;
2321
2322 if (remaining_bits_len < 0)
2323 {
2324 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2325 }
2326
2327 { /* extract bits */
2328 guint8* pui8 = pui8DATA(data, pDescr->offset);
2329 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2330
2331 while (no_of_bits > 0)
2332 {
2333 vector->writeField(writeIndex, *pui8, 8);
2334 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
2335 pui8++;
2336 no_of_bits -= 8;
2337 }
2338 if (nB1 > 0)
2339 {
2340 vector->writeField(writeIndex, *pui8, nB1);
2341 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
2342 pui8++;
2343 no_of_bits -= nB1;
2344 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2345 }
2346 }
2347
2348 }
2349
2350 /* bitmap was successfully extracted or it was empty */
2351 pDescr++;
2352 break;
2353 }
2354
2355 case CSN_VARIABLE_ARRAY:
2356 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2357 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2358 * Array with length specified in parameter:
2359 * <count: bit (x)>
2360 * <list: octet(count + offset)>
2361 */
2362 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2363
2364 count += pDescr->i; /* Adjusted by offset */
2365
2366 if (count > 0)
2367 {
2368 remaining_bits_len -= count * 8;
2369
2370 if (remaining_bits_len < 0)
2371 {
2372 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2373 }
2374
2375 pui8 = pui8DATA(data, pDescr->offset);
2376
2377 while (count > 0)
2378 {
2379 vector->writeField(writeIndex, *pui8, 8);
2380 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
2381 pui8++;
2382 bit_offset += 8;
2383 count--;
2384 }
2385 }
2386
2387 pDescr++;
2388 break;
2389 }
2390
2391 case CSN_RECURSIVE_ARRAY:
2392 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2393 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2394 * where <element> ::= bit(value)
2395 * <tag> ::= 0 | 1
2396 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2397 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2398 * REMARK: recursive way to specify an array but an iterative implementation!
2399 */
2400 gint16 no_of_bits = pDescr->i;
2401 guint8 ElementCount = 0;
2402 pui8 = pui8DATA(data, pDescr->offset);
2403 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2404 while (ElementCount > 0)
2405 { /* tag control shows existence of next list elements */
2406 vector->writeField(writeIndex, Tag, 1);
2407 LOG(INFO) << pDescr->sz << " = " << (unsigned)Tag << "\n" ;
2408 bit_offset++;
2409 remaining_bits_len--;
2410
2411 /* extract and store no_of_bits long element from bitstream */
2412 vector->writeField(writeIndex, *pui8, no_of_bits);
2413 LOG(INFO) << pDescr->sz << " = " << (unsigned)*pui8 << "\n" ;
2414 pui8++;
2415 remaining_bits_len -= no_of_bits;
2416 ElementCount--;
2417
2418 if (remaining_bits_len < 0)
2419 {
2420 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2421 }
2422
2423 bit_offset += no_of_bits;
2424 }
2425
2426 vector->writeField(writeIndex, !Tag, 1);
2427 LOG(INFO) << pDescr->sz << " = " << (unsigned)(!Tag) << "\n" ;
2428 bit_offset++;
2429
2430 pDescr++;
2431 break;
2432 }
2433
2434 case CSN_RECURSIVE_TARRAY:
2435 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2436 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2437 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2438 */
2439 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2440 guint8 ElementCount = 0;
2441 pui8 = pui8DATA(data, pDescr->offset);
2442 /* Store the counted number of elements of the array */
2443 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2444
2445 while (ElementCount > 0)
2446 { /* tag control shows existence of next list elements */
2447 vector->writeField(writeIndex, Tag, 1);
2448 LOG(INFO) << pDescr->sz << " = " << (unsigned)Tag << "\n" ;
2449 bit_offset++;
2450
2451 remaining_bits_len--;
2452 ElementCount--;
2453
2454 { /* unpack the following data structure */
2455 csnStream_t arT = *ar;
2456 gint16 Status;
2457 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2458 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
2459
2460 if (Status >= 0)
2461 { /* successful completion */
2462 pui8 += nSizeElement; /* -> to next data element */
2463 remaining_bits_len = arT.remaining_bits_len;
2464 bit_offset = arT.bit_offset;
2465 }
2466 else
2467 { /* something went awry */
2468 return Status;
2469 }
2470 }
2471
2472 if (remaining_bits_len < 0)
2473 {
2474 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2475 }
2476 }
2477
2478 vector->writeField(writeIndex, !Tag, 1);
2479 LOG(INFO) << pDescr->sz << " = " << (unsigned)(!Tag) << "\n" ;
2480 bit_offset++;
2481
2482 pDescr++;
2483 break;
2484 }
2485
2486 case CSN_RECURSIVE_TARRAY_2:
2487 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2488
2489 Tag = REVERSED_TAG;
2490
2491 /* NO break -
2492 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2493 */
2494 }
2495
2496 case CSN_RECURSIVE_TARRAY_1:
2497 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2498 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2499 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2500 */
2501 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2502 guint8 ElementCount = 0;
2503 guint8 ElementNum = 0;
2504 csnStream_t arT = *ar;
2505 gint16 Status;
2506
2507 pui8 = pui8DATA(data, pDescr->offset);
2508 /* Store the count of the array */
2509 ElementCount = *pui8DATA(data, pDescr->i);
2510 ElementNum = ElementCount;
2511
2512 while (ElementCount > 0)
2513 { /* get data element */
2514 if (ElementCount != ElementNum)
2515 {
2516 vector->writeField(writeIndex, Tag, 1);
2517 LOG(INFO) << pDescr->sz << " = " << (unsigned)Tag << "\n" ;
2518 bit_offset++;
2519 remaining_bits_len--;
2520 }
2521 ElementCount--;
2522 LOG(INFO) << pDescr->sz << " { \n";
2523 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2524 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
2525 LOG(INFO) << pDescr->sz << " } \n";
2526 if (Status >= 0)
2527 { /* successful completion */
2528 pui8 += nSizeElement; /* -> to next */
2529 remaining_bits_len = arT.remaining_bits_len;
2530 bit_offset = arT.bit_offset;
2531 }
2532 else
2533 { /* something went awry */
2534 return Status;
2535 }
2536
2537 if (remaining_bits_len < 0)
2538 {
2539 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2540 }
2541
2542 }
2543 vector->writeField(writeIndex, !Tag, 1);
2544 bit_offset++;
2545 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2546 pDescr++;
2547 break;
2548 }
2549
2550 case CSN_FIXED:
2551 { /* Verify the fixed bits */
2552 guint8 no_of_bits = (guint8) pDescr->i;
2553 vector->writeField(writeIndex, pDescr->offset, no_of_bits);
2554 LOG(INFO) << pDescr->sz<< " = " << pDescr->offset << "\n";
2555 remaining_bits_len -= no_of_bits;
2556 bit_offset += no_of_bits;
2557 pDescr++;
2558 break;
2559 }
2560
2561 case CSN_CALLBACK:
2562 {
2563 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2564 break;
2565 }
2566
2567 case CSN_TRAP_ERROR:
2568 {
2569 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2570 }
2571
2572 case CSN_END:
2573 {
2574 ar->remaining_bits_len = remaining_bits_len;
2575 ar->bit_offset = bit_offset;
2576 return remaining_bits_len;
2577 }
2578
2579 default:
2580 {
2581 assert(0);
2582 }
2583
2584 }
2585
2586 } while (remaining_bits_len >= 0);
2587
2588 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2589}
2590