blob: 2f8bd03e394178ff22936228c6bfbbebddda77c8 [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
Pau Espin Pedrold636f742020-02-03 15:37:08 +010040extern "C" {
41#include <osmocom/core/logging.h>
42#include <osmocom/core/utils.h>
43}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030044
45#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
46#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
47#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
48#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
49#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
50/* used to tag existence of next element in variable length lists */
51#define STANDARD_TAG 1
52#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030053
54using namespace std;
55static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
56
57
58/* Returns no_of_bits (up to 8) masked with 0x2B */
59
60static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040061get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030062{
63 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
64 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
65 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
66 guint8 result;
67 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
68 readIndex -= relative_bit_offset;
69 if (bit_shift >= 0)
70 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010071 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030072 readIndex-= bit_shift;
73 result &= maskBits[no_of_bits];
74 }
75 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010076 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010077 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030078 hight_part = (guint8) (hight_part << (-bit_shift));
Alexander Couzensccde5c92017-02-04 03:10:08 +010079 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030080 readIndex = readIndex - (8 - (-bit_shift));
81 result |= hight_part;
82 }
83 return result;
84}
85
86/**
87 * ================================================================================================
88 * set initial/start values in help data structure used for packing/unpacking operation
89 * ================================================================================================
90 */
91void
92csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
93{
94 ar->remaining_bits_len = remaining_bits_len;
95 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040096 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030097}
98
Pau Espin Pedrold636f742020-02-03 15:37:08 +010099static const struct value_string csn1_error_names[] = {
100 { CSN_OK, "General 0" },
101 { CSN_ERROR_GENERAL, "General -1" },
102 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
103 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
104 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
105 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
106 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "ILLEGAL BIT VALUE" },
107 { CSN_ERROR_ILLEGAL_BIT_VALUE, "Internal" },
108 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
109 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
110 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111};
112
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100113
114static gint16 ProcessError_impl(const char *file, int line, unsigned readIndex,
115 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116{
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100117 if (err != CSN_OK)
118 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %d)\n",
119 sz, get_value_string(csn1_error_names, err), err,
120 pDescr ? pDescr->sz : "-", readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300121 return err;
122}
123
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100124#define ProcessError(readIndex, sz, err, pDescr) \
125 ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
126
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300127
128/**
129 * ================================================================================================
130 * Return TRUE if tag in bit stream indicates existence of next list element,
131 * otherwise return FALSE.
132 * Will work for tag values equal to both 0 and 1.
133 * ================================================================================================
134 */
135
136static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400137existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300138{
Alexander Couzensccde5c92017-02-04 03:10:08 +0100139 guint8 res = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300140 if (Tag == STANDARD_TAG)
141 {
142 return (res > 0);
143 }
144 return (res == 0);
145}
146
147
148gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400149csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300150{
151 gint remaining_bits_len = ar->remaining_bits_len;
152 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100153 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300154 guint16* pui16;
155 guint32* pui32;
156 guint64* pui64;
157 guint8 Tag = STANDARD_TAG;
158
159 if (remaining_bits_len <= 0)
160 {
161 return 0;
162 }
163
164 do
165 {
166 switch (pDescr->type)
167 {
168 case CSN_BIT:
169 {
170 if (remaining_bits_len > 0)
171 {
172 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100173 *pui8 = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400174 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300175 /* end add the bit value to protocol tree */
176 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400177 else if(pDescr->may_be_null)
178 {
179 pui8 = pui8DATA(data, pDescr->offset);
180 *pui8 = 0;
181 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
182 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300183 else
184 {
185 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
186 }
187
188 pDescr++;
189 remaining_bits_len--;
190 bit_offset++;
191 break;
192 }
193
194 case CSN_NULL:
195 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100196 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300197 pDescr++;
198 break;
199 }
200
201 case CSN_UINT:
202 {
203 guint8 no_of_bits = (guint8) pDescr->i;
204
205 if (remaining_bits_len >= no_of_bits)
206 {
207 if (no_of_bits <= 8)
208 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100209 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300210 pui8 = pui8DATA(data, pDescr->offset);
211 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400212 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300213 }
214 else if (no_of_bits <= 16)
215 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100216 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300217 pui16 = pui16DATA(data, pDescr->offset);
218 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400219 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300220 }
221 else if (no_of_bits <= 32)
222 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100223 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300224 pui32 = pui32DATA(data, pDescr->offset);
225 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400226 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300227 }
228 else
229 {
230 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
231 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400232 remaining_bits_len -= no_of_bits;
233 bit_offset += no_of_bits;
234 }
235 else if(pDescr->may_be_null)
236 {
237 if (no_of_bits <= 8)
238 {
239 pui8 = pui8DATA(data, pDescr->offset);
240 *pui8 = 0;
241 }
242 else if (no_of_bits <= 16)
243 {
244 pui16 = pui16DATA(data, pDescr->offset);
245 *pui16 = 0;
246 }
247 else if (no_of_bits <= 32)
248 {
249 pui32 = pui32DATA(data, pDescr->offset);
250 *pui32 = 0;
251 }
252 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300253 }
254 else
255 {
256 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
257 }
258
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300259 pDescr++;
260 break;
261 }
262
263 case CSN_UINT_OFFSET:
264 {
265 guint8 no_of_bits = (guint8) pDescr->i;
266
267 if (remaining_bits_len >= no_of_bits)
268 {
269 if (no_of_bits <= 8)
270 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100271 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300272 pui8 = pui8DATA(data, pDescr->offset);
273 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400274 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300275 }
276 else if (no_of_bits <= 16)
277 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100278 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300279 pui16 = pui16DATA(data, pDescr->offset);
280 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400281 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300282 }
283 else if (no_of_bits <= 32)
284 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100285 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300286 pui32 = pui32DATA(data, pDescr->offset);
287 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400288 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300289 }
290 else
291 {
292 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
293 }
294 }
295 else
296 {
297 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
298 }
299
300 remaining_bits_len -= no_of_bits;
301 bit_offset += no_of_bits;
302 pDescr++;
303 break;
304 }
305
306 case CSN_UINT_LH:
307 {
308 guint8 no_of_bits = (guint8) pDescr->i;
309
310 if (remaining_bits_len >= no_of_bits)
311 {
312 remaining_bits_len -= no_of_bits;
313 if (no_of_bits <= 8)
314 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100315 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300316 pui8 = pui8DATA(data, pDescr->offset);
317 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400318 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300319 }
320 else
321 {/* Maybe we should support more than 8 bits ? */
322 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
323 }
324 }
325 else
326 {
327 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
328 }
329
330 remaining_bits_len -= no_of_bits;
331 bit_offset += no_of_bits;
332 pDescr++;
333 break;
334 }
335
336 case CSN_UINT_ARRAY:
337 {
338 guint8 no_of_bits = (guint8) pDescr->i;
339 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
340
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100341 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300342 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
343 nCount = *pui16DATA(data, nCount);
344 }
345
346 if (remaining_bits_len >= no_of_bits)
347 {
348 remaining_bits_len -= (no_of_bits*nCount);
349 if (no_of_bits <= 8)
350 {
351 pui8 = pui8DATA(data, pDescr->offset);
352 do
353 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100354 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400355 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300356 pui8++;
357 bit_offset += no_of_bits;
358 } while (--nCount > 0);
359 }
360 else if (no_of_bits <= 16)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else if (no_of_bits <= 32)
365 {
366 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
367 }
368 else
369 {
370 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
371 }
372 }
373 else
374 {
375 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
376 }
377 pDescr++;
378 break;
379 }
380
381 case CSN_VARIABLE_TARRAY_OFFSET:
382 case CSN_VARIABLE_TARRAY:
383 case CSN_TYPE_ARRAY:
384 {
385 gint16 Status;
386 csnStream_t arT = *ar;
387 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100388 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300389
390 pui8 = pui8DATA(data, pDescr->offset);
391 if (pDescr->type == CSN_VARIABLE_TARRAY)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 }
395 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
396 { /* Count specified in field */
397 nCount = *pui8DATA(data, pDescr->i);
398 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
399 }
400
401 while (nCount > 0)
402 { /* resulting array of length 0 is possible
403 * but no bits shall be read from bitstream
404 */
405
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400406 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300407 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100408 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300409 if (Status >= 0)
410 {
411 pui8 += nSize;
412 remaining_bits_len = arT.remaining_bits_len;
413 bit_offset = arT.bit_offset;
414 }
415 else
416 {
417 return Status;
418 }
419 nCount--;
420 }
421
422 pDescr++;
423 break;
424 }
425
426 case CSN_BITMAP:
427 { /* bitmap with given length. The result is left aligned! */
428 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
429
430 if (no_of_bits > 0)
431 {
432
433 if (no_of_bits <= 32)
434 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400435 for(unsigned ib = 0; ib < 4; ib++)
436 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100437 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400438 pui8 = pui8DATA(data, pDescr->offset+ib);
439 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400440 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400441 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300442 }
443 else if (no_of_bits <= 64)
444 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400445 for(unsigned ib = 0; ib < 8; ib++)
446 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100447 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400448 pui8 = pui8DATA(data, pDescr->offset+ib);
449 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400450 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400451 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300452 }
453 else
454 {
455 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
456 }
457
458 remaining_bits_len -= no_of_bits;
459 assert(remaining_bits_len >= 0);
460 bit_offset += no_of_bits;
461 }
462 /* bitmap was successfully extracted or it was empty */
463
464 pDescr++;
465 break;
466 }
467
468 case CSN_TYPE:
469 {
470 gint16 Status;
471 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400472 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300473 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100474 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400475 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300476 if (Status >= 0)
477 {
478 remaining_bits_len = arT.remaining_bits_len;
479 bit_offset = arT.bit_offset;
480 pDescr++;
481 }
482 else
483 {
484 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
485 return Status;
486 }
487
488 break;
489 }
490
491 case CSN_CHOICE:
492 {
493 gint16 count = pDescr->i;
494 guint8 i = 0;
495 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
496
497 while (count > 0)
498 {
499 guint8 no_of_bits = pChoice->bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100500 guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300501 if (value == pChoice->value)
502 {
503 CSN_DESCR descr[2];
504 gint16 Status;
505 csnStream_t arT = *ar;
506
507 descr[0] = pChoice->descr;
508 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
509 descr[1].type = CSN_END;
510 pui8 = pui8DATA(data, pDescr->offset);
511 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400512 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100513 if (!pChoice->keep_bits) {
514 bit_offset += no_of_bits;
515 remaining_bits_len -= no_of_bits;
516 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300517
518 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100519 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300520
521 if (Status >= 0)
522 {
523 remaining_bits_len = arT.remaining_bits_len;
524 bit_offset = arT.bit_offset;
525 }
526 else
527 {
528 return Status;
529 }
530 break;
531 }
532
533 readIndex -= no_of_bits;
534 count--;
535 pChoice++;
536 i++;
537 }
538
539 pDescr++;
540 break;
541 }
542
543 case CSN_SERIALIZE:
544 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100545 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300546 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400547 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300548 gint16 Status = -1;
549
Alexander Couzensccde5c92017-02-04 03:10:08 +0100550 guint8 length = bitvec_read_field(vector, &readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300551
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400552 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400553 bit_offset += length_len;
554 remaining_bits_len -= length_len;
555
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100556 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100557 arT.direction = 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100558 LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100559 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300560
561 if (Status >= 0)
562 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100563 if (length > 0) {
564 remaining_bits_len -= length;
565 bit_offset += length;
566 } else {
567 remaining_bits_len = arT.remaining_bits_len;
568 bit_offset = arT.bit_offset;
569 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300570 pDescr++;
571 }
572 else
573 {
574 /* Has already been processed: */
575 return Status;
576 }
577
578 break;
579 }
580
581 case CSN_UNION_LH:
582 case CSN_UNION:
583 {
584 gint16 Bits;
585 guint8 index;
586 gint16 count = pDescr->i;
587 const CSN_DESCR* pDescrNext = pDescr;
588
589 pDescrNext += count + 1; /* now this is next after the union */
590 if ((count <= 0) || (count > 16))
591 {
592 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
593 }
594
595 /* Now get the bits to extract the index */
596 Bits = ixBitsTab[count];
597 index = 0;
598
599 while (Bits > 0)
600 {
601 index <<= 1;
602
603 if (CSN_UNION_LH == pDescr->type)
604 {
605 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
606 }
607 else
608 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100609 index |= bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300610 }
611 remaining_bits_len--;
612 bit_offset++;
613 Bits--;
614 }
615
616 /* Assign UnionType */
617 pui8 = pui8DATA(data, pDescr->offset);
618 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100619
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300620
621 /* script index to continue on, limited in case we do not have a power of 2 */
622 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400623 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300624
625 switch (pDescr->type)
626 { /* get the right element of the union based on computed index */
627
628 case CSN_BIT:
629 {
630 pui8 = pui8DATA(data, pDescr->offset);
631 *pui8 = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100632 if (bitvec_read_field(vector, &readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300633 {
634 *pui8 = 0x01;
635 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400636 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300637 remaining_bits_len -= 1;
638 bit_offset++;
639 pDescr++;
640 break;
641 }
642
643 case CSN_NULL:
644 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100645 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300646 pDescr++;
647 break;
648 }
649
650 case CSN_UINT:
651 {
652 guint8 no_of_bits = (guint8) pDescr->i;
653 if (remaining_bits_len >= no_of_bits)
654 {
655 remaining_bits_len -= no_of_bits;
656
657 if (no_of_bits <= 8)
658 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100659 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300660 pui8 = pui8DATA(data, pDescr->offset);
661 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400662 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300663 }
664 else if (no_of_bits <= 16)
665 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100666 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300667 pui16 = pui16DATA(data, pDescr->offset);
668 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400669 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300670 }
671 else if (no_of_bits <= 32)
672 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100673 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300674 pui32 = pui32DATA(data, pDescr->offset);
675 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400676 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300677 }
678 else
679 {
680 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
681 }
682 }
683 else
684 {
685 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
686 }
687
688 bit_offset += no_of_bits;
689 pDescr++;
690 break;
691 }
692
693 case CSN_UINT_OFFSET:
694 {
695 guint8 no_of_bits = (guint8) pDescr->i;
696
697 if (remaining_bits_len >= no_of_bits)
698 {
699 if (no_of_bits <= 8)
700 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100701 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300702 pui8 = pui8DATA(data, pDescr->offset);
703 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400704 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300705 }
706 else if (no_of_bits <= 16)
707 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100708 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300709 pui16 = pui16DATA(data, pDescr->offset);
710 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400711 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300712 }
713 else if (no_of_bits <= 32)
714 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100715 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300716 pui32 = pui32DATA(data, pDescr->offset);
717 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400718 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300719 }
720 else
721 {
722 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
723 }
724 }
725 else
726 {
727 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
728 }
729
730 bit_offset += no_of_bits;
731 pDescr++;
732 break;
733 }
734
735 case CSN_UINT_LH:
736 {
737 guint8 no_of_bits = (guint8) pDescr->i;
738
739 if (remaining_bits_len >= no_of_bits)
740 {
741 if (no_of_bits <= 8)
742 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100743 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300744 pui8 = pui8DATA(data, pDescr->offset);
745 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400746 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300747 }
748 else
749 { /* Maybe we should support more than 8 bits ? */
750 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
751 }
752 }
753 else
754 {
755 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
756 }
757
758 bit_offset += no_of_bits;
759 pDescr++;
760 break;
761 }
762
763 case CSN_UINT_ARRAY:
764 {
765 guint8 no_of_bits = (guint8) pDescr->i;
766 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
767
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100768 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300769 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
770 nCount = *pui16DATA(data, nCount);
771 }
772
773 if (remaining_bits_len >= no_of_bits)
774 {
775 remaining_bits_len -= (no_of_bits * nCount);
776 if (no_of_bits <= 8)
777 {
778 pui8 = pui8DATA(data, pDescr->offset);
779
780 while (nCount > 0)
781 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100782 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400783 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300784 pui8++;
785 bit_offset += no_of_bits;
786 nCount--;
787 }
788 }
789 else if (no_of_bits <= 16)
790 {
791 pui16 = pui16DATA(data, pDescr->offset);
792
793 while (nCount > 0)
794 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100795 *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400796 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300797 pui16++;
798 bit_offset += no_of_bits;
799 nCount--;
800 }
801 }
802 else if (no_of_bits <= 32)
803 { /* not supported */
804 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
805 }
806 else
807 {
808 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
809 }
810 }
811 else
812 {
813 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
814 }
815
816 pDescr++;
817 break;
818 }
819
820 case CSN_VARIABLE_TARRAY_OFFSET:
821 case CSN_VARIABLE_TARRAY:
822 case CSN_TYPE_ARRAY:
823 {
824 gint16 Status;
825 csnStream_t arT = *ar;
826 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100827 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300828
829 pui8 = pui8DATA(data, pDescr->offset);
830
831 if (CSN_VARIABLE_TARRAY == pDescr->type)
832 { /* Count specified in field */
833 nCount = *pui8DATA(data, pDescr->i);
834 }
835 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
836 { /* Count specified in field */
837 nCount = *pui8DATA(data, pDescr->i);
838 nCount--; /* Offset 1 */
839 }
840
841 while (nCount--) /* Changed to handle length = 0. */
842 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400843 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300844 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100845 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300846 if (Status >= 0)
847 {
848 pui8 += nSize;
849 remaining_bits_len = arT.remaining_bits_len;
850 bit_offset = arT.bit_offset;
851 }
852 else
853 {
854 return Status;
855 }
856 }
857
858 pDescr++;
859 break;
860 }
861
862 case CSN_BITMAP:
863 { /* bitmap with given length. The result is left aligned! */
864 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
865
866 if (no_of_bits > 0)
867 {
868
869 if (no_of_bits <= 32)
870 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100871 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300872 pui32 = pui32DATA(data, pDescr->offset);
873 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300874 }
875 else if (no_of_bits <= 64)
876 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100877 guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300878 pui64 = pui64DATA(data, pDescr->offset);
879 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200880 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300881 }
882 else
883 {
884 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
885 }
886
887 remaining_bits_len -= no_of_bits;
888 assert(remaining_bits_len >= 0);
889 bit_offset += no_of_bits;
890 }
891 /* bitmap was successfully extracted or it was empty */
892
893 pDescr++;
894 break;
895 }
896
897 case CSN_TYPE:
898 {
899 gint16 Status;
900 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400901 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300902 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100903 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400904 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300905 if (Status >= 0)
906 {
907 remaining_bits_len = arT.remaining_bits_len;
908 bit_offset = arT.bit_offset;
909 pDescr++;
910 }
911 else
912 { /* return error code Has already been processed: */
913 return Status;
914 }
915
916 break;
917 }
918
919 default:
920 { /* descriptions of union elements other than above are illegal */
921 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
922 }
923 }
924
925 pDescr = pDescrNext;
926 break;
927 }
928
929 case CSN_EXIST:
930 case CSN_EXIST_LH:
931 {
932 guint8 fExist;
933
934 pui8 = pui8DATA(data, pDescr->offset);
935
936 if (CSN_EXIST_LH == pDescr->type)
937 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100938 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300939 }
940 else
941 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100942 fExist = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300943 }
944
945 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400946 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300947 pDescr++;
948 remaining_bits_len -= 1;
949
950 if (!fExist)
951 {
952 ar->remaining_bits_len = remaining_bits_len;
953 ar->bit_offset = bit_offset;
954 return remaining_bits_len;
955 }
956
957 break;
958 }
959
960 case CSN_NEXT_EXIST:
961 {
962 guint8 fExist;
963
964 pui8 = pui8DATA(data, pDescr->offset);
965
966 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400967 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300968 { /* no more bits to decode is fine here - end of message detected and allowed */
969
970 /* Skip i entries + this entry */
971 pDescr += pDescr->i + 1;
972
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300973 /* Set the data member to "not exist" */
974 *pui8 = 0;
975 break;
976 }
977
978 /* the "regular" M_NEXT_EXIST description element */
979
980 fExist = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100981 if (bitvec_read_field(vector, &readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300982 {
983 fExist = 0x01;
984 }
985
986 *pui8 = fExist;
987 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400988 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300989 ++bit_offset;
990
991 if (fExist == 0)
992 { /* Skip 'i' entries */
993 pDescr += pDescr->i;
994 }
995
996 pDescr++;
997 break;
998 }
999
1000 case CSN_NEXT_EXIST_LH:
1001 {
1002 guint8 fExist;
1003 pui8 = pui8DATA(data, pDescr->offset);
1004
1005 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1006 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1007 { /* no more bits to decode is fine here - end of message detected and allowed */
1008
1009 /* skip 'i' entries + this entry */
1010 pDescr += pDescr->i + 1;
1011
1012 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1013 if ( pDescr->type != CSN_END )
1014 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1015 remaining_bits_len--;
1016 }
1017
1018 /* set the data member to "not exist" */
1019 *pui8 = 0;
1020 break;
1021 }
1022
1023 /* the "regular" M_NEXT_EXIST_LH description element */
1024 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001025 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001026 *pui8++ = fExist;
1027 remaining_bits_len -= 1;
1028
1029 bit_offset++;
1030
1031 if (fExist == 0)
1032 { /* Skip 'i' entries */
1033 pDescr += pDescr->i;
1034 }
1035 pDescr++;
1036
1037 break;
1038 }
1039
1040 case CSN_VARIABLE_BITMAP_1:
1041 { /* Bitmap from here and to the end of message */
1042
1043 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1044
1045 /*no break -
1046 * with a length set we have a regular variable length bitmap so we continue */
1047 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001048 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001049 case CSN_VARIABLE_BITMAP:
1050 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1051 * <N: bit (5)> <bitmap: bit(N + offset)>
1052 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1053 * The result is right aligned!
1054 */
1055 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1056
1057 no_of_bits += pDescr->i; /* adjusted by offset */
1058
1059 if (no_of_bits > 0)
1060 {
1061 remaining_bits_len -= no_of_bits;
1062
1063 if (remaining_bits_len < 0)
1064 {
1065 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1066 }
1067
1068 { /* extract bits */
1069 guint8* pui8 = pui8DATA(data, pDescr->offset);
1070 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1071
1072 if (nB1 > 0)
1073 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001074 *pui8 = bitvec_read_field(vector, &readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001075 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001076 pui8++;
1077 no_of_bits -= nB1;
1078 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1079 }
1080
1081 /* remaining no_of_bits is a multiple of 8 or 0 */
1082 while (no_of_bits > 0)
1083 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001084 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001085 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001086 pui8++;
1087 no_of_bits -= 8;
1088 }
1089 }
1090 }
1091 pDescr++;
1092 break;
1093 }
1094
1095 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1096 { /* Bitmap from here and to the end of message */
1097
1098 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1099
1100 /* no break -
1101 * with a length set we have a regular left aligned variable length bitmap so we continue
1102 */
1103 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001104 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001105 case CSN_LEFT_ALIGNED_VAR_BMP:
1106 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1107 * <N: bit (5)> <bitmap: bit(N + offset)>
1108 * bit array with length (in bits) specified in parameter (pDescr->descr)
1109 */
1110 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1111
1112 no_of_bits += pDescr->i;/* size adjusted by offset */
1113
1114 if (no_of_bits > 0)
1115 {
1116 remaining_bits_len -= no_of_bits;
1117
1118 if (remaining_bits_len < 0)
1119 {
1120 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1121 }
1122
1123 { /* extract bits */
1124 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001125
Neels Hofmeyr02415262016-09-02 02:15:26 +02001126 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001127 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001128 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001129 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001130 pui8++;
1131 no_of_bits -= 8;
1132 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001133 if (no_of_bits > 0)
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001134 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001135 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001136 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001137 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001138 bit_offset += no_of_bits;
1139 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001140 }
1141 }
1142 }
1143
1144 /* bitmap was successfully extracted or it was empty */
1145 pDescr++;
1146 break;
1147 }
1148
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001149 case CSN_PADDING_BITS:
1150 { /* Padding from here and to the end of message */
1151 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1152 if (remaining_bits_len > 0)
1153 {
1154 while (remaining_bits_len > 0)
1155 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001156 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001157 if (bits_to_handle > 0)
1158 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001159 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001160 remaining_bits_len -= bits_to_handle;
1161 bit_offset += bits_to_handle;
1162 }
1163 else if (bits_to_handle == 0)
1164 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001165 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001166 remaining_bits_len -= 8;
1167 bit_offset += 8;
1168 }
1169 }
1170 }
1171 if (remaining_bits_len < 0)
1172 {
1173 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1174 }
1175
1176 /* Padding was successfully extracted or it was empty */
1177 pDescr++;
1178 break;
1179 }
1180
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001181 case CSN_VARIABLE_ARRAY:
1182 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1183 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1184 * Array with length specified in parameter:
1185 * <count: bit (x)>
1186 * <list: octet(count + offset)>
1187 */
1188 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1189
1190 count += pDescr->i; /* Adjusted by offset */
1191
1192 if (count > 0)
1193 {
1194 remaining_bits_len -= count * 8;
1195
1196 if (remaining_bits_len < 0)
1197 {
1198 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1199 }
1200
1201 pui8 = pui8DATA(data, pDescr->offset);
1202
1203 while (count > 0)
1204 {
1205 readIndex -= 8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001206 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001207 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001208 pui8++;
1209 bit_offset += 8;
1210 count--;
1211 }
1212 }
1213
1214 pDescr++;
1215 break;
1216 }
1217
1218 case CSN_RECURSIVE_ARRAY:
1219 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1220 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1221 * where <element> ::= bit(value)
1222 * <tag> ::= 0 | 1
1223 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1224 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1225 * REMARK: recursive way to specify an array but an iterative implementation!
1226 */
1227 gint16 no_of_bits = pDescr->i;
1228 guint8 ElementCount = 0;
1229
1230 pui8 = pui8DATA(data, pDescr->offset);
1231
Alexander Couzensccde5c92017-02-04 03:10:08 +01001232 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001233 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001234 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001235 bit_offset++;
1236 remaining_bits_len--;
1237
1238 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001239 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001240 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001241 pui8++;
1242 remaining_bits_len -= no_of_bits;
1243 ElementCount++;
1244
1245 if (remaining_bits_len < 0)
1246 {
1247 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1248 }
1249
1250 bit_offset += no_of_bits;
1251 }
1252
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001253 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001254 /* existNextElement() returned FALSE, 1 bit consumed */
1255 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001256 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001257
1258 /* Store the counted number of elements of the array */
1259 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1260
1261 pDescr++;
1262 break;
1263 }
1264
1265 case CSN_RECURSIVE_TARRAY:
1266 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1267 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1268 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1269 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001270 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001271 guint8 ElementCount = 0;
1272 pui8 = pui8DATA(data, pDescr->offset);
1273
Alexander Couzensccde5c92017-02-04 03:10:08 +01001274 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001275 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001276 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001277 /* existNextElement() returned TRUE, 1 bit consumed */
1278 bit_offset++;
1279 remaining_bits_len--;
1280 ElementCount++;
1281
1282 { /* unpack the following data structure */
1283 csnStream_t arT = *ar;
1284 gint16 Status;
1285 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001286 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001287
1288 if (Status >= 0)
1289 { /* successful completion */
1290 pui8 += nSizeElement; /* -> to next data element */
1291 remaining_bits_len = arT.remaining_bits_len;
1292 bit_offset = arT.bit_offset;
1293 }
1294 else
1295 { /* something went awry */
1296 return Status;
1297 }
1298 }
1299
1300 if (remaining_bits_len < 0)
1301 {
1302 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1303 }
1304 }
1305
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001306 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001307
1308 /* existNextElement() returned FALSE, 1 bit consumed */
1309 bit_offset++;
1310
1311 /* Store the counted number of elements of the array */
1312 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1313
1314 pDescr++;
1315 break;
1316 }
1317
1318 case CSN_RECURSIVE_TARRAY_2:
1319 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1320
1321 Tag = REVERSED_TAG;
1322
1323 /* NO break -
1324 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1325 */
1326 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001327 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001328 case CSN_RECURSIVE_TARRAY_1:
1329 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1330 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1331 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1332 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001333 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001334 guint8 ElementCount = 0;
1335 csnStream_t arT = *ar;
1336 gboolean EndOfList = FALSE;
1337 gint16 Status;
1338 pui8 = pui8DATA(data, pDescr->offset);
1339
1340 do
1341 { /* get data element */
1342 ElementCount++;
1343
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001344 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001345
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001346 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001347 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001348
1349 if (Status >= 0)
1350 { /* successful completion */
1351 pui8 += nSizeElement; /* -> to next */
1352 remaining_bits_len = arT.remaining_bits_len;
1353 bit_offset = arT.bit_offset;
1354 }
1355 else
1356 { /* something went awry */
1357 return Status;
1358 }
1359
1360 if (remaining_bits_len < 0)
1361 {
1362 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1363 }
1364
1365 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001366 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001367 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001368
1369 bit_offset++;
1370 remaining_bits_len--; /* 1 bit consumed (tag) */
1371 } while (!EndOfList);
1372
1373
1374 /* Store the count of the array */
1375 *pui8DATA(data, pDescr->i) = ElementCount;
1376 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1377 pDescr++;
1378 break;
1379 }
1380
1381 case CSN_FIXED:
1382 { /* Verify the fixed bits */
1383 guint8 no_of_bits = (guint8) pDescr->i;
1384 guint32 ui32;
1385
1386 if (no_of_bits <= 32)
1387 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001388 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001389 }
1390 else
1391 {
1392 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1393 }
1394 if (ui32 != (unsigned)(gint32)pDescr->offset)
1395 {
1396 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1397 }
1398
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001399 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001400 remaining_bits_len -= no_of_bits;
1401 bit_offset += no_of_bits;
1402 pDescr++;
1403 break;
1404 }
1405
1406 case CSN_CALLBACK:
1407 {
1408 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1409 break;
1410 }
1411
1412 case CSN_TRAP_ERROR:
1413 {
1414 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1415 }
1416
1417 case CSN_END:
1418 {
1419 ar->remaining_bits_len = remaining_bits_len;
1420 ar->bit_offset = bit_offset;
1421 return remaining_bits_len;
1422 }
1423
1424 default:
1425 {
1426 assert(0);
1427 }
1428
1429
1430 }
1431
1432 } while (remaining_bits_len >= 0);
1433
1434 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1435}
1436
1437
1438
1439
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001440gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001441{
1442 gint remaining_bits_len = ar->remaining_bits_len;
1443 gint bit_offset = ar->bit_offset;
1444 guint8* pui8;
1445 guint16* pui16;
1446 guint32* pui32;
1447 guint64* pui64;
1448
1449 guint8 Tag = STANDARD_TAG;
1450
1451 if (remaining_bits_len <= 0)
1452 {
1453 return 0;
1454 }
1455
1456 do
1457 {
1458 switch (pDescr->type)
1459 {
1460 case CSN_BIT:
1461 {
1462 if (remaining_bits_len > 0)
1463 {
1464 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001465 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001466 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001467 /* end add the bit value to protocol tree */
1468 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001469 else if(pDescr->may_be_null)
1470 {
1471 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1472 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001473 else
1474 {
1475 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1476 }
1477
1478 pDescr++;
1479 remaining_bits_len--;
1480 bit_offset++;
1481 break;
1482 }
1483
1484 case CSN_NULL:
1485 { /* Empty member! */
1486 pDescr++;
1487 break;
1488 }
1489
1490 case CSN_UINT:
1491 {
1492 guint8 no_of_bits = (guint8) pDescr->i;
1493
1494 if (remaining_bits_len >= no_of_bits)
1495 {
1496 if (no_of_bits <= 8)
1497 {
1498 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001499 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001500 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001501 }
1502 else if (no_of_bits <= 16)
1503 {
1504 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001505 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001506 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001507 }
1508 else if (no_of_bits <= 32)
1509 {
1510 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001511 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001512 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001513 }
1514 else
1515 {
1516 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1517 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001518
1519 remaining_bits_len -= no_of_bits;
1520 bit_offset += no_of_bits;
1521 }
1522 else if(pDescr->may_be_null)
1523 {
1524 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001525 }
1526 else
1527 {
1528 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1529 }
1530
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001531 pDescr++;
1532 break;
1533 }
1534
1535 case CSN_UINT_OFFSET:
1536 {
1537 guint8 no_of_bits = (guint8) pDescr->i;
1538
1539 if (remaining_bits_len >= no_of_bits)
1540 {
1541 if (no_of_bits <= 8)
1542 {
1543 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001544 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001545 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001546 }
1547 else if (no_of_bits <= 16)
1548 {
1549 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001550 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001551 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001552 }
1553 else if (no_of_bits <= 32)
1554 {
1555 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001556 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001557 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001558 }
1559 else
1560 {
1561 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1562 }
1563 }
1564 else
1565 {
1566 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1567 }
1568
1569 remaining_bits_len -= no_of_bits;
1570 bit_offset += no_of_bits;
1571 pDescr++;
1572 break;
1573 }
1574
1575 case CSN_UINT_LH:
1576 {
1577 guint8 no_of_bits = (guint8) pDescr->i;
1578
1579 if (remaining_bits_len >= no_of_bits)
1580 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001581 if (no_of_bits <= 8)
1582 {
1583 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001584 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001585 // TODO : Change get_masked_bits8()
1586 writeIndex -= no_of_bits;
1587 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1588 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001589 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001590 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001591
1592 }
1593 else
1594 {/* Maybe we should support more than 8 bits ? */
1595 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1596 }
1597 }
1598 else
1599 {
1600 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1601 }
1602
1603 remaining_bits_len -= no_of_bits;
1604 bit_offset += no_of_bits;
1605 pDescr++;
1606 break;
1607 }
1608
1609 case CSN_UINT_ARRAY:
1610 {
1611 guint8 no_of_bits = (guint8) pDescr->i;
1612 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1613
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001614 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001615 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1616 nCount = *pui16DATA(data, nCount);
1617 }
1618
1619 if (remaining_bits_len >= no_of_bits)
1620 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001621 if (no_of_bits <= 8)
1622 {
1623 pui8 = pui8DATA(data, pDescr->offset);
1624 do
1625 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001626 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001627 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001628 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001629 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001630 bit_offset += no_of_bits;
1631 } while (--nCount > 0);
1632 }
1633 else if (no_of_bits <= 16)
1634 {
1635 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1636 }
1637 else if (no_of_bits <= 32)
1638 {
1639 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1640 }
1641 else
1642 {
1643 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1644 }
1645 }
1646 else
1647 {
1648 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1649 }
1650 pDescr++;
1651 break;
1652 }
1653
1654 case CSN_VARIABLE_TARRAY_OFFSET:
1655 case CSN_VARIABLE_TARRAY:
1656 case CSN_TYPE_ARRAY:
1657 {
1658 gint16 Status;
1659 csnStream_t arT = *ar;
1660 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001661 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001662
1663 pui8 = pui8DATA(data, pDescr->offset);
1664 if (pDescr->type == CSN_VARIABLE_TARRAY)
1665 { /* Count specified in field */
1666 nCount = *pui8DATA(data, pDescr->i);
1667 }
1668 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1669 { /* Count specified in field */
1670 nCount = *pui8DATA(data, pDescr->i);
1671 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1672 }
1673
1674 while (nCount > 0)
1675 { /* resulting array of length 0 is possible
1676 * but no bits shall be read from bitstream
1677 */
1678
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001679 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001680 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1681 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1682 if (Status >= 0)
1683 {
1684 pui8 += nSize;
1685 remaining_bits_len = arT.remaining_bits_len;
1686 bit_offset = arT.bit_offset;
1687
1688 }
1689 else
1690 {
1691 return Status;
1692 }
1693 nCount--;
1694 }
1695
1696 pDescr++;
1697 break;
1698 }
1699
1700 case CSN_BITMAP:
1701 { /* bitmap with given length. The result is left aligned! */
1702 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1703
1704 if (no_of_bits > 0)
1705 {
1706
1707 if (no_of_bits <= 32)
1708 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001709 for(unsigned ib = 0; ib < 4; ib++)
1710 {
1711 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001712 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001713 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001714 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001715 }
1716 else if (no_of_bits <= 64)
1717 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001718 for(unsigned ib = 0; ib < 8; ib++)
1719 {
1720 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001721 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001722 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001723 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001724 }
1725 else
1726 {
1727 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1728 }
1729
1730 remaining_bits_len -= no_of_bits;
1731 assert(remaining_bits_len >= 0);
1732 bit_offset += no_of_bits;
1733 }
1734 /* bitmap was successfully extracted or it was empty */
1735
1736 pDescr++;
1737 break;
1738 }
1739
1740 case CSN_TYPE:
1741 {
1742 gint16 Status;
1743 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001744 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001745 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1746 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001747 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001748 if (Status >= 0)
1749 {
1750
1751 remaining_bits_len = arT.remaining_bits_len;
1752 bit_offset = arT.bit_offset;
1753 pDescr++;
1754 }
1755 else
1756 {
1757 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1758 return Status;
1759 }
1760
1761 break;
1762 }
1763
1764 case CSN_CHOICE:
1765 {
1766 //gint16 count = pDescr->i;
1767 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001768 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001769
1770 pui8 = pui8DATA(data, pDescr->offset);
1771 i = *pui8;
1772 pChoice += i;
1773 guint8 no_of_bits = pChoice->bits;
1774 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001775 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001776 bitvec_write_field(vector, &writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001777
1778 CSN_DESCR descr[2];
1779 gint16 Status;
1780 csnStream_t arT = *ar;
1781
1782 descr[0] = pChoice->descr;
1783 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1784 descr[1].type = CSN_END;
1785 bit_offset += no_of_bits;
1786 remaining_bits_len -= no_of_bits;
1787
1788 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1789 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1790
1791 if (Status >= 0)
1792 {
1793 remaining_bits_len = arT.remaining_bits_len;
1794 bit_offset = arT.bit_offset;
1795 }
1796 else
1797 {
1798 return Status;
1799 }
1800
1801 pDescr++;
1802 break;
1803 }
1804
1805 case CSN_SERIALIZE:
1806 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001807 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001808 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001809 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001810 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001811 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001812
1813 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001814 lengthIndex = writeIndex;
1815 writeIndex += length_len;
1816 bit_offset += length_len;
1817 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001818 arT.direction = 0;
1819 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1820 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001821
Alexander Couzensccde5c92017-02-04 03:10:08 +01001822 bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001823 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001824
1825 if (Status >= 0)
1826 {
1827 remaining_bits_len = arT.remaining_bits_len;
1828 bit_offset = arT.bit_offset;
1829 pDescr++;
1830 }
1831 else
1832 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001833 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001834 return Status;
1835 }
1836
1837 break;
1838 }
1839
1840 case CSN_UNION_LH:
1841 case CSN_UNION:
1842 {
1843 gint16 Bits;
1844 guint8 index;
1845 gint16 count = pDescr->i;
1846 const CSN_DESCR* pDescrNext = pDescr;
1847
1848 pDescrNext += count + 1; /* now this is next after the union */
1849 if ((count <= 0) || (count > 16))
1850 {
1851 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1852 }
1853
1854 /* Now get the bits to extract the index */
1855 Bits = ixBitsTab[count];
1856 index = 0;
1857
1858 /* Assign UnionType */
1859 pui8 = pui8DATA(data, pDescr->offset);
1860 //read index from data and write to vector
Alexander Couzensccde5c92017-02-04 03:10:08 +01001861 bitvec_write_field(vector, &writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001862
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001863 //decode index
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001864 writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001865
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001866 while (Bits > 0)
1867 {
1868 index <<= 1;
1869
1870 if (CSN_UNION_LH == pDescr->type)
1871 {
1872 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1873 }
1874 else
1875 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001876 index |= bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001877 }
1878
1879 remaining_bits_len--;
1880 bit_offset++;
1881 Bits--;
1882 }
1883
1884 writeIndex -= Bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001885 bitvec_write_field(vector, &writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001886
1887
1888 /* script index to continue on, limited in case we do not have a power of 2 */
1889 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001890 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001891
1892 switch (pDescr->type)
1893 { /* get the right element of the union based on computed index */
1894
1895 case CSN_BIT:
1896 {
1897 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001898 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001899 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001900 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001901 bit_offset++;
1902 pDescr++;
1903 break;
1904 }
1905
1906 case CSN_NULL:
1907 { /* Empty member! */
1908 pDescr++;
1909 break;
1910 }
1911
1912 case CSN_UINT:
1913 {
1914 guint8 no_of_bits = (guint8) pDescr->i;
1915 if (remaining_bits_len >= no_of_bits)
1916 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001917 if (no_of_bits <= 8)
1918 {
1919 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001920 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001921 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001922 }
1923 else if (no_of_bits <= 16)
1924 {
1925 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001926 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001927 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001928 }
1929 else if (no_of_bits <= 32)
1930 {
1931 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001932 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001933 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001934 }
1935 else
1936 {
1937 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1938 }
1939 }
1940 else
1941 {
1942 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1943 }
1944
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001945 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001946 bit_offset += no_of_bits;
1947 pDescr++;
1948 break;
1949 }
1950
1951 case CSN_UINT_OFFSET:
1952 {
1953 guint8 no_of_bits = (guint8) pDescr->i;
1954
1955 if (remaining_bits_len >= no_of_bits)
1956 {
1957 if (no_of_bits <= 8)
1958 {
1959 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001960 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001961 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001962 }
1963 else if (no_of_bits <= 16)
1964 {
1965 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001966 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001967 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001968 }
1969 else if (no_of_bits <= 32)
1970 {
1971 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001972 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001973 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001974 }
1975 else
1976 {
1977 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1978 }
1979 }
1980 else
1981 {
1982 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1983 }
1984
1985 remaining_bits_len -= no_of_bits;
1986 bit_offset += no_of_bits;
1987 pDescr++;
1988 break;
1989 }
1990
1991 case CSN_UINT_LH:
1992 {
1993 guint8 no_of_bits = (guint8) pDescr->i;
1994
1995 if (remaining_bits_len >= no_of_bits)
1996 {
1997 remaining_bits_len -= no_of_bits;
1998 if (no_of_bits <= 8)
1999 {
2000 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002001 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002002 // TODO : Change get_masked_bits8()
2003 writeIndex -= no_of_bits;
2004 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
2005 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002006 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002007 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002008
2009 }
2010 else
2011 {/* Maybe we should support more than 8 bits ? */
2012 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2013 }
2014 }
2015 else
2016 {
2017 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2018 }
2019
2020 remaining_bits_len -= no_of_bits;
2021 bit_offset += no_of_bits;
2022 pDescr++;
2023 break;
2024 }
2025
2026 case CSN_UINT_ARRAY:
2027 {
2028 guint8 no_of_bits = (guint8) pDescr->i;
2029 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2030
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002031 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002032 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2033 nCount = *pui16DATA(data, nCount);
2034 }
2035
2036 if (remaining_bits_len >= no_of_bits)
2037 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002038 if (no_of_bits <= 8)
2039 {
2040 pui8 = pui8DATA(data, pDescr->offset);
2041 do
2042 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002043 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002044 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002045 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002046 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002047 bit_offset += no_of_bits;
2048 } while (--nCount > 0);
2049 }
2050 else if (no_of_bits <= 16)
2051 {
2052 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2053 }
2054 else if (no_of_bits <= 32)
2055 {
2056 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2057 }
2058 else
2059 {
2060 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2061 }
2062 }
2063 else
2064 {
2065 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2066 }
2067 pDescr++;
2068 break;
2069 }
2070
2071 case CSN_VARIABLE_TARRAY_OFFSET:
2072 case CSN_VARIABLE_TARRAY:
2073 case CSN_TYPE_ARRAY:
2074 {
2075 gint16 Status;
2076 csnStream_t arT = *ar;
2077 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002078 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002079
2080 pui8 = pui8DATA(data, pDescr->offset);
2081 if (pDescr->type == CSN_VARIABLE_TARRAY)
2082 { /* Count specified in field */
2083 nCount = *pui8DATA(data, pDescr->i);
2084 }
2085 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2086 { /* Count specified in field */
2087 nCount = *pui8DATA(data, pDescr->i);
2088 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2089 }
2090
2091 while (nCount > 0)
2092 { /* resulting array of length 0 is possible
2093 * but no bits shall be read from bitstream
2094 */
2095
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002096 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002097 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2098 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2099 if (Status >= 0)
2100 {
2101 pui8 += nSize;
2102 remaining_bits_len = arT.remaining_bits_len;
2103 bit_offset = arT.bit_offset;
2104 }
2105 else
2106 {
2107 return Status;
2108 }
2109 nCount--;
2110 }
2111
2112 pDescr++;
2113 break;
2114 }
2115
2116 case CSN_BITMAP:
2117 { /* bitmap with given length. The result is left aligned! */
2118 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2119
2120 if (no_of_bits > 0)
2121 {
2122
2123 if (no_of_bits <= 32)
2124 {
2125 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002126 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002127 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002128 }
2129 else if (no_of_bits <= 64)
2130 {
2131 pui64 = pui64DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002132 bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002133 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002134 }
2135 else
2136 {
2137 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2138 }
2139
2140 remaining_bits_len -= no_of_bits;
2141 assert(remaining_bits_len >= 0);
2142 bit_offset += no_of_bits;
2143 }
2144 /* bitmap was successfully extracted or it was empty */
2145
2146 pDescr++;
2147 break;
2148 }
2149
2150 case CSN_TYPE:
2151 {
2152 gint16 Status;
2153 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002154 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002155 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2156 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002157 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002158 if (Status >= 0)
2159 {
2160 remaining_bits_len = arT.remaining_bits_len;
2161 bit_offset = arT.bit_offset;
2162 pDescr++;
2163 }
2164 else
2165 {
2166 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2167 return Status;
2168 }
2169
2170 break;
2171 }
2172
2173 default:
2174 { /* descriptions of union elements other than above are illegal */
2175 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2176 }
2177 }
2178
2179 pDescr = pDescrNext;
2180 break;
2181 }
2182
2183 case CSN_EXIST:
2184 case CSN_EXIST_LH:
2185 {
2186 guint8 fExist;
2187 unsigned exist = 0;
2188 pui8 = pui8DATA(data, pDescr->offset);
2189 exist = *pui8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002190 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002191 writeIndex--;
2192 if (CSN_EXIST_LH == pDescr->type)
2193 {
2194 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2195 }
2196 else
2197 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002198 fExist = bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002199 }
2200 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002201 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002202 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002203 remaining_bits_len--;
2204 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002205 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002206
2207 if (!exist)
2208 {
2209 ar->remaining_bits_len = remaining_bits_len;
2210 ar->bit_offset = bit_offset;
2211 return remaining_bits_len;
2212 }
2213 break;
2214 }
2215
2216 case CSN_NEXT_EXIST:
2217 {
2218 guint8 fExist;
2219
2220 pui8 = pui8DATA(data, pDescr->offset);
2221
2222 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002223 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002224 { /* no more bits to decode is fine here - end of message detected and allowed */
2225
2226 /* Skip i entries + this entry */
2227 pDescr += pDescr->i + 1;
2228
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002229 break;
2230 }
2231
Alexander Couzensccde5c92017-02-04 03:10:08 +01002232 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002233 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002234 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002235
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002236 remaining_bits_len--;
2237 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002238
2239 if (fExist == 0)
2240 { /* Skip 'i' entries */
2241 pDescr += pDescr->i;
2242 }
2243
2244 pDescr++;
2245 break;
2246 }
2247
2248 case CSN_NEXT_EXIST_LH:
2249 {
2250 guint8 fExist;
2251 pui8 = pui8DATA(data, pDescr->offset);
2252
2253 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2254 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2255 { /* no more bits to decode is fine here - end of message detected and allowed */
2256
2257 /* skip 'i' entries + this entry */
2258 pDescr += pDescr->i + 1;
2259
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002260 /* set the data member to "not exist" */
2261 //*pui8 = 0;
2262 break;
2263 }
2264
2265 /* the "regular" M_NEXT_EXIST_LH description element */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002266 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002267 writeIndex--;
2268 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2269 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002270 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002271 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002272
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002273 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002274 bit_offset++;
2275
2276 if (fExist == 0)
2277 { /* Skip 'i' entries */
2278 pDescr += pDescr->i;
2279 }
2280 pDescr++;
2281
2282 break;
2283 }
2284
2285 case CSN_VARIABLE_BITMAP_1:
2286 { /* Bitmap from here and to the end of message */
2287
2288 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2289
2290 /*no break -
2291 * with a length set we have a regular variable length bitmap so we continue */
2292 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002293 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002294 case CSN_VARIABLE_BITMAP:
2295 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2296 * <N: bit (5)> <bitmap: bit(N + offset)>
2297 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2298 * The result is right aligned!
2299 */
2300 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2301
2302 no_of_bits += pDescr->i; /* adjusted by offset */
2303
2304 if (no_of_bits > 0)
2305 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002306
2307 if (remaining_bits_len < 0)
2308 {
2309 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2310 }
2311
2312 { /* extract bits */
2313 guint8* pui8 = pui8DATA(data, pDescr->offset);
2314 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2315
2316 if (nB1 > 0)
2317 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002318 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002319 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002320 pui8++;
2321 no_of_bits -= nB1;
2322 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002323 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002324 }
2325
2326 /* remaining no_of_bits is a multiple of 8 or 0 */
2327 while (no_of_bits > 0)
2328 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002329 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002330 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002331 pui8++;
2332 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002333 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002334 }
2335 }
2336 }
2337 pDescr++;
2338 break;
2339 }
2340
2341 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2342 { /* Bitmap from here and to the end of message */
2343
2344 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2345
2346 /* no break -
2347 * with a length set we have a regular left aligned variable length bitmap so we continue
2348 */
2349 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002350 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002351 case CSN_LEFT_ALIGNED_VAR_BMP:
2352 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2353 * <N: bit (5)> <bitmap: bit(N + offset)>
2354 * bit array with length (in bits) specified in parameter (pDescr->descr)
2355 */
2356
2357 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2358
2359 no_of_bits += pDescr->i;/* size adjusted by offset */
2360
2361 if (no_of_bits > 0)
2362 {
2363 remaining_bits_len -= no_of_bits;
2364
2365 if (remaining_bits_len < 0)
2366 {
2367 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2368 }
2369
2370 { /* extract bits */
2371 guint8* pui8 = pui8DATA(data, pDescr->offset);
2372 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2373
2374 while (no_of_bits > 0)
2375 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002376 bitvec_write_field(vector, &writeIndex, *pui8, 8);
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 -= 8;
2380 }
2381 if (nB1 > 0)
2382 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002383 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002384 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002385 pui8++;
2386 no_of_bits -= nB1;
2387 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2388 }
2389 }
2390
2391 }
2392
2393 /* bitmap was successfully extracted or it was empty */
2394 pDescr++;
2395 break;
2396 }
2397
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002398 case CSN_PADDING_BITS:
2399 { /* Padding from here and to the end of message */
2400 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2401 guint8 filler = 0x2b;
2402 if (remaining_bits_len > 0)
2403 {
2404 while (remaining_bits_len > 0)
2405 {
2406 guint8 bits_to_handle = remaining_bits_len%8;
2407 if (bits_to_handle > 0)
2408 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302409 /* section 11 of 44.060
2410 * The padding bits may be the 'null' string. Otherwise, the
2411 * padding bits starts with bit '0', followed by 'spare padding'
2412 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2413 */
2414 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Alexander Couzensccde5c92017-02-04 03:10:08 +01002415 bitvec_write_field(vector, &writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002416 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2417 remaining_bits_len -= bits_to_handle;
2418 bit_offset += bits_to_handle;
2419 }
2420 else if (bits_to_handle == 0)
2421 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002422 bitvec_write_field(vector, &writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002423 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2424 remaining_bits_len -= 8;
2425 bit_offset += 8;
2426 }
2427 }
2428 }
2429 if (remaining_bits_len < 0)
2430 {
2431 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2432 }
2433
2434 /* Padding was successfully extracted or it was empty */
2435 pDescr++;
2436 break;
2437 }
2438
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002439 case CSN_VARIABLE_ARRAY:
2440 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2441 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2442 * Array with length specified in parameter:
2443 * <count: bit (x)>
2444 * <list: octet(count + offset)>
2445 */
2446 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2447
2448 count += pDescr->i; /* Adjusted by offset */
2449
2450 if (count > 0)
2451 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002452 if (remaining_bits_len < 0)
2453 {
2454 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2455 }
2456
2457 pui8 = pui8DATA(data, pDescr->offset);
2458
2459 while (count > 0)
2460 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002461 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002462 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002463 pui8++;
2464 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002465 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002466 count--;
2467 }
2468 }
2469
2470 pDescr++;
2471 break;
2472 }
2473
2474 case CSN_RECURSIVE_ARRAY:
2475 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2476 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2477 * where <element> ::= bit(value)
2478 * <tag> ::= 0 | 1
2479 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2480 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2481 * REMARK: recursive way to specify an array but an iterative implementation!
2482 */
2483 gint16 no_of_bits = pDescr->i;
2484 guint8 ElementCount = 0;
2485 pui8 = pui8DATA(data, pDescr->offset);
2486 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2487 while (ElementCount > 0)
2488 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002489 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002490 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002491 bit_offset++;
2492 remaining_bits_len--;
2493
2494 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002495 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002496 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002497 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002498 ElementCount--;
2499
2500 if (remaining_bits_len < 0)
2501 {
2502 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2503 }
2504
2505 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002506 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002507 }
2508
Alexander Couzensccde5c92017-02-04 03:10:08 +01002509 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002510 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002511 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302512 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002513
2514 pDescr++;
2515 break;
2516 }
2517
2518 case CSN_RECURSIVE_TARRAY:
2519 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2520 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2521 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2522 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002523 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002524 guint8 ElementCount = 0;
2525 pui8 = pui8DATA(data, pDescr->offset);
2526 /* Store the counted number of elements of the array */
2527 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2528
2529 while (ElementCount > 0)
2530 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002531 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002532 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002533 bit_offset++;
2534
2535 remaining_bits_len--;
2536 ElementCount--;
2537
2538 { /* unpack the following data structure */
2539 csnStream_t arT = *ar;
2540 gint16 Status;
2541 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002542 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002543
2544 if (Status >= 0)
2545 { /* successful completion */
2546 pui8 += nSizeElement; /* -> to next data element */
2547 remaining_bits_len = arT.remaining_bits_len;
2548 bit_offset = arT.bit_offset;
2549 }
2550 else
2551 { /* something went awry */
2552 return Status;
2553 }
2554 }
2555
2556 if (remaining_bits_len < 0)
2557 {
2558 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2559 }
2560 }
2561
Alexander Couzensccde5c92017-02-04 03:10:08 +01002562 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002563 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002564 bit_offset++;
2565
2566 pDescr++;
2567 break;
2568 }
2569
2570 case CSN_RECURSIVE_TARRAY_2:
2571 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2572
2573 Tag = REVERSED_TAG;
2574
2575 /* NO break -
2576 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2577 */
2578 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002579 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002580 case CSN_RECURSIVE_TARRAY_1:
2581 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2582 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2583 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2584 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002585 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002586 guint8 ElementCount = 0;
2587 guint8 ElementNum = 0;
2588 csnStream_t arT = *ar;
2589 gint16 Status;
2590
2591 pui8 = pui8DATA(data, pDescr->offset);
2592 /* Store the count of the array */
2593 ElementCount = *pui8DATA(data, pDescr->i);
2594 ElementNum = ElementCount;
2595
2596 while (ElementCount > 0)
2597 { /* get data element */
2598 if (ElementCount != ElementNum)
2599 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002600 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002601 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002602 bit_offset++;
2603 remaining_bits_len--;
2604 }
2605 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002606 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002607 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002608 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002609 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002610 if (Status >= 0)
2611 { /* successful completion */
2612 pui8 += nSizeElement; /* -> to next */
2613 remaining_bits_len = arT.remaining_bits_len;
2614 bit_offset = arT.bit_offset;
2615 }
2616 else
2617 { /* something went awry */
2618 return Status;
2619 }
2620
2621 if (remaining_bits_len < 0)
2622 {
2623 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2624 }
2625
2626 }
Alexander Couzensccde5c92017-02-04 03:10:08 +01002627 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002628 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002629 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002630 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2631 pDescr++;
2632 break;
2633 }
2634
2635 case CSN_FIXED:
2636 { /* Verify the fixed bits */
2637 guint8 no_of_bits = (guint8) pDescr->i;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002638 bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002639 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002640 remaining_bits_len -= no_of_bits;
2641 bit_offset += no_of_bits;
2642 pDescr++;
2643 break;
2644 }
2645
2646 case CSN_CALLBACK:
2647 {
2648 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2649 break;
2650 }
2651
2652 case CSN_TRAP_ERROR:
2653 {
2654 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2655 }
2656
2657 case CSN_END:
2658 {
2659 ar->remaining_bits_len = remaining_bits_len;
2660 ar->bit_offset = bit_offset;
2661 return remaining_bits_len;
2662 }
2663
2664 default:
2665 {
2666 assert(0);
2667 }
2668
2669 }
2670
2671 } while (remaining_bits_len >= 0);
2672
2673 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2674}