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