blob: 6203a4409c0f9429b7de315bac37b575138d5908 [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>
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040033#include <assert.h>
34#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020035#define __STDC_FORMAT_MACROS
36#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040038#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030039
40
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
50using namespace std;
51static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
52
53
54/* Returns no_of_bits (up to 8) masked with 0x2B */
55
56static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040057get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030058{
59 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
60 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
61 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
62 guint8 result;
63 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
64 readIndex -= relative_bit_offset;
65 if (bit_shift >= 0)
66 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010067 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030068 readIndex-= bit_shift;
69 result &= maskBits[no_of_bits];
70 }
71 else
72 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010073 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030074 hight_part = (guint8) (hight_part << (-bit_shift));
Alexander Couzensccde5c92017-02-04 03:10:08 +010075 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030076 readIndex = readIndex - (8 - (-bit_shift));
77 result |= hight_part;
78 }
79 return result;
80}
81
82/**
83 * ================================================================================================
84 * set initial/start values in help data structure used for packing/unpacking operation
85 * ================================================================================================
86 */
87void
88csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
89{
90 ar->remaining_bits_len = remaining_bits_len;
91 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040092 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030093}
94
95static const char* ErrCodes[] =
96{
97 "General 0",
98 "General -1",
99 "DATA_NOT VALID",
100 "IN SCRIPT",
101 "INVALID UNION INDEX",
102 "NEED_MORE BITS TO UNPACK",
103 "ILLEGAL BIT VALUE",
104 "Internal",
105 "STREAM_NOT_SUPPORTED",
106 "MESSAGE_TOO_LONG"
107};
108
109static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400110ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111{
112 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
113 if (i >= 0)
114 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400115 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116 }
117 else
118 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400119 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300120 }
121 return err;
122}
123
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300124
125/**
126 * ================================================================================================
127 * Return TRUE if tag in bit stream indicates existence of next list element,
128 * otherwise return FALSE.
129 * Will work for tag values equal to both 0 and 1.
130 * ================================================================================================
131 */
132
133static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400134existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300135{
Alexander Couzensccde5c92017-02-04 03:10:08 +0100136 guint8 res = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300137 if (Tag == STANDARD_TAG)
138 {
139 return (res > 0);
140 }
141 return (res == 0);
142}
143
144
145gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400146csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300147{
148 gint remaining_bits_len = ar->remaining_bits_len;
149 gint bit_offset = ar->bit_offset;
150 guint8* pui8;
151 guint16* pui16;
152 guint32* pui32;
153 guint64* pui64;
154 guint8 Tag = STANDARD_TAG;
155
156 if (remaining_bits_len <= 0)
157 {
158 return 0;
159 }
160
161 do
162 {
163 switch (pDescr->type)
164 {
165 case CSN_BIT:
166 {
167 if (remaining_bits_len > 0)
168 {
169 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100170 *pui8 = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400171 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 /* end add the bit value to protocol tree */
173 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400174 else if(pDescr->may_be_null)
175 {
176 pui8 = pui8DATA(data, pDescr->offset);
177 *pui8 = 0;
178 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
179 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300180 else
181 {
182 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
183 }
184
185 pDescr++;
186 remaining_bits_len--;
187 bit_offset++;
188 break;
189 }
190
191 case CSN_NULL:
192 { /* Empty member! */
193 pDescr++;
194 break;
195 }
196
197 case CSN_UINT:
198 {
199 guint8 no_of_bits = (guint8) pDescr->i;
200
201 if (remaining_bits_len >= no_of_bits)
202 {
203 if (no_of_bits <= 8)
204 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100205 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300206 pui8 = pui8DATA(data, pDescr->offset);
207 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400208 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300209 }
210 else if (no_of_bits <= 16)
211 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100212 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300213 pui16 = pui16DATA(data, pDescr->offset);
214 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400215 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300216 }
217 else if (no_of_bits <= 32)
218 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100219 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300220 pui32 = pui32DATA(data, pDescr->offset);
221 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400222 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300223 }
224 else
225 {
226 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
227 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400228 remaining_bits_len -= no_of_bits;
229 bit_offset += no_of_bits;
230 }
231 else if(pDescr->may_be_null)
232 {
233 if (no_of_bits <= 8)
234 {
235 pui8 = pui8DATA(data, pDescr->offset);
236 *pui8 = 0;
237 }
238 else if (no_of_bits <= 16)
239 {
240 pui16 = pui16DATA(data, pDescr->offset);
241 *pui16 = 0;
242 }
243 else if (no_of_bits <= 32)
244 {
245 pui32 = pui32DATA(data, pDescr->offset);
246 *pui32 = 0;
247 }
248 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300249 }
250 else
251 {
252 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
253 }
254
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300255 pDescr++;
256 break;
257 }
258
259 case CSN_UINT_OFFSET:
260 {
261 guint8 no_of_bits = (guint8) pDescr->i;
262
263 if (remaining_bits_len >= no_of_bits)
264 {
265 if (no_of_bits <= 8)
266 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100267 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300268 pui8 = pui8DATA(data, pDescr->offset);
269 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400270 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300271 }
272 else if (no_of_bits <= 16)
273 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100274 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300275 pui16 = pui16DATA(data, pDescr->offset);
276 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400277 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300278 }
279 else if (no_of_bits <= 32)
280 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100281 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300282 pui32 = pui32DATA(data, pDescr->offset);
283 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400284 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300285 }
286 else
287 {
288 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
289 }
290 }
291 else
292 {
293 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
294 }
295
296 remaining_bits_len -= no_of_bits;
297 bit_offset += no_of_bits;
298 pDescr++;
299 break;
300 }
301
302 case CSN_UINT_LH:
303 {
304 guint8 no_of_bits = (guint8) pDescr->i;
305
306 if (remaining_bits_len >= no_of_bits)
307 {
308 remaining_bits_len -= no_of_bits;
309 if (no_of_bits <= 8)
310 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100311 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300312 pui8 = pui8DATA(data, pDescr->offset);
313 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300315 }
316 else
317 {/* Maybe we should support more than 8 bits ? */
318 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
319 }
320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
324 }
325
326 remaining_bits_len -= no_of_bits;
327 bit_offset += no_of_bits;
328 pDescr++;
329 break;
330 }
331
332 case CSN_UINT_ARRAY:
333 {
334 guint8 no_of_bits = (guint8) pDescr->i;
335 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
336
337 if (pDescr->serialize.value != 0)
338 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
339 nCount = *pui16DATA(data, nCount);
340 }
341
342 if (remaining_bits_len >= no_of_bits)
343 {
344 remaining_bits_len -= (no_of_bits*nCount);
345 if (no_of_bits <= 8)
346 {
347 pui8 = pui8DATA(data, pDescr->offset);
348 do
349 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100350 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400351 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300352 pui8++;
353 bit_offset += no_of_bits;
354 } while (--nCount > 0);
355 }
356 else if (no_of_bits <= 16)
357 {
358 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
359 }
360 else if (no_of_bits <= 32)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else
365 {
366 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
367 }
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
372 }
373 pDescr++;
374 break;
375 }
376
377 case CSN_VARIABLE_TARRAY_OFFSET:
378 case CSN_VARIABLE_TARRAY:
379 case CSN_TYPE_ARRAY:
380 {
381 gint16 Status;
382 csnStream_t arT = *ar;
383 gint16 nCount = pDescr->i;
384 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
385
386 pui8 = pui8DATA(data, pDescr->offset);
387 if (pDescr->type == CSN_VARIABLE_TARRAY)
388 { /* Count specified in field */
389 nCount = *pui8DATA(data, pDescr->i);
390 }
391 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
395 }
396
397 while (nCount > 0)
398 { /* resulting array of length 0 is possible
399 * but no bits shall be read from bitstream
400 */
401
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400402 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300403 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100404 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300405 if (Status >= 0)
406 {
407 pui8 += nSize;
408 remaining_bits_len = arT.remaining_bits_len;
409 bit_offset = arT.bit_offset;
410 }
411 else
412 {
413 return Status;
414 }
415 nCount--;
416 }
417
418 pDescr++;
419 break;
420 }
421
422 case CSN_BITMAP:
423 { /* bitmap with given length. The result is left aligned! */
424 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
425
426 if (no_of_bits > 0)
427 {
428
429 if (no_of_bits <= 32)
430 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400431 for(unsigned ib = 0; ib < 4; ib++)
432 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100433 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400434 pui8 = pui8DATA(data, pDescr->offset+ib);
435 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400436 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 }
439 else if (no_of_bits <= 64)
440 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400441 for(unsigned ib = 0; ib < 8; ib++)
442 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100443 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400444 pui8 = pui8DATA(data, pDescr->offset+ib);
445 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400446 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300448 }
449 else
450 {
451 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
452 }
453
454 remaining_bits_len -= no_of_bits;
455 assert(remaining_bits_len >= 0);
456 bit_offset += no_of_bits;
457 }
458 /* bitmap was successfully extracted or it was empty */
459
460 pDescr++;
461 break;
462 }
463
464 case CSN_TYPE:
465 {
466 gint16 Status;
467 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400468 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300469 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100470 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400471 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300472 if (Status >= 0)
473 {
474 remaining_bits_len = arT.remaining_bits_len;
475 bit_offset = arT.bit_offset;
476 pDescr++;
477 }
478 else
479 {
480 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
481 return Status;
482 }
483
484 break;
485 }
486
487 case CSN_CHOICE:
488 {
489 gint16 count = pDescr->i;
490 guint8 i = 0;
491 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
492
493 while (count > 0)
494 {
495 guint8 no_of_bits = pChoice->bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100496 guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300497 if (value == pChoice->value)
498 {
499 CSN_DESCR descr[2];
500 gint16 Status;
501 csnStream_t arT = *ar;
502
503 descr[0] = pChoice->descr;
504 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
505 descr[1].type = CSN_END;
506 pui8 = pui8DATA(data, pDescr->offset);
507 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400508 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300509 bit_offset += no_of_bits;
510 remaining_bits_len -= no_of_bits;
511
512 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100513 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300514
515 if (Status >= 0)
516 {
517 remaining_bits_len = arT.remaining_bits_len;
518 bit_offset = arT.bit_offset;
519 }
520 else
521 {
522 return Status;
523 }
524 break;
525 }
526
527 readIndex -= no_of_bits;
528 count--;
529 pChoice++;
530 i++;
531 }
532
533 pDescr++;
534 break;
535 }
536
537 case CSN_SERIALIZE:
538 {
539 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
540 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400541 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300542 gint16 Status = -1;
543
Alexander Couzensccde5c92017-02-04 03:10:08 +0100544 guint8 length = bitvec_read_field(vector, &readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300545
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400546 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400547 bit_offset += length_len;
548 remaining_bits_len -= length_len;
549
550 csnStreamInit(&arT, bit_offset, length);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100551 arT.direction = 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100552 LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100553 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300554
555 if (Status >= 0)
556 {
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400557 remaining_bits_len -= length;
558 bit_offset += length;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300559 pDescr++;
560 }
561 else
562 {
563 /* Has already been processed: */
564 return Status;
565 }
566
567 break;
568 }
569
570 case CSN_UNION_LH:
571 case CSN_UNION:
572 {
573 gint16 Bits;
574 guint8 index;
575 gint16 count = pDescr->i;
576 const CSN_DESCR* pDescrNext = pDescr;
577
578 pDescrNext += count + 1; /* now this is next after the union */
579 if ((count <= 0) || (count > 16))
580 {
581 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
582 }
583
584 /* Now get the bits to extract the index */
585 Bits = ixBitsTab[count];
586 index = 0;
587
588 while (Bits > 0)
589 {
590 index <<= 1;
591
592 if (CSN_UNION_LH == pDescr->type)
593 {
594 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
595 }
596 else
597 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100598 index |= bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300599 }
600 remaining_bits_len--;
601 bit_offset++;
602 Bits--;
603 }
604
605 /* Assign UnionType */
606 pui8 = pui8DATA(data, pDescr->offset);
607 *pui8 = index;
608
609
610 /* script index to continue on, limited in case we do not have a power of 2 */
611 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400612 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300613
614 switch (pDescr->type)
615 { /* get the right element of the union based on computed index */
616
617 case CSN_BIT:
618 {
619 pui8 = pui8DATA(data, pDescr->offset);
620 *pui8 = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100621 if (bitvec_read_field(vector, &readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300622 {
623 *pui8 = 0x01;
624 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400625 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300626 remaining_bits_len -= 1;
627 bit_offset++;
628 pDescr++;
629 break;
630 }
631
632 case CSN_NULL:
633 { /* Empty member! */
634 pDescr++;
635 break;
636 }
637
638 case CSN_UINT:
639 {
640 guint8 no_of_bits = (guint8) pDescr->i;
641 if (remaining_bits_len >= no_of_bits)
642 {
643 remaining_bits_len -= no_of_bits;
644
645 if (no_of_bits <= 8)
646 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100647 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300648 pui8 = pui8DATA(data, pDescr->offset);
649 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400650 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300651 }
652 else if (no_of_bits <= 16)
653 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100654 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300655 pui16 = pui16DATA(data, pDescr->offset);
656 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400657 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300658 }
659 else if (no_of_bits <= 32)
660 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100661 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300662 pui32 = pui32DATA(data, pDescr->offset);
663 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400664 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300665 }
666 else
667 {
668 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
669 }
670 }
671 else
672 {
673 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
674 }
675
676 bit_offset += no_of_bits;
677 pDescr++;
678 break;
679 }
680
681 case CSN_UINT_OFFSET:
682 {
683 guint8 no_of_bits = (guint8) pDescr->i;
684
685 if (remaining_bits_len >= no_of_bits)
686 {
687 if (no_of_bits <= 8)
688 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100689 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300690 pui8 = pui8DATA(data, pDescr->offset);
691 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400692 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300693 }
694 else if (no_of_bits <= 16)
695 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100696 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300697 pui16 = pui16DATA(data, pDescr->offset);
698 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400699 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300700 }
701 else if (no_of_bits <= 32)
702 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100703 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300704 pui32 = pui32DATA(data, pDescr->offset);
705 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400706 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300707 }
708 else
709 {
710 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
711 }
712 }
713 else
714 {
715 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
716 }
717
718 bit_offset += no_of_bits;
719 pDescr++;
720 break;
721 }
722
723 case CSN_UINT_LH:
724 {
725 guint8 no_of_bits = (guint8) pDescr->i;
726
727 if (remaining_bits_len >= no_of_bits)
728 {
729 if (no_of_bits <= 8)
730 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100731 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300732 pui8 = pui8DATA(data, pDescr->offset);
733 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400734 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300735 }
736 else
737 { /* Maybe we should support more than 8 bits ? */
738 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
739 }
740 }
741 else
742 {
743 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
744 }
745
746 bit_offset += no_of_bits;
747 pDescr++;
748 break;
749 }
750
751 case CSN_UINT_ARRAY:
752 {
753 guint8 no_of_bits = (guint8) pDescr->i;
754 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
755
756 if (pDescr->serialize.value != 0)
757 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
758 nCount = *pui16DATA(data, nCount);
759 }
760
761 if (remaining_bits_len >= no_of_bits)
762 {
763 remaining_bits_len -= (no_of_bits * nCount);
764 if (no_of_bits <= 8)
765 {
766 pui8 = pui8DATA(data, pDescr->offset);
767
768 while (nCount > 0)
769 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100770 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400771 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300772 pui8++;
773 bit_offset += no_of_bits;
774 nCount--;
775 }
776 }
777 else if (no_of_bits <= 16)
778 {
779 pui16 = pui16DATA(data, pDescr->offset);
780
781 while (nCount > 0)
782 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100783 *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400784 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300785 pui16++;
786 bit_offset += no_of_bits;
787 nCount--;
788 }
789 }
790 else if (no_of_bits <= 32)
791 { /* not supported */
792 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
793 }
794 else
795 {
796 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
797 }
798 }
799 else
800 {
801 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
802 }
803
804 pDescr++;
805 break;
806 }
807
808 case CSN_VARIABLE_TARRAY_OFFSET:
809 case CSN_VARIABLE_TARRAY:
810 case CSN_TYPE_ARRAY:
811 {
812 gint16 Status;
813 csnStream_t arT = *ar;
814 guint16 nCount = (guint16) pDescr->i;
815 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
816
817 pui8 = pui8DATA(data, pDescr->offset);
818
819 if (CSN_VARIABLE_TARRAY == pDescr->type)
820 { /* Count specified in field */
821 nCount = *pui8DATA(data, pDescr->i);
822 }
823 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
824 { /* Count specified in field */
825 nCount = *pui8DATA(data, pDescr->i);
826 nCount--; /* Offset 1 */
827 }
828
829 while (nCount--) /* Changed to handle length = 0. */
830 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400831 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300832 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100833 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300834 if (Status >= 0)
835 {
836 pui8 += nSize;
837 remaining_bits_len = arT.remaining_bits_len;
838 bit_offset = arT.bit_offset;
839 }
840 else
841 {
842 return Status;
843 }
844 }
845
846 pDescr++;
847 break;
848 }
849
850 case CSN_BITMAP:
851 { /* bitmap with given length. The result is left aligned! */
852 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
853
854 if (no_of_bits > 0)
855 {
856
857 if (no_of_bits <= 32)
858 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100859 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300860 pui32 = pui32DATA(data, pDescr->offset);
861 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300862 }
863 else if (no_of_bits <= 64)
864 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100865 guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300866 pui64 = pui64DATA(data, pDescr->offset);
867 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200868 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300869 }
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;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400889 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300890 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100891 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400892 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300893 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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100926 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300927 }
928 else
929 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100930 fExist = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300931 }
932
933 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400934 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300935 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 */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400955 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300956 { /* 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
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300961 /* Set the data member to "not exist" */
962 *pui8 = 0;
963 break;
964 }
965
966 /* the "regular" M_NEXT_EXIST description element */
967
968 fExist = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100969 if (bitvec_read_field(vector, &readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300970 {
971 fExist = 0x01;
972 }
973
974 *pui8 = fExist;
975 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400976 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300977 ++bit_offset;
978
979 if (fExist == 0)
980 { /* Skip 'i' entries */
981 pDescr += pDescr->i;
982 }
983
984 pDescr++;
985 break;
986 }
987
988 case CSN_NEXT_EXIST_LH:
989 {
990 guint8 fExist;
991 pui8 = pui8DATA(data, pDescr->offset);
992
993 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
994 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
995 { /* no more bits to decode is fine here - end of message detected and allowed */
996
997 /* skip 'i' entries + this entry */
998 pDescr += pDescr->i + 1;
999
1000 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1001 if ( pDescr->type != CSN_END )
1002 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1003 remaining_bits_len--;
1004 }
1005
1006 /* set the data member to "not exist" */
1007 *pui8 = 0;
1008 break;
1009 }
1010
1011 /* the "regular" M_NEXT_EXIST_LH description element */
1012 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001013 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001014 *pui8++ = fExist;
1015 remaining_bits_len -= 1;
1016
1017 bit_offset++;
1018
1019 if (fExist == 0)
1020 { /* Skip 'i' entries */
1021 pDescr += pDescr->i;
1022 }
1023 pDescr++;
1024
1025 break;
1026 }
1027
1028 case CSN_VARIABLE_BITMAP_1:
1029 { /* Bitmap from here and to the end of message */
1030
1031 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1032
1033 /*no break -
1034 * with a length set we have a regular variable length bitmap so we continue */
1035 }
1036
1037 case CSN_VARIABLE_BITMAP:
1038 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1039 * <N: bit (5)> <bitmap: bit(N + offset)>
1040 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1041 * The result is right aligned!
1042 */
1043 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1044
1045 no_of_bits += pDescr->i; /* adjusted by offset */
1046
1047 if (no_of_bits > 0)
1048 {
1049 remaining_bits_len -= no_of_bits;
1050
1051 if (remaining_bits_len < 0)
1052 {
1053 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1054 }
1055
1056 { /* extract bits */
1057 guint8* pui8 = pui8DATA(data, pDescr->offset);
1058 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1059
1060 if (nB1 > 0)
1061 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001062 *pui8 = bitvec_read_field(vector, &readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001063 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001064 pui8++;
1065 no_of_bits -= nB1;
1066 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1067 }
1068
1069 /* remaining no_of_bits is a multiple of 8 or 0 */
1070 while (no_of_bits > 0)
1071 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001072 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001073 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001074 pui8++;
1075 no_of_bits -= 8;
1076 }
1077 }
1078 }
1079 pDescr++;
1080 break;
1081 }
1082
1083 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1084 { /* Bitmap from here and to the end of message */
1085
1086 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1087
1088 /* no break -
1089 * with a length set we have a regular left aligned variable length bitmap so we continue
1090 */
1091 }
1092
1093 case CSN_LEFT_ALIGNED_VAR_BMP:
1094 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1095 * <N: bit (5)> <bitmap: bit(N + offset)>
1096 * bit array with length (in bits) specified in parameter (pDescr->descr)
1097 */
1098 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1099
1100 no_of_bits += pDescr->i;/* size adjusted by offset */
1101
1102 if (no_of_bits > 0)
1103 {
1104 remaining_bits_len -= no_of_bits;
1105
1106 if (remaining_bits_len < 0)
1107 {
1108 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1109 }
1110
1111 { /* extract bits */
1112 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001113
Neels Hofmeyr02415262016-09-02 02:15:26 +02001114 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001115 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001116 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001117 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001118 pui8++;
1119 no_of_bits -= 8;
1120 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001121 if (no_of_bits > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001122 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001123 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001124 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001125 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001126 bit_offset += no_of_bits;
1127 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001128 }
1129 }
1130 }
1131
1132 /* bitmap was successfully extracted or it was empty */
1133 pDescr++;
1134 break;
1135 }
1136
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001137 case CSN_PADDING_BITS:
1138 { /* Padding from here and to the end of message */
1139 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1140 if (remaining_bits_len > 0)
1141 {
1142 while (remaining_bits_len > 0)
1143 {
1144 guint8 bits_to_handle = remaining_bits_len%8;
1145 if (bits_to_handle > 0)
1146 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001147 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001148 remaining_bits_len -= bits_to_handle;
1149 bit_offset += bits_to_handle;
1150 }
1151 else if (bits_to_handle == 0)
1152 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001153 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001154 remaining_bits_len -= 8;
1155 bit_offset += 8;
1156 }
1157 }
1158 }
1159 if (remaining_bits_len < 0)
1160 {
1161 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1162 }
1163
1164 /* Padding was successfully extracted or it was empty */
1165 pDescr++;
1166 break;
1167 }
1168
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001169 case CSN_VARIABLE_ARRAY:
1170 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1171 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1172 * Array with length specified in parameter:
1173 * <count: bit (x)>
1174 * <list: octet(count + offset)>
1175 */
1176 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1177
1178 count += pDescr->i; /* Adjusted by offset */
1179
1180 if (count > 0)
1181 {
1182 remaining_bits_len -= count * 8;
1183
1184 if (remaining_bits_len < 0)
1185 {
1186 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1187 }
1188
1189 pui8 = pui8DATA(data, pDescr->offset);
1190
1191 while (count > 0)
1192 {
1193 readIndex -= 8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001194 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001195 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001196 pui8++;
1197 bit_offset += 8;
1198 count--;
1199 }
1200 }
1201
1202 pDescr++;
1203 break;
1204 }
1205
1206 case CSN_RECURSIVE_ARRAY:
1207 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1208 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1209 * where <element> ::= bit(value)
1210 * <tag> ::= 0 | 1
1211 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1212 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1213 * REMARK: recursive way to specify an array but an iterative implementation!
1214 */
1215 gint16 no_of_bits = pDescr->i;
1216 guint8 ElementCount = 0;
1217
1218 pui8 = pui8DATA(data, pDescr->offset);
1219
Alexander Couzensccde5c92017-02-04 03:10:08 +01001220 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001221 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001222 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001223 bit_offset++;
1224 remaining_bits_len--;
1225
1226 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001227 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001228 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001229 pui8++;
1230 remaining_bits_len -= no_of_bits;
1231 ElementCount++;
1232
1233 if (remaining_bits_len < 0)
1234 {
1235 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1236 }
1237
1238 bit_offset += no_of_bits;
1239 }
1240
Alexander Couzensccde5c92017-02-04 03:10:08 +01001241 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001242 /* existNextElement() returned FALSE, 1 bit consumed */
1243 bit_offset++;
1244
1245 /* Store the counted number of elements of the array */
1246 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1247
1248 pDescr++;
1249 break;
1250 }
1251
1252 case CSN_RECURSIVE_TARRAY:
1253 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1254 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1255 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1256 */
1257 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1258 guint8 ElementCount = 0;
1259 pui8 = pui8DATA(data, pDescr->offset);
1260
Alexander Couzensccde5c92017-02-04 03:10:08 +01001261 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001262 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001263 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001264 /* existNextElement() returned TRUE, 1 bit consumed */
1265 bit_offset++;
1266 remaining_bits_len--;
1267 ElementCount++;
1268
1269 { /* unpack the following data structure */
1270 csnStream_t arT = *ar;
1271 gint16 Status;
1272 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001273 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001274
1275 if (Status >= 0)
1276 { /* successful completion */
1277 pui8 += nSizeElement; /* -> to next data element */
1278 remaining_bits_len = arT.remaining_bits_len;
1279 bit_offset = arT.bit_offset;
1280 }
1281 else
1282 { /* something went awry */
1283 return Status;
1284 }
1285 }
1286
1287 if (remaining_bits_len < 0)
1288 {
1289 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1290 }
1291 }
1292
Alexander Couzensccde5c92017-02-04 03:10:08 +01001293 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001294
1295 /* existNextElement() returned FALSE, 1 bit consumed */
1296 bit_offset++;
1297
1298 /* Store the counted number of elements of the array */
1299 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1300
1301 pDescr++;
1302 break;
1303 }
1304
1305 case CSN_RECURSIVE_TARRAY_2:
1306 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1307
1308 Tag = REVERSED_TAG;
1309
1310 /* NO break -
1311 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1312 */
1313 }
1314
1315 case CSN_RECURSIVE_TARRAY_1:
1316 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1317 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1318 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1319 */
1320 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1321 guint8 ElementCount = 0;
1322 csnStream_t arT = *ar;
1323 gboolean EndOfList = FALSE;
1324 gint16 Status;
1325 pui8 = pui8DATA(data, pDescr->offset);
1326
1327 do
1328 { /* get data element */
1329 ElementCount++;
1330
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001331 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1332
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001333 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001334 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001335
1336 if (Status >= 0)
1337 { /* successful completion */
1338 pui8 += nSizeElement; /* -> to next */
1339 remaining_bits_len = arT.remaining_bits_len;
1340 bit_offset = arT.bit_offset;
1341 }
1342 else
1343 { /* something went awry */
1344 return Status;
1345 }
1346
1347 if (remaining_bits_len < 0)
1348 {
1349 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1350 }
1351
1352 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001353 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001354 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001355
1356 bit_offset++;
1357 remaining_bits_len--; /* 1 bit consumed (tag) */
1358 } while (!EndOfList);
1359
1360
1361 /* Store the count of the array */
1362 *pui8DATA(data, pDescr->i) = ElementCount;
1363 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1364 pDescr++;
1365 break;
1366 }
1367
1368 case CSN_FIXED:
1369 { /* Verify the fixed bits */
1370 guint8 no_of_bits = (guint8) pDescr->i;
1371 guint32 ui32;
1372
1373 if (no_of_bits <= 32)
1374 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001375 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001376 }
1377 else
1378 {
1379 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1380 }
1381 if (ui32 != (unsigned)(gint32)pDescr->offset)
1382 {
1383 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1384 }
1385
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001386 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001387 remaining_bits_len -= no_of_bits;
1388 bit_offset += no_of_bits;
1389 pDescr++;
1390 break;
1391 }
1392
1393 case CSN_CALLBACK:
1394 {
1395 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1396 break;
1397 }
1398
1399 case CSN_TRAP_ERROR:
1400 {
1401 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1402 }
1403
1404 case CSN_END:
1405 {
1406 ar->remaining_bits_len = remaining_bits_len;
1407 ar->bit_offset = bit_offset;
1408 return remaining_bits_len;
1409 }
1410
1411 default:
1412 {
1413 assert(0);
1414 }
1415
1416
1417 }
1418
1419 } while (remaining_bits_len >= 0);
1420
1421 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1422}
1423
1424
1425
1426
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001427gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001428{
1429 gint remaining_bits_len = ar->remaining_bits_len;
1430 gint bit_offset = ar->bit_offset;
1431 guint8* pui8;
1432 guint16* pui16;
1433 guint32* pui32;
1434 guint64* pui64;
1435
1436 guint8 Tag = STANDARD_TAG;
1437
1438 if (remaining_bits_len <= 0)
1439 {
1440 return 0;
1441 }
1442
1443 do
1444 {
1445 switch (pDescr->type)
1446 {
1447 case CSN_BIT:
1448 {
1449 if (remaining_bits_len > 0)
1450 {
1451 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001452 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001453 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001454 /* end add the bit value to protocol tree */
1455 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001456 else if(pDescr->may_be_null)
1457 {
1458 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1459 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001460 else
1461 {
1462 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1463 }
1464
1465 pDescr++;
1466 remaining_bits_len--;
1467 bit_offset++;
1468 break;
1469 }
1470
1471 case CSN_NULL:
1472 { /* Empty member! */
1473 pDescr++;
1474 break;
1475 }
1476
1477 case CSN_UINT:
1478 {
1479 guint8 no_of_bits = (guint8) pDescr->i;
1480
1481 if (remaining_bits_len >= no_of_bits)
1482 {
1483 if (no_of_bits <= 8)
1484 {
1485 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001486 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001487 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001488 }
1489 else if (no_of_bits <= 16)
1490 {
1491 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001492 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001493 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001494 }
1495 else if (no_of_bits <= 32)
1496 {
1497 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001498 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001499 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001500 }
1501 else
1502 {
1503 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1504 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001505
1506 remaining_bits_len -= no_of_bits;
1507 bit_offset += no_of_bits;
1508 }
1509 else if(pDescr->may_be_null)
1510 {
1511 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001512 }
1513 else
1514 {
1515 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1516 }
1517
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001518 pDescr++;
1519 break;
1520 }
1521
1522 case CSN_UINT_OFFSET:
1523 {
1524 guint8 no_of_bits = (guint8) pDescr->i;
1525
1526 if (remaining_bits_len >= no_of_bits)
1527 {
1528 if (no_of_bits <= 8)
1529 {
1530 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001531 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001532 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001533 }
1534 else if (no_of_bits <= 16)
1535 {
1536 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001537 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001538 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001539 }
1540 else if (no_of_bits <= 32)
1541 {
1542 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001543 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001544 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001545 }
1546 else
1547 {
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_LH:
1563 {
1564 guint8 no_of_bits = (guint8) pDescr->i;
1565
1566 if (remaining_bits_len >= no_of_bits)
1567 {
1568 remaining_bits_len -= no_of_bits;
1569 if (no_of_bits <= 8)
1570 {
1571 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001572 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001573 // TODO : Change get_masked_bits8()
1574 writeIndex -= no_of_bits;
1575 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1576 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001577 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001578 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001579
1580 }
1581 else
1582 {/* Maybe we should support more than 8 bits ? */
1583 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1584 }
1585 }
1586 else
1587 {
1588 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1589 }
1590
1591 remaining_bits_len -= no_of_bits;
1592 bit_offset += no_of_bits;
1593 pDescr++;
1594 break;
1595 }
1596
1597 case CSN_UINT_ARRAY:
1598 {
1599 guint8 no_of_bits = (guint8) pDescr->i;
1600 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1601
1602 if (pDescr->serialize.value != 0)
1603 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1604 nCount = *pui16DATA(data, nCount);
1605 }
1606
1607 if (remaining_bits_len >= no_of_bits)
1608 {
1609 remaining_bits_len -= (no_of_bits*nCount);
1610 if (no_of_bits <= 8)
1611 {
1612 pui8 = pui8DATA(data, pDescr->offset);
1613 do
1614 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001615 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001616 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001617 pui8++;
1618 bit_offset += no_of_bits;
1619 } while (--nCount > 0);
1620 }
1621 else if (no_of_bits <= 16)
1622 {
1623 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1624 }
1625 else if (no_of_bits <= 32)
1626 {
1627 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1628 }
1629 else
1630 {
1631 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1632 }
1633 }
1634 else
1635 {
1636 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1637 }
1638 pDescr++;
1639 break;
1640 }
1641
1642 case CSN_VARIABLE_TARRAY_OFFSET:
1643 case CSN_VARIABLE_TARRAY:
1644 case CSN_TYPE_ARRAY:
1645 {
1646 gint16 Status;
1647 csnStream_t arT = *ar;
1648 gint16 nCount = pDescr->i;
1649 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1650
1651 pui8 = pui8DATA(data, pDescr->offset);
1652 if (pDescr->type == CSN_VARIABLE_TARRAY)
1653 { /* Count specified in field */
1654 nCount = *pui8DATA(data, pDescr->i);
1655 }
1656 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1657 { /* Count specified in field */
1658 nCount = *pui8DATA(data, pDescr->i);
1659 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1660 }
1661
1662 while (nCount > 0)
1663 { /* resulting array of length 0 is possible
1664 * but no bits shall be read from bitstream
1665 */
1666
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001667 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001668 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1669 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1670 if (Status >= 0)
1671 {
1672 pui8 += nSize;
1673 remaining_bits_len = arT.remaining_bits_len;
1674 bit_offset = arT.bit_offset;
1675
1676 }
1677 else
1678 {
1679 return Status;
1680 }
1681 nCount--;
1682 }
1683
1684 pDescr++;
1685 break;
1686 }
1687
1688 case CSN_BITMAP:
1689 { /* bitmap with given length. The result is left aligned! */
1690 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1691
1692 if (no_of_bits > 0)
1693 {
1694
1695 if (no_of_bits <= 32)
1696 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001697 for(unsigned ib = 0; ib < 4; ib++)
1698 {
1699 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001700 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001701 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001702 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001703 }
1704 else if (no_of_bits <= 64)
1705 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001706 for(unsigned ib = 0; ib < 8; ib++)
1707 {
1708 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001709 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001710 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001711 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001712 }
1713 else
1714 {
1715 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1716 }
1717
1718 remaining_bits_len -= no_of_bits;
1719 assert(remaining_bits_len >= 0);
1720 bit_offset += no_of_bits;
1721 }
1722 /* bitmap was successfully extracted or it was empty */
1723
1724 pDescr++;
1725 break;
1726 }
1727
1728 case CSN_TYPE:
1729 {
1730 gint16 Status;
1731 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001732 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001733 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1734 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001735 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001736 if (Status >= 0)
1737 {
1738
1739 remaining_bits_len = arT.remaining_bits_len;
1740 bit_offset = arT.bit_offset;
1741 pDescr++;
1742 }
1743 else
1744 {
1745 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1746 return Status;
1747 }
1748
1749 break;
1750 }
1751
1752 case CSN_CHOICE:
1753 {
1754 //gint16 count = pDescr->i;
1755 guint8 i = 0;
1756 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1757
1758 pui8 = pui8DATA(data, pDescr->offset);
1759 i = *pui8;
1760 pChoice += i;
1761 guint8 no_of_bits = pChoice->bits;
1762 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001763 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001764 bitvec_write_field(vector, &writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001765
1766 CSN_DESCR descr[2];
1767 gint16 Status;
1768 csnStream_t arT = *ar;
1769
1770 descr[0] = pChoice->descr;
1771 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1772 descr[1].type = CSN_END;
1773 bit_offset += no_of_bits;
1774 remaining_bits_len -= no_of_bits;
1775
1776 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1777 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1778
1779 if (Status >= 0)
1780 {
1781 remaining_bits_len = arT.remaining_bits_len;
1782 bit_offset = arT.bit_offset;
1783 }
1784 else
1785 {
1786 return Status;
1787 }
1788
1789 pDescr++;
1790 break;
1791 }
1792
1793 case CSN_SERIALIZE:
1794 {
1795 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1796 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001797 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001798 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001799 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001800
1801 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001802 lengthIndex = writeIndex;
1803 writeIndex += length_len;
1804 bit_offset += length_len;
1805 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001806 arT.direction = 0;
1807 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1808 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001809
Alexander Couzensccde5c92017-02-04 03:10:08 +01001810 bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001811 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001812
1813 if (Status >= 0)
1814 {
1815 remaining_bits_len = arT.remaining_bits_len;
1816 bit_offset = arT.bit_offset;
1817 pDescr++;
1818 }
1819 else
1820 {
1821 // Has already been processed:
1822 return Status;
1823 }
1824
1825 break;
1826 }
1827
1828 case CSN_UNION_LH:
1829 case CSN_UNION:
1830 {
1831 gint16 Bits;
1832 guint8 index;
1833 gint16 count = pDescr->i;
1834 const CSN_DESCR* pDescrNext = pDescr;
1835
1836 pDescrNext += count + 1; /* now this is next after the union */
1837 if ((count <= 0) || (count > 16))
1838 {
1839 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1840 }
1841
1842 /* Now get the bits to extract the index */
1843 Bits = ixBitsTab[count];
1844 index = 0;
1845
1846 /* Assign UnionType */
1847 pui8 = pui8DATA(data, pDescr->offset);
1848 //read index from data and write to vector
Alexander Couzensccde5c92017-02-04 03:10:08 +01001849 bitvec_write_field(vector, &writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001850
1851 //decode index
1852 writeIndex -= Bits;
1853
1854 while (Bits > 0)
1855 {
1856 index <<= 1;
1857
1858 if (CSN_UNION_LH == pDescr->type)
1859 {
1860 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1861 }
1862 else
1863 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001864 index |= bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001865 }
1866
1867 remaining_bits_len--;
1868 bit_offset++;
1869 Bits--;
1870 }
1871
1872 writeIndex -= Bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001873 bitvec_write_field(vector, &writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001874
1875
1876 /* script index to continue on, limited in case we do not have a power of 2 */
1877 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001878 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001879
1880 switch (pDescr->type)
1881 { /* get the right element of the union based on computed index */
1882
1883 case CSN_BIT:
1884 {
1885 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001886 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001887 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001888 remaining_bits_len -= 1;
1889 bit_offset++;
1890 pDescr++;
1891 break;
1892 }
1893
1894 case CSN_NULL:
1895 { /* Empty member! */
1896 pDescr++;
1897 break;
1898 }
1899
1900 case CSN_UINT:
1901 {
1902 guint8 no_of_bits = (guint8) pDescr->i;
1903 if (remaining_bits_len >= no_of_bits)
1904 {
1905 remaining_bits_len -= no_of_bits;
1906
1907 if (no_of_bits <= 8)
1908 {
1909 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001910 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001911 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001912 }
1913 else if (no_of_bits <= 16)
1914 {
1915 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001916 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001917 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001918 }
1919 else if (no_of_bits <= 32)
1920 {
1921 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001922 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001923 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001924 }
1925 else
1926 {
1927 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1928 }
1929 }
1930 else
1931 {
1932 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1933 }
1934
1935 bit_offset += no_of_bits;
1936 pDescr++;
1937 break;
1938 }
1939
1940 case CSN_UINT_OFFSET:
1941 {
1942 guint8 no_of_bits = (guint8) pDescr->i;
1943
1944 if (remaining_bits_len >= no_of_bits)
1945 {
1946 if (no_of_bits <= 8)
1947 {
1948 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001949 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001950 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001951 }
1952 else if (no_of_bits <= 16)
1953 {
1954 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001955 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001956 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001957 }
1958 else if (no_of_bits <= 32)
1959 {
1960 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001961 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001962 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001963 }
1964 else
1965 {
1966 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1967 }
1968 }
1969 else
1970 {
1971 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1972 }
1973
1974 remaining_bits_len -= no_of_bits;
1975 bit_offset += no_of_bits;
1976 pDescr++;
1977 break;
1978 }
1979
1980 case CSN_UINT_LH:
1981 {
1982 guint8 no_of_bits = (guint8) pDescr->i;
1983
1984 if (remaining_bits_len >= no_of_bits)
1985 {
1986 remaining_bits_len -= no_of_bits;
1987 if (no_of_bits <= 8)
1988 {
1989 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001990 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001991 // TODO : Change get_masked_bits8()
1992 writeIndex -= no_of_bits;
1993 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1994 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001995 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001996 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001997
1998 }
1999 else
2000 {/* Maybe we should support more than 8 bits ? */
2001 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2002 }
2003 }
2004 else
2005 {
2006 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2007 }
2008
2009 remaining_bits_len -= no_of_bits;
2010 bit_offset += no_of_bits;
2011 pDescr++;
2012 break;
2013 }
2014
2015 case CSN_UINT_ARRAY:
2016 {
2017 guint8 no_of_bits = (guint8) pDescr->i;
2018 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2019
2020 if (pDescr->serialize.value != 0)
2021 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2022 nCount = *pui16DATA(data, nCount);
2023 }
2024
2025 if (remaining_bits_len >= no_of_bits)
2026 {
2027 remaining_bits_len -= (no_of_bits*nCount);
2028 if (no_of_bits <= 8)
2029 {
2030 pui8 = pui8DATA(data, pDescr->offset);
2031 do
2032 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002033 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002034 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002035 pui8++;
2036 bit_offset += no_of_bits;
2037 } while (--nCount > 0);
2038 }
2039 else if (no_of_bits <= 16)
2040 {
2041 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2042 }
2043 else if (no_of_bits <= 32)
2044 {
2045 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2046 }
2047 else
2048 {
2049 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2050 }
2051 }
2052 else
2053 {
2054 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2055 }
2056 pDescr++;
2057 break;
2058 }
2059
2060 case CSN_VARIABLE_TARRAY_OFFSET:
2061 case CSN_VARIABLE_TARRAY:
2062 case CSN_TYPE_ARRAY:
2063 {
2064 gint16 Status;
2065 csnStream_t arT = *ar;
2066 gint16 nCount = pDescr->i;
2067 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2068
2069 pui8 = pui8DATA(data, pDescr->offset);
2070 if (pDescr->type == CSN_VARIABLE_TARRAY)
2071 { /* Count specified in field */
2072 nCount = *pui8DATA(data, pDescr->i);
2073 }
2074 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2075 { /* Count specified in field */
2076 nCount = *pui8DATA(data, pDescr->i);
2077 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2078 }
2079
2080 while (nCount > 0)
2081 { /* resulting array of length 0 is possible
2082 * but no bits shall be read from bitstream
2083 */
2084
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002085 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002086 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2087 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2088 if (Status >= 0)
2089 {
2090 pui8 += nSize;
2091 remaining_bits_len = arT.remaining_bits_len;
2092 bit_offset = arT.bit_offset;
2093 }
2094 else
2095 {
2096 return Status;
2097 }
2098 nCount--;
2099 }
2100
2101 pDescr++;
2102 break;
2103 }
2104
2105 case CSN_BITMAP:
2106 { /* bitmap with given length. The result is left aligned! */
2107 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2108
2109 if (no_of_bits > 0)
2110 {
2111
2112 if (no_of_bits <= 32)
2113 {
2114 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002115 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002116 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002117 }
2118 else if (no_of_bits <= 64)
2119 {
2120 pui64 = pui64DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002121 bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002122 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002123 }
2124 else
2125 {
2126 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2127 }
2128
2129 remaining_bits_len -= no_of_bits;
2130 assert(remaining_bits_len >= 0);
2131 bit_offset += no_of_bits;
2132 }
2133 /* bitmap was successfully extracted or it was empty */
2134
2135 pDescr++;
2136 break;
2137 }
2138
2139 case CSN_TYPE:
2140 {
2141 gint16 Status;
2142 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002143 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002144 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2145 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002146 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002147 if (Status >= 0)
2148 {
2149 remaining_bits_len = arT.remaining_bits_len;
2150 bit_offset = arT.bit_offset;
2151 pDescr++;
2152 }
2153 else
2154 {
2155 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2156 return Status;
2157 }
2158
2159 break;
2160 }
2161
2162 default:
2163 { /* descriptions of union elements other than above are illegal */
2164 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2165 }
2166 }
2167
2168 pDescr = pDescrNext;
2169 break;
2170 }
2171
2172 case CSN_EXIST:
2173 case CSN_EXIST_LH:
2174 {
2175 guint8 fExist;
2176 unsigned exist = 0;
2177 pui8 = pui8DATA(data, pDescr->offset);
2178 exist = *pui8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002179 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002180 writeIndex--;
2181 if (CSN_EXIST_LH == pDescr->type)
2182 {
2183 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2184 }
2185 else
2186 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002187 fExist = bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002188 }
2189 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002190 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002191 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002192 pDescr++;
2193 remaining_bits_len -= 1;
2194
2195 if (!exist)
2196 {
2197 ar->remaining_bits_len = remaining_bits_len;
2198 ar->bit_offset = bit_offset;
2199 return remaining_bits_len;
2200 }
2201 break;
2202 }
2203
2204 case CSN_NEXT_EXIST:
2205 {
2206 guint8 fExist;
2207
2208 pui8 = pui8DATA(data, pDescr->offset);
2209
2210 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002211 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002212 { /* no more bits to decode is fine here - end of message detected and allowed */
2213
2214 /* Skip i entries + this entry */
2215 pDescr += pDescr->i + 1;
2216
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002217 break;
2218 }
2219
Alexander Couzensccde5c92017-02-04 03:10:08 +01002220 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002221 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002222 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002223 remaining_bits_len -= 1;
2224
2225 ++bit_offset;
2226
2227 if (fExist == 0)
2228 { /* Skip 'i' entries */
2229 pDescr += pDescr->i;
2230 }
2231
2232 pDescr++;
2233 break;
2234 }
2235
2236 case CSN_NEXT_EXIST_LH:
2237 {
2238 guint8 fExist;
2239 pui8 = pui8DATA(data, pDescr->offset);
2240
2241 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2242 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2243 { /* no more bits to decode is fine here - end of message detected and allowed */
2244
2245 /* skip 'i' entries + this entry */
2246 pDescr += pDescr->i + 1;
2247
2248 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2249 if ( pDescr->type != CSN_END )
2250 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2251 remaining_bits_len--;
2252 }
2253
2254 /* set the data member to "not exist" */
2255 //*pui8 = 0;
2256 break;
2257 }
2258
2259 /* the "regular" M_NEXT_EXIST_LH description element */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002260 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002261 writeIndex--;
2262 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2263 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002264 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002265 pui8++;
2266 remaining_bits_len -= 1;
2267
2268 bit_offset++;
2269
2270 if (fExist == 0)
2271 { /* Skip 'i' entries */
2272 pDescr += pDescr->i;
2273 }
2274 pDescr++;
2275
2276 break;
2277 }
2278
2279 case CSN_VARIABLE_BITMAP_1:
2280 { /* Bitmap from here and to the end of message */
2281
2282 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2283
2284 /*no break -
2285 * with a length set we have a regular variable length bitmap so we continue */
2286 }
2287
2288 case CSN_VARIABLE_BITMAP:
2289 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2290 * <N: bit (5)> <bitmap: bit(N + offset)>
2291 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2292 * The result is right aligned!
2293 */
2294 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2295
2296 no_of_bits += pDescr->i; /* adjusted by offset */
2297
2298 if (no_of_bits > 0)
2299 {
2300 remaining_bits_len -= no_of_bits;
2301
2302 if (remaining_bits_len < 0)
2303 {
2304 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2305 }
2306
2307 { /* extract bits */
2308 guint8* pui8 = pui8DATA(data, pDescr->offset);
2309 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2310
2311 if (nB1 > 0)
2312 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002313 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002315 pui8++;
2316 no_of_bits -= nB1;
2317 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2318 }
2319
2320 /* remaining no_of_bits is a multiple of 8 or 0 */
2321 while (no_of_bits > 0)
2322 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002323 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002324 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002325 pui8++;
2326 no_of_bits -= 8;
2327 }
2328 }
2329 }
2330 pDescr++;
2331 break;
2332 }
2333
2334 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2335 { /* Bitmap from here and to the end of message */
2336
2337 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2338
2339 /* no break -
2340 * with a length set we have a regular left aligned variable length bitmap so we continue
2341 */
2342 }
2343
2344 case CSN_LEFT_ALIGNED_VAR_BMP:
2345 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2346 * <N: bit (5)> <bitmap: bit(N + offset)>
2347 * bit array with length (in bits) specified in parameter (pDescr->descr)
2348 */
2349
2350 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2351
2352 no_of_bits += pDescr->i;/* size adjusted by offset */
2353
2354 if (no_of_bits > 0)
2355 {
2356 remaining_bits_len -= no_of_bits;
2357
2358 if (remaining_bits_len < 0)
2359 {
2360 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2361 }
2362
2363 { /* extract bits */
2364 guint8* pui8 = pui8DATA(data, pDescr->offset);
2365 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2366
2367 while (no_of_bits > 0)
2368 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002369 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002370 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002371 pui8++;
2372 no_of_bits -= 8;
2373 }
2374 if (nB1 > 0)
2375 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002376 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002377 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002378 pui8++;
2379 no_of_bits -= nB1;
2380 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2381 }
2382 }
2383
2384 }
2385
2386 /* bitmap was successfully extracted or it was empty */
2387 pDescr++;
2388 break;
2389 }
2390
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002391 case CSN_PADDING_BITS:
2392 { /* Padding from here and to the end of message */
2393 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2394 guint8 filler = 0x2b;
2395 if (remaining_bits_len > 0)
2396 {
2397 while (remaining_bits_len > 0)
2398 {
2399 guint8 bits_to_handle = remaining_bits_len%8;
2400 if (bits_to_handle > 0)
2401 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302402 /* section 11 of 44.060
2403 * The padding bits may be the 'null' string. Otherwise, the
2404 * padding bits starts with bit '0', followed by 'spare padding'
2405 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2406 */
2407 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Alexander Couzensccde5c92017-02-04 03:10:08 +01002408 bitvec_write_field(vector, &writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002409 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2410 remaining_bits_len -= bits_to_handle;
2411 bit_offset += bits_to_handle;
2412 }
2413 else if (bits_to_handle == 0)
2414 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002415 bitvec_write_field(vector, &writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002416 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2417 remaining_bits_len -= 8;
2418 bit_offset += 8;
2419 }
2420 }
2421 }
2422 if (remaining_bits_len < 0)
2423 {
2424 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2425 }
2426
2427 /* Padding was successfully extracted or it was empty */
2428 pDescr++;
2429 break;
2430 }
2431
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002432 case CSN_VARIABLE_ARRAY:
2433 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2434 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2435 * Array with length specified in parameter:
2436 * <count: bit (x)>
2437 * <list: octet(count + offset)>
2438 */
2439 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2440
2441 count += pDescr->i; /* Adjusted by offset */
2442
2443 if (count > 0)
2444 {
2445 remaining_bits_len -= count * 8;
2446
2447 if (remaining_bits_len < 0)
2448 {
2449 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2450 }
2451
2452 pui8 = pui8DATA(data, pDescr->offset);
2453
2454 while (count > 0)
2455 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002456 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002457 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002458 pui8++;
2459 bit_offset += 8;
2460 count--;
2461 }
2462 }
2463
2464 pDescr++;
2465 break;
2466 }
2467
2468 case CSN_RECURSIVE_ARRAY:
2469 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2470 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2471 * where <element> ::= bit(value)
2472 * <tag> ::= 0 | 1
2473 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2474 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2475 * REMARK: recursive way to specify an array but an iterative implementation!
2476 */
2477 gint16 no_of_bits = pDescr->i;
2478 guint8 ElementCount = 0;
2479 pui8 = pui8DATA(data, pDescr->offset);
2480 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2481 while (ElementCount > 0)
2482 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002483 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002484 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002485 bit_offset++;
2486 remaining_bits_len--;
2487
2488 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002489 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002490 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002491 pui8++;
2492 remaining_bits_len -= no_of_bits;
2493 ElementCount--;
2494
2495 if (remaining_bits_len < 0)
2496 {
2497 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2498 }
2499
2500 bit_offset += no_of_bits;
2501 }
2502
Alexander Couzensccde5c92017-02-04 03:10:08 +01002503 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002504 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002505 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302506 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002507
2508 pDescr++;
2509 break;
2510 }
2511
2512 case CSN_RECURSIVE_TARRAY:
2513 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2514 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2515 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2516 */
2517 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2518 guint8 ElementCount = 0;
2519 pui8 = pui8DATA(data, pDescr->offset);
2520 /* Store the counted number of elements of the array */
2521 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2522
2523 while (ElementCount > 0)
2524 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002525 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002526 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002527 bit_offset++;
2528
2529 remaining_bits_len--;
2530 ElementCount--;
2531
2532 { /* unpack the following data structure */
2533 csnStream_t arT = *ar;
2534 gint16 Status;
2535 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002536 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002537
2538 if (Status >= 0)
2539 { /* successful completion */
2540 pui8 += nSizeElement; /* -> to next data element */
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
2550 if (remaining_bits_len < 0)
2551 {
2552 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2553 }
2554 }
2555
Alexander Couzensccde5c92017-02-04 03:10:08 +01002556 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002557 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002558 bit_offset++;
2559
2560 pDescr++;
2561 break;
2562 }
2563
2564 case CSN_RECURSIVE_TARRAY_2:
2565 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2566
2567 Tag = REVERSED_TAG;
2568
2569 /* NO break -
2570 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2571 */
2572 }
2573
2574 case CSN_RECURSIVE_TARRAY_1:
2575 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2576 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2577 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2578 */
2579 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2580 guint8 ElementCount = 0;
2581 guint8 ElementNum = 0;
2582 csnStream_t arT = *ar;
2583 gint16 Status;
2584
2585 pui8 = pui8DATA(data, pDescr->offset);
2586 /* Store the count of the array */
2587 ElementCount = *pui8DATA(data, pDescr->i);
2588 ElementNum = ElementCount;
2589
2590 while (ElementCount > 0)
2591 { /* get data element */
2592 if (ElementCount != ElementNum)
2593 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002594 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002595 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002596 bit_offset++;
2597 remaining_bits_len--;
2598 }
2599 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002600 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002601 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002602 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002603 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002604 if (Status >= 0)
2605 { /* successful completion */
2606 pui8 += nSizeElement; /* -> to next */
2607 remaining_bits_len = arT.remaining_bits_len;
2608 bit_offset = arT.bit_offset;
2609 }
2610 else
2611 { /* something went awry */
2612 return Status;
2613 }
2614
2615 if (remaining_bits_len < 0)
2616 {
2617 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2618 }
2619
2620 }
Alexander Couzensccde5c92017-02-04 03:10:08 +01002621 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002622 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002623 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002624 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2625 pDescr++;
2626 break;
2627 }
2628
2629 case CSN_FIXED:
2630 { /* Verify the fixed bits */
2631 guint8 no_of_bits = (guint8) pDescr->i;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002632 bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002633 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002634 remaining_bits_len -= no_of_bits;
2635 bit_offset += no_of_bits;
2636 pDescr++;
2637 break;
2638 }
2639
2640 case CSN_CALLBACK:
2641 {
2642 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2643 break;
2644 }
2645
2646 case CSN_TRAP_ERROR:
2647 {
2648 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2649 }
2650
2651 case CSN_END:
2652 {
2653 ar->remaining_bits_len = remaining_bits_len;
2654 ar->bit_offset = bit_offset;
2655 return remaining_bits_len;
2656 }
2657
2658 default:
2659 {
2660 assert(0);
2661 }
2662
2663 }
2664
2665 } while (remaining_bits_len >= 0);
2666
2667 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2668}
2669