blob: b2ae1f2cf0ff82b4f7eb25f924ce24ca6897b019 [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" },
Vadim Yanitskiyfee767f2020-02-11 05:28:02 +0700106 { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" },
107 { CSN_ERROR_INTERNAL, "INTERNAL" },
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100108 { 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 Pedrolac2b8662020-02-03 18:58:24 +0100117 /* Don't add trailing newline, top caller is responsible for appending it */
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100118 if (err != CSN_OK)
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100119 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %d)",
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100120 sz, get_value_string(csn1_error_names, err), err,
121 pDescr ? pDescr->sz : "-", readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300122 return err;
123}
124
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100125#define ProcessError(readIndex, sz, err, pDescr) \
126 ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
127
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300128
129/**
130 * ================================================================================================
131 * Return TRUE if tag in bit stream indicates existence of next list element,
132 * otherwise return FALSE.
133 * Will work for tag values equal to both 0 and 1.
134 * ================================================================================================
135 */
136
137static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400138existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300139{
Vadim Yanitskiy74bc1502020-02-16 23:36:38 +0700140 int res = bitvec_get_bit_pos(vector, readIndex++);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300141 if (Tag == STANDARD_TAG)
142 {
143 return (res > 0);
144 }
145 return (res == 0);
146}
147
148
149gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400150csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300151{
152 gint remaining_bits_len = ar->remaining_bits_len;
153 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100154 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300155 guint16* pui16;
156 guint32* pui32;
157 guint64* pui64;
158 guint8 Tag = STANDARD_TAG;
159
160 if (remaining_bits_len <= 0)
161 {
162 return 0;
163 }
164
165 do
166 {
167 switch (pDescr->type)
168 {
169 case CSN_BIT:
170 {
171 if (remaining_bits_len > 0)
172 {
173 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100174 *pui8 = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400175 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300176 /* end add the bit value to protocol tree */
177 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400178 else if(pDescr->may_be_null)
179 {
180 pui8 = pui8DATA(data, pDescr->offset);
181 *pui8 = 0;
182 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
183 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300184 else
185 {
186 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
187 }
188
189 pDescr++;
190 remaining_bits_len--;
191 bit_offset++;
192 break;
193 }
194
195 case CSN_NULL:
196 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100197 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300198 pDescr++;
199 break;
200 }
201
202 case CSN_UINT:
203 {
204 guint8 no_of_bits = (guint8) pDescr->i;
205
206 if (remaining_bits_len >= no_of_bits)
207 {
208 if (no_of_bits <= 8)
209 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100210 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300211 pui8 = pui8DATA(data, pDescr->offset);
212 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400213 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300214 }
215 else if (no_of_bits <= 16)
216 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100217 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300218 pui16 = pui16DATA(data, pDescr->offset);
219 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400220 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300221 }
222 else if (no_of_bits <= 32)
223 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100224 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300225 pui32 = pui32DATA(data, pDescr->offset);
226 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400227 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300228 }
229 else
230 {
231 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
232 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400233 remaining_bits_len -= no_of_bits;
234 bit_offset += no_of_bits;
235 }
236 else if(pDescr->may_be_null)
237 {
238 if (no_of_bits <= 8)
239 {
240 pui8 = pui8DATA(data, pDescr->offset);
241 *pui8 = 0;
242 }
243 else if (no_of_bits <= 16)
244 {
245 pui16 = pui16DATA(data, pDescr->offset);
246 *pui16 = 0;
247 }
248 else if (no_of_bits <= 32)
249 {
250 pui32 = pui32DATA(data, pDescr->offset);
251 *pui32 = 0;
252 }
253 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300254 }
255 else
256 {
257 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
258 }
259
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300260 pDescr++;
261 break;
262 }
263
264 case CSN_UINT_OFFSET:
265 {
266 guint8 no_of_bits = (guint8) pDescr->i;
267
268 if (remaining_bits_len >= no_of_bits)
269 {
270 if (no_of_bits <= 8)
271 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100272 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300273 pui8 = pui8DATA(data, pDescr->offset);
274 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400275 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300276 }
277 else if (no_of_bits <= 16)
278 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100279 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300280 pui16 = pui16DATA(data, pDescr->offset);
281 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400282 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300283 }
284 else if (no_of_bits <= 32)
285 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100286 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300287 pui32 = pui32DATA(data, pDescr->offset);
288 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400289 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300290 }
291 else
292 {
293 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
294 }
295 }
296 else
297 {
298 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
299 }
300
301 remaining_bits_len -= no_of_bits;
302 bit_offset += no_of_bits;
303 pDescr++;
304 break;
305 }
306
307 case CSN_UINT_LH:
308 {
309 guint8 no_of_bits = (guint8) pDescr->i;
310
311 if (remaining_bits_len >= no_of_bits)
312 {
313 remaining_bits_len -= no_of_bits;
314 if (no_of_bits <= 8)
315 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100316 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300317 pui8 = pui8DATA(data, pDescr->offset);
318 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400319 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300320 }
321 else
322 {/* Maybe we should support more than 8 bits ? */
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
324 }
325 }
326 else
327 {
328 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
329 }
330
331 remaining_bits_len -= no_of_bits;
332 bit_offset += no_of_bits;
333 pDescr++;
334 break;
335 }
336
337 case CSN_UINT_ARRAY:
338 {
339 guint8 no_of_bits = (guint8) pDescr->i;
340 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
341
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100342 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300343 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
344 nCount = *pui16DATA(data, nCount);
345 }
346
347 if (remaining_bits_len >= no_of_bits)
348 {
349 remaining_bits_len -= (no_of_bits*nCount);
350 if (no_of_bits <= 8)
351 {
352 pui8 = pui8DATA(data, pDescr->offset);
353 do
354 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100355 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400356 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300357 pui8++;
358 bit_offset += no_of_bits;
359 } while (--nCount > 0);
360 }
361 else if (no_of_bits <= 16)
362 {
363 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
364 }
365 else if (no_of_bits <= 32)
366 {
367 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
372 }
373 }
374 else
375 {
376 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
377 }
378 pDescr++;
379 break;
380 }
381
382 case CSN_VARIABLE_TARRAY_OFFSET:
383 case CSN_VARIABLE_TARRAY:
384 case CSN_TYPE_ARRAY:
385 {
386 gint16 Status;
387 csnStream_t arT = *ar;
388 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100389 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300390
391 pui8 = pui8DATA(data, pDescr->offset);
392 if (pDescr->type == CSN_VARIABLE_TARRAY)
393 { /* Count specified in field */
394 nCount = *pui8DATA(data, pDescr->i);
395 }
396 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
397 { /* Count specified in field */
398 nCount = *pui8DATA(data, pDescr->i);
399 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
400 }
401
402 while (nCount > 0)
403 { /* resulting array of length 0 is possible
404 * but no bits shall be read from bitstream
405 */
406
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400407 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300408 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100409 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300410 if (Status >= 0)
411 {
412 pui8 += nSize;
413 remaining_bits_len = arT.remaining_bits_len;
414 bit_offset = arT.bit_offset;
415 }
416 else
417 {
418 return Status;
419 }
420 nCount--;
421 }
422
423 pDescr++;
424 break;
425 }
426
427 case CSN_BITMAP:
428 { /* bitmap with given length. The result is left aligned! */
429 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
430
431 if (no_of_bits > 0)
432 {
433
434 if (no_of_bits <= 32)
435 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400436 for(unsigned ib = 0; ib < 4; ib++)
437 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100438 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400439 pui8 = pui8DATA(data, pDescr->offset+ib);
440 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400441 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400442 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300443 }
444 else if (no_of_bits <= 64)
445 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400446 for(unsigned ib = 0; ib < 8; ib++)
447 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100448 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400449 pui8 = pui8DATA(data, pDescr->offset+ib);
450 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400451 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400452 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300453 }
454 else
455 {
456 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
457 }
458
459 remaining_bits_len -= no_of_bits;
460 assert(remaining_bits_len >= 0);
461 bit_offset += no_of_bits;
462 }
463 /* bitmap was successfully extracted or it was empty */
464
465 pDescr++;
466 break;
467 }
468
469 case CSN_TYPE:
470 {
471 gint16 Status;
472 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400473 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300474 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100475 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400476 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300477 if (Status >= 0)
478 {
479 remaining_bits_len = arT.remaining_bits_len;
480 bit_offset = arT.bit_offset;
481 pDescr++;
482 }
483 else
484 {
485 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
486 return Status;
487 }
488
489 break;
490 }
491
492 case CSN_CHOICE:
493 {
494 gint16 count = pDescr->i;
495 guint8 i = 0;
496 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
497
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700498 /* Make sure that the list of choice items is not empty */
499 if (!count)
500 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
501
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300502 while (count > 0)
503 {
504 guint8 no_of_bits = pChoice->bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100505 guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300506 if (value == pChoice->value)
507 {
508 CSN_DESCR descr[2];
509 gint16 Status;
510 csnStream_t arT = *ar;
511
512 descr[0] = pChoice->descr;
513 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
514 descr[1].type = CSN_END;
515 pui8 = pui8DATA(data, pDescr->offset);
516 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400517 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100518 if (!pChoice->keep_bits) {
519 bit_offset += no_of_bits;
520 remaining_bits_len -= no_of_bits;
521 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300522
523 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100524 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300525
526 if (Status >= 0)
527 {
528 remaining_bits_len = arT.remaining_bits_len;
529 bit_offset = arT.bit_offset;
530 }
531 else
532 {
533 return Status;
534 }
535 break;
536 }
537
538 readIndex -= no_of_bits;
539 count--;
540 pChoice++;
541 i++;
542 }
543
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700544 /* Neither of the choice items matched => unknown value */
545 if (!count)
546 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
547
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300548 pDescr++;
549 break;
550 }
551
552 case CSN_SERIALIZE:
553 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100554 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300555 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400556 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300557 gint16 Status = -1;
558
Alexander Couzensccde5c92017-02-04 03:10:08 +0100559 guint8 length = bitvec_read_field(vector, &readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300560
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400561 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400562 bit_offset += length_len;
563 remaining_bits_len -= length_len;
564
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100565 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100566 arT.direction = 1;
Vadim Yanitskiy8a87f912020-02-17 01:19:10 +0700567 LOGPC(DCSN1, LOGL_NOTICE, "offset = %d | ", (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100568 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300569
570 if (Status >= 0)
571 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100572 if (length > 0) {
573 remaining_bits_len -= length;
574 bit_offset += length;
575 } else {
576 remaining_bits_len = arT.remaining_bits_len;
577 bit_offset = arT.bit_offset;
578 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300579 pDescr++;
580 }
581 else
582 {
583 /* Has already been processed: */
584 return Status;
585 }
586
587 break;
588 }
589
590 case CSN_UNION_LH:
591 case CSN_UNION:
592 {
593 gint16 Bits;
594 guint8 index;
595 gint16 count = pDescr->i;
596 const CSN_DESCR* pDescrNext = pDescr;
597
598 pDescrNext += count + 1; /* now this is next after the union */
599 if ((count <= 0) || (count > 16))
600 {
601 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
602 }
603
604 /* Now get the bits to extract the index */
605 Bits = ixBitsTab[count];
606 index = 0;
607
608 while (Bits > 0)
609 {
610 index <<= 1;
611
612 if (CSN_UNION_LH == pDescr->type)
613 {
614 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
615 }
616 else
617 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100618 index |= bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300619 }
620 remaining_bits_len--;
621 bit_offset++;
622 Bits--;
623 }
624
625 /* Assign UnionType */
626 pui8 = pui8DATA(data, pDescr->offset);
627 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100628
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300629
630 /* script index to continue on, limited in case we do not have a power of 2 */
631 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400632 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300633
634 switch (pDescr->type)
635 { /* get the right element of the union based on computed index */
636
637 case CSN_BIT:
638 {
639 pui8 = pui8DATA(data, pDescr->offset);
640 *pui8 = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100641 if (bitvec_read_field(vector, &readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300642 {
643 *pui8 = 0x01;
644 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400645 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300646 remaining_bits_len -= 1;
647 bit_offset++;
648 pDescr++;
649 break;
650 }
651
652 case CSN_NULL:
653 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100654 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300655 pDescr++;
656 break;
657 }
658
659 case CSN_UINT:
660 {
661 guint8 no_of_bits = (guint8) pDescr->i;
662 if (remaining_bits_len >= no_of_bits)
663 {
664 remaining_bits_len -= no_of_bits;
665
666 if (no_of_bits <= 8)
667 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100668 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300669 pui8 = pui8DATA(data, pDescr->offset);
670 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400671 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300672 }
673 else if (no_of_bits <= 16)
674 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100675 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300676 pui16 = pui16DATA(data, pDescr->offset);
677 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400678 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300679 }
680 else if (no_of_bits <= 32)
681 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100682 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300683 pui32 = pui32DATA(data, pDescr->offset);
684 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400685 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300686 }
687 else
688 {
689 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
690 }
691 }
692 else
693 {
694 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
695 }
696
697 bit_offset += no_of_bits;
698 pDescr++;
699 break;
700 }
701
702 case CSN_UINT_OFFSET:
703 {
704 guint8 no_of_bits = (guint8) pDescr->i;
705
706 if (remaining_bits_len >= no_of_bits)
707 {
708 if (no_of_bits <= 8)
709 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100710 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300711 pui8 = pui8DATA(data, pDescr->offset);
712 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400713 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300714 }
715 else if (no_of_bits <= 16)
716 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100717 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300718 pui16 = pui16DATA(data, pDescr->offset);
719 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400720 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300721 }
722 else if (no_of_bits <= 32)
723 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100724 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300725 pui32 = pui32DATA(data, pDescr->offset);
726 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400727 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300728 }
729 else
730 {
731 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
732 }
733 }
734 else
735 {
736 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
737 }
738
739 bit_offset += no_of_bits;
740 pDescr++;
741 break;
742 }
743
744 case CSN_UINT_LH:
745 {
746 guint8 no_of_bits = (guint8) pDescr->i;
747
748 if (remaining_bits_len >= no_of_bits)
749 {
750 if (no_of_bits <= 8)
751 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100752 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300753 pui8 = pui8DATA(data, pDescr->offset);
754 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400755 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300756 }
757 else
758 { /* Maybe we should support more than 8 bits ? */
759 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
760 }
761 }
762 else
763 {
764 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
765 }
766
767 bit_offset += no_of_bits;
768 pDescr++;
769 break;
770 }
771
772 case CSN_UINT_ARRAY:
773 {
774 guint8 no_of_bits = (guint8) pDescr->i;
775 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
776
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100777 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300778 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
779 nCount = *pui16DATA(data, nCount);
780 }
781
782 if (remaining_bits_len >= no_of_bits)
783 {
784 remaining_bits_len -= (no_of_bits * nCount);
785 if (no_of_bits <= 8)
786 {
787 pui8 = pui8DATA(data, pDescr->offset);
788
789 while (nCount > 0)
790 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100791 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400792 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300793 pui8++;
794 bit_offset += no_of_bits;
795 nCount--;
796 }
797 }
798 else if (no_of_bits <= 16)
799 {
800 pui16 = pui16DATA(data, pDescr->offset);
801
802 while (nCount > 0)
803 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100804 *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400805 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300806 pui16++;
807 bit_offset += no_of_bits;
808 nCount--;
809 }
810 }
811 else if (no_of_bits <= 32)
812 { /* not supported */
813 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
814 }
815 else
816 {
817 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
818 }
819 }
820 else
821 {
822 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
823 }
824
825 pDescr++;
826 break;
827 }
828
829 case CSN_VARIABLE_TARRAY_OFFSET:
830 case CSN_VARIABLE_TARRAY:
831 case CSN_TYPE_ARRAY:
832 {
833 gint16 Status;
834 csnStream_t arT = *ar;
835 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100836 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300837
838 pui8 = pui8DATA(data, pDescr->offset);
839
840 if (CSN_VARIABLE_TARRAY == pDescr->type)
841 { /* Count specified in field */
842 nCount = *pui8DATA(data, pDescr->i);
843 }
844 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
845 { /* Count specified in field */
846 nCount = *pui8DATA(data, pDescr->i);
847 nCount--; /* Offset 1 */
848 }
849
850 while (nCount--) /* Changed to handle length = 0. */
851 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400852 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300853 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100854 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300855 if (Status >= 0)
856 {
857 pui8 += nSize;
858 remaining_bits_len = arT.remaining_bits_len;
859 bit_offset = arT.bit_offset;
860 }
861 else
862 {
863 return Status;
864 }
865 }
866
867 pDescr++;
868 break;
869 }
870
871 case CSN_BITMAP:
872 { /* bitmap with given length. The result is left aligned! */
873 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
874
875 if (no_of_bits > 0)
876 {
877
878 if (no_of_bits <= 32)
879 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100880 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300881 pui32 = pui32DATA(data, pDescr->offset);
882 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300883 }
884 else if (no_of_bits <= 64)
885 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100886 guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300887 pui64 = pui64DATA(data, pDescr->offset);
888 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200889 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300890 }
891 else
892 {
893 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
894 }
895
896 remaining_bits_len -= no_of_bits;
897 assert(remaining_bits_len >= 0);
898 bit_offset += no_of_bits;
899 }
900 /* bitmap was successfully extracted or it was empty */
901
902 pDescr++;
903 break;
904 }
905
906 case CSN_TYPE:
907 {
908 gint16 Status;
909 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400910 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300911 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100912 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400913 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300914 if (Status >= 0)
915 {
916 remaining_bits_len = arT.remaining_bits_len;
917 bit_offset = arT.bit_offset;
918 pDescr++;
919 }
920 else
921 { /* return error code Has already been processed: */
922 return Status;
923 }
924
925 break;
926 }
927
928 default:
929 { /* descriptions of union elements other than above are illegal */
930 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
931 }
932 }
933
934 pDescr = pDescrNext;
935 break;
936 }
937
938 case CSN_EXIST:
939 case CSN_EXIST_LH:
940 {
941 guint8 fExist;
942
943 pui8 = pui8DATA(data, pDescr->offset);
944
945 if (CSN_EXIST_LH == pDescr->type)
946 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100947 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300948 }
949 else
950 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100951 fExist = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300952 }
953
954 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400955 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300956 pDescr++;
957 remaining_bits_len -= 1;
958
959 if (!fExist)
960 {
961 ar->remaining_bits_len = remaining_bits_len;
962 ar->bit_offset = bit_offset;
963 return remaining_bits_len;
964 }
965
966 break;
967 }
968
969 case CSN_NEXT_EXIST:
970 {
971 guint8 fExist;
972
973 pui8 = pui8DATA(data, pDescr->offset);
974
975 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400976 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300977 { /* no more bits to decode is fine here - end of message detected and allowed */
978
979 /* Skip i entries + this entry */
980 pDescr += pDescr->i + 1;
981
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300982 /* Set the data member to "not exist" */
983 *pui8 = 0;
984 break;
985 }
986
987 /* the "regular" M_NEXT_EXIST description element */
988
989 fExist = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100990 if (bitvec_read_field(vector, &readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300991 {
992 fExist = 0x01;
993 }
994
995 *pui8 = fExist;
996 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400997 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300998 ++bit_offset;
999
1000 if (fExist == 0)
1001 { /* Skip 'i' entries */
1002 pDescr += pDescr->i;
1003 }
1004
1005 pDescr++;
1006 break;
1007 }
1008
1009 case CSN_NEXT_EXIST_LH:
1010 {
1011 guint8 fExist;
1012 pui8 = pui8DATA(data, pDescr->offset);
1013
1014 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1015 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1016 { /* no more bits to decode is fine here - end of message detected and allowed */
1017
1018 /* skip 'i' entries + this entry */
1019 pDescr += pDescr->i + 1;
1020
1021 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1022 if ( pDescr->type != CSN_END )
1023 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1024 remaining_bits_len--;
1025 }
1026
1027 /* set the data member to "not exist" */
1028 *pui8 = 0;
1029 break;
1030 }
1031
1032 /* the "regular" M_NEXT_EXIST_LH description element */
1033 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001034 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001035 *pui8++ = fExist;
1036 remaining_bits_len -= 1;
1037
1038 bit_offset++;
1039
1040 if (fExist == 0)
1041 { /* Skip 'i' entries */
1042 pDescr += pDescr->i;
1043 }
1044 pDescr++;
1045
1046 break;
1047 }
1048
1049 case CSN_VARIABLE_BITMAP_1:
1050 { /* Bitmap from here and to the end of message */
1051
1052 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1053
1054 /*no break -
1055 * with a length set we have a regular variable length bitmap so we continue */
1056 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001057 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001058 case CSN_VARIABLE_BITMAP:
1059 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1060 * <N: bit (5)> <bitmap: bit(N + offset)>
1061 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1062 * The result is right aligned!
1063 */
1064 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1065
1066 no_of_bits += pDescr->i; /* adjusted by offset */
1067
1068 if (no_of_bits > 0)
1069 {
1070 remaining_bits_len -= no_of_bits;
1071
1072 if (remaining_bits_len < 0)
1073 {
1074 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1075 }
1076
1077 { /* extract bits */
1078 guint8* pui8 = pui8DATA(data, pDescr->offset);
1079 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1080
1081 if (nB1 > 0)
1082 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001083 *pui8 = bitvec_read_field(vector, &readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001084 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001085 pui8++;
1086 no_of_bits -= nB1;
1087 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1088 }
1089
1090 /* remaining no_of_bits is a multiple of 8 or 0 */
1091 while (no_of_bits > 0)
1092 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001093 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001094 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001095 pui8++;
1096 no_of_bits -= 8;
1097 }
1098 }
1099 }
1100 pDescr++;
1101 break;
1102 }
1103
1104 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1105 { /* Bitmap from here and to the end of message */
1106
1107 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1108
1109 /* no break -
1110 * with a length set we have a regular left aligned variable length bitmap so we continue
1111 */
1112 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001113 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001114 case CSN_LEFT_ALIGNED_VAR_BMP:
1115 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1116 * <N: bit (5)> <bitmap: bit(N + offset)>
1117 * bit array with length (in bits) specified in parameter (pDescr->descr)
1118 */
1119 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1120
1121 no_of_bits += pDescr->i;/* size adjusted by offset */
1122
1123 if (no_of_bits > 0)
1124 {
1125 remaining_bits_len -= no_of_bits;
1126
1127 if (remaining_bits_len < 0)
1128 {
1129 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1130 }
1131
1132 { /* extract bits */
1133 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001134
Neels Hofmeyr02415262016-09-02 02:15:26 +02001135 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001136 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001137 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001138 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001139 pui8++;
1140 no_of_bits -= 8;
1141 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001142 if (no_of_bits > 0)
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001143 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001144 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001145 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001146 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001147 bit_offset += no_of_bits;
1148 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001149 }
1150 }
1151 }
1152
1153 /* bitmap was successfully extracted or it was empty */
1154 pDescr++;
1155 break;
1156 }
1157
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001158 case CSN_PADDING_BITS:
1159 { /* Padding from here and to the end of message */
1160 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1161 if (remaining_bits_len > 0)
1162 {
1163 while (remaining_bits_len > 0)
1164 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001165 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001166 if (bits_to_handle > 0)
1167 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001168 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001169 remaining_bits_len -= bits_to_handle;
1170 bit_offset += bits_to_handle;
1171 }
1172 else if (bits_to_handle == 0)
1173 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001174 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001175 remaining_bits_len -= 8;
1176 bit_offset += 8;
1177 }
1178 }
1179 }
1180 if (remaining_bits_len < 0)
1181 {
1182 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1183 }
1184
1185 /* Padding was successfully extracted or it was empty */
1186 pDescr++;
1187 break;
1188 }
1189
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001190 case CSN_VARIABLE_ARRAY:
1191 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1192 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1193 * Array with length specified in parameter:
1194 * <count: bit (x)>
1195 * <list: octet(count + offset)>
1196 */
1197 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1198
1199 count += pDescr->i; /* Adjusted by offset */
1200
1201 if (count > 0)
1202 {
1203 remaining_bits_len -= count * 8;
1204
1205 if (remaining_bits_len < 0)
1206 {
1207 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1208 }
1209
1210 pui8 = pui8DATA(data, pDescr->offset);
1211
1212 while (count > 0)
1213 {
1214 readIndex -= 8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001215 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001216 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001217 pui8++;
1218 bit_offset += 8;
1219 count--;
1220 }
1221 }
1222
1223 pDescr++;
1224 break;
1225 }
1226
1227 case CSN_RECURSIVE_ARRAY:
1228 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1229 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1230 * where <element> ::= bit(value)
1231 * <tag> ::= 0 | 1
1232 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1233 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1234 * REMARK: recursive way to specify an array but an iterative implementation!
1235 */
1236 gint16 no_of_bits = pDescr->i;
1237 guint8 ElementCount = 0;
1238
1239 pui8 = pui8DATA(data, pDescr->offset);
1240
Alexander Couzensccde5c92017-02-04 03:10:08 +01001241 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001242 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001243 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001244 bit_offset++;
1245 remaining_bits_len--;
1246
1247 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001248 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001249 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001250 pui8++;
1251 remaining_bits_len -= no_of_bits;
1252 ElementCount++;
1253
1254 if (remaining_bits_len < 0)
1255 {
1256 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1257 }
1258
1259 bit_offset += no_of_bits;
1260 }
1261
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001262 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001263 /* existNextElement() returned FALSE, 1 bit consumed */
1264 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001265 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001266
1267 /* Store the counted number of elements of the array */
1268 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1269
1270 pDescr++;
1271 break;
1272 }
1273
1274 case CSN_RECURSIVE_TARRAY:
1275 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1276 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1277 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1278 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001279 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001280 guint8 ElementCount = 0;
1281 pui8 = pui8DATA(data, pDescr->offset);
1282
Alexander Couzensccde5c92017-02-04 03:10:08 +01001283 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001284 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001285 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001286 /* existNextElement() returned TRUE, 1 bit consumed */
1287 bit_offset++;
1288 remaining_bits_len--;
1289 ElementCount++;
1290
1291 { /* unpack the following data structure */
1292 csnStream_t arT = *ar;
1293 gint16 Status;
1294 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001295 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001296
1297 if (Status >= 0)
1298 { /* successful completion */
1299 pui8 += nSizeElement; /* -> to next data element */
1300 remaining_bits_len = arT.remaining_bits_len;
1301 bit_offset = arT.bit_offset;
1302 }
1303 else
1304 { /* something went awry */
1305 return Status;
1306 }
1307 }
1308
1309 if (remaining_bits_len < 0)
1310 {
1311 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1312 }
1313 }
1314
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001315 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001316
1317 /* existNextElement() returned FALSE, 1 bit consumed */
1318 bit_offset++;
1319
1320 /* Store the counted number of elements of the array */
1321 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1322
1323 pDescr++;
1324 break;
1325 }
1326
1327 case CSN_RECURSIVE_TARRAY_2:
1328 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1329
1330 Tag = REVERSED_TAG;
1331
1332 /* NO break -
1333 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1334 */
1335 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001336 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001337 case CSN_RECURSIVE_TARRAY_1:
1338 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1339 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1340 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1341 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001342 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001343 guint8 ElementCount = 0;
1344 csnStream_t arT = *ar;
1345 gboolean EndOfList = FALSE;
1346 gint16 Status;
1347 pui8 = pui8DATA(data, pDescr->offset);
1348
1349 do
1350 { /* get data element */
1351 ElementCount++;
1352
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001353 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001354
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001355 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001356 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001357
1358 if (Status >= 0)
1359 { /* successful completion */
1360 pui8 += nSizeElement; /* -> to next */
1361 remaining_bits_len = arT.remaining_bits_len;
1362 bit_offset = arT.bit_offset;
1363 }
1364 else
1365 { /* something went awry */
1366 return Status;
1367 }
1368
1369 if (remaining_bits_len < 0)
1370 {
1371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1372 }
1373
1374 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001375 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001376 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001377
1378 bit_offset++;
1379 remaining_bits_len--; /* 1 bit consumed (tag) */
1380 } while (!EndOfList);
1381
1382
1383 /* Store the count of the array */
1384 *pui8DATA(data, pDescr->i) = ElementCount;
1385 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1386 pDescr++;
1387 break;
1388 }
1389
1390 case CSN_FIXED:
1391 { /* Verify the fixed bits */
1392 guint8 no_of_bits = (guint8) pDescr->i;
1393 guint32 ui32;
1394
1395 if (no_of_bits <= 32)
1396 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001397 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001398 }
1399 else
1400 {
1401 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1402 }
1403 if (ui32 != (unsigned)(gint32)pDescr->offset)
1404 {
1405 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1406 }
1407
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001408 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001409 remaining_bits_len -= no_of_bits;
1410 bit_offset += no_of_bits;
1411 pDescr++;
1412 break;
1413 }
1414
1415 case CSN_CALLBACK:
1416 {
1417 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1418 break;
1419 }
1420
1421 case CSN_TRAP_ERROR:
1422 {
1423 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1424 }
1425
1426 case CSN_END:
1427 {
1428 ar->remaining_bits_len = remaining_bits_len;
1429 ar->bit_offset = bit_offset;
1430 return remaining_bits_len;
1431 }
1432
1433 default:
1434 {
1435 assert(0);
1436 }
1437
1438
1439 }
1440
1441 } while (remaining_bits_len >= 0);
1442
1443 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1444}
1445
1446
1447
1448
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001449gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001450{
1451 gint remaining_bits_len = ar->remaining_bits_len;
1452 gint bit_offset = ar->bit_offset;
1453 guint8* pui8;
1454 guint16* pui16;
1455 guint32* pui32;
1456 guint64* pui64;
1457
1458 guint8 Tag = STANDARD_TAG;
1459
1460 if (remaining_bits_len <= 0)
1461 {
1462 return 0;
1463 }
1464
1465 do
1466 {
1467 switch (pDescr->type)
1468 {
1469 case CSN_BIT:
1470 {
1471 if (remaining_bits_len > 0)
1472 {
1473 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001474 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001475 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001476 /* end add the bit value to protocol tree */
1477 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001478 else if(pDescr->may_be_null)
1479 {
1480 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1481 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001482 else
1483 {
1484 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1485 }
1486
1487 pDescr++;
1488 remaining_bits_len--;
1489 bit_offset++;
1490 break;
1491 }
1492
1493 case CSN_NULL:
1494 { /* Empty member! */
1495 pDescr++;
1496 break;
1497 }
1498
1499 case CSN_UINT:
1500 {
1501 guint8 no_of_bits = (guint8) pDescr->i;
1502
1503 if (remaining_bits_len >= no_of_bits)
1504 {
1505 if (no_of_bits <= 8)
1506 {
1507 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001508 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001509 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001510 }
1511 else if (no_of_bits <= 16)
1512 {
1513 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001514 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001515 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001516 }
1517 else if (no_of_bits <= 32)
1518 {
1519 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001520 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001521 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001522 }
1523 else
1524 {
1525 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1526 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001527
1528 remaining_bits_len -= no_of_bits;
1529 bit_offset += no_of_bits;
1530 }
1531 else if(pDescr->may_be_null)
1532 {
1533 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001534 }
1535 else
1536 {
1537 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1538 }
1539
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001540 pDescr++;
1541 break;
1542 }
1543
1544 case CSN_UINT_OFFSET:
1545 {
1546 guint8 no_of_bits = (guint8) pDescr->i;
1547
1548 if (remaining_bits_len >= no_of_bits)
1549 {
1550 if (no_of_bits <= 8)
1551 {
1552 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001553 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001554 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001555 }
1556 else if (no_of_bits <= 16)
1557 {
1558 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001559 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001560 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001561 }
1562 else if (no_of_bits <= 32)
1563 {
1564 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001565 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001566 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001567 }
1568 else
1569 {
1570 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1571 }
1572 }
1573 else
1574 {
1575 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1576 }
1577
1578 remaining_bits_len -= no_of_bits;
1579 bit_offset += no_of_bits;
1580 pDescr++;
1581 break;
1582 }
1583
1584 case CSN_UINT_LH:
1585 {
1586 guint8 no_of_bits = (guint8) pDescr->i;
1587
1588 if (remaining_bits_len >= no_of_bits)
1589 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001590 if (no_of_bits <= 8)
1591 {
1592 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001593 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001594 // TODO : Change get_masked_bits8()
1595 writeIndex -= no_of_bits;
1596 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1597 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001598 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001599 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001600
1601 }
1602 else
1603 {/* Maybe we should support more than 8 bits ? */
1604 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1605 }
1606 }
1607 else
1608 {
1609 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1610 }
1611
1612 remaining_bits_len -= no_of_bits;
1613 bit_offset += no_of_bits;
1614 pDescr++;
1615 break;
1616 }
1617
1618 case CSN_UINT_ARRAY:
1619 {
1620 guint8 no_of_bits = (guint8) pDescr->i;
1621 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1622
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001623 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001624 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1625 nCount = *pui16DATA(data, nCount);
1626 }
1627
1628 if (remaining_bits_len >= no_of_bits)
1629 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001630 if (no_of_bits <= 8)
1631 {
1632 pui8 = pui8DATA(data, pDescr->offset);
1633 do
1634 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001635 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001636 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001637 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001638 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001639 bit_offset += no_of_bits;
1640 } while (--nCount > 0);
1641 }
1642 else if (no_of_bits <= 16)
1643 {
1644 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1645 }
1646 else if (no_of_bits <= 32)
1647 {
1648 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1649 }
1650 else
1651 {
1652 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1653 }
1654 }
1655 else
1656 {
1657 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1658 }
1659 pDescr++;
1660 break;
1661 }
1662
1663 case CSN_VARIABLE_TARRAY_OFFSET:
1664 case CSN_VARIABLE_TARRAY:
1665 case CSN_TYPE_ARRAY:
1666 {
1667 gint16 Status;
1668 csnStream_t arT = *ar;
1669 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001670 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001671
1672 pui8 = pui8DATA(data, pDescr->offset);
1673 if (pDescr->type == CSN_VARIABLE_TARRAY)
1674 { /* Count specified in field */
1675 nCount = *pui8DATA(data, pDescr->i);
1676 }
1677 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1678 { /* Count specified in field */
1679 nCount = *pui8DATA(data, pDescr->i);
1680 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1681 }
1682
1683 while (nCount > 0)
1684 { /* resulting array of length 0 is possible
1685 * but no bits shall be read from bitstream
1686 */
1687
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001688 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001689 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1690 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1691 if (Status >= 0)
1692 {
1693 pui8 += nSize;
1694 remaining_bits_len = arT.remaining_bits_len;
1695 bit_offset = arT.bit_offset;
1696
1697 }
1698 else
1699 {
1700 return Status;
1701 }
1702 nCount--;
1703 }
1704
1705 pDescr++;
1706 break;
1707 }
1708
1709 case CSN_BITMAP:
1710 { /* bitmap with given length. The result is left aligned! */
1711 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1712
1713 if (no_of_bits > 0)
1714 {
1715
1716 if (no_of_bits <= 32)
1717 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001718 for(unsigned ib = 0; ib < 4; 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 if (no_of_bits <= 64)
1726 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001727 for(unsigned ib = 0; ib < 8; ib++)
1728 {
1729 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001730 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001731 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001732 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001733 }
1734 else
1735 {
1736 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1737 }
1738
1739 remaining_bits_len -= no_of_bits;
1740 assert(remaining_bits_len >= 0);
1741 bit_offset += no_of_bits;
1742 }
1743 /* bitmap was successfully extracted or it was empty */
1744
1745 pDescr++;
1746 break;
1747 }
1748
1749 case CSN_TYPE:
1750 {
1751 gint16 Status;
1752 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001753 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001754 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1755 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001756 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001757 if (Status >= 0)
1758 {
1759
1760 remaining_bits_len = arT.remaining_bits_len;
1761 bit_offset = arT.bit_offset;
1762 pDescr++;
1763 }
1764 else
1765 {
1766 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1767 return Status;
1768 }
1769
1770 break;
1771 }
1772
1773 case CSN_CHOICE:
1774 {
1775 //gint16 count = pDescr->i;
1776 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001777 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001778
1779 pui8 = pui8DATA(data, pDescr->offset);
1780 i = *pui8;
1781 pChoice += i;
1782 guint8 no_of_bits = pChoice->bits;
1783 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001784 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001785 bitvec_write_field(vector, &writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001786
1787 CSN_DESCR descr[2];
1788 gint16 Status;
1789 csnStream_t arT = *ar;
1790
1791 descr[0] = pChoice->descr;
1792 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1793 descr[1].type = CSN_END;
1794 bit_offset += no_of_bits;
1795 remaining_bits_len -= no_of_bits;
1796
1797 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1798 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1799
1800 if (Status >= 0)
1801 {
1802 remaining_bits_len = arT.remaining_bits_len;
1803 bit_offset = arT.bit_offset;
1804 }
1805 else
1806 {
1807 return Status;
1808 }
1809
1810 pDescr++;
1811 break;
1812 }
1813
1814 case CSN_SERIALIZE:
1815 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001816 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001817 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001818 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001819 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001820 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001821
1822 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001823 lengthIndex = writeIndex;
1824 writeIndex += length_len;
1825 bit_offset += length_len;
1826 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001827 arT.direction = 0;
1828 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1829 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001830
Alexander Couzensccde5c92017-02-04 03:10:08 +01001831 bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001832 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001833
1834 if (Status >= 0)
1835 {
1836 remaining_bits_len = arT.remaining_bits_len;
1837 bit_offset = arT.bit_offset;
1838 pDescr++;
1839 }
1840 else
1841 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001842 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001843 return Status;
1844 }
1845
1846 break;
1847 }
1848
1849 case CSN_UNION_LH:
1850 case CSN_UNION:
1851 {
1852 gint16 Bits;
1853 guint8 index;
1854 gint16 count = pDescr->i;
1855 const CSN_DESCR* pDescrNext = pDescr;
1856
1857 pDescrNext += count + 1; /* now this is next after the union */
1858 if ((count <= 0) || (count > 16))
1859 {
1860 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1861 }
1862
1863 /* Now get the bits to extract the index */
1864 Bits = ixBitsTab[count];
1865 index = 0;
1866
1867 /* Assign UnionType */
1868 pui8 = pui8DATA(data, pDescr->offset);
1869 //read index from data and write to vector
Alexander Couzensccde5c92017-02-04 03:10:08 +01001870 bitvec_write_field(vector, &writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001871
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001872 //decode index
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001873 writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001874
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001875 while (Bits > 0)
1876 {
1877 index <<= 1;
1878
1879 if (CSN_UNION_LH == pDescr->type)
1880 {
1881 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1882 }
1883 else
1884 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001885 index |= bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001886 }
1887
1888 remaining_bits_len--;
1889 bit_offset++;
1890 Bits--;
1891 }
1892
1893 writeIndex -= Bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001894 bitvec_write_field(vector, &writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001895
1896
1897 /* script index to continue on, limited in case we do not have a power of 2 */
1898 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001899 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001900
1901 switch (pDescr->type)
1902 { /* get the right element of the union based on computed index */
1903
1904 case CSN_BIT:
1905 {
1906 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001907 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001908 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001909 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001910 bit_offset++;
1911 pDescr++;
1912 break;
1913 }
1914
1915 case CSN_NULL:
1916 { /* Empty member! */
1917 pDescr++;
1918 break;
1919 }
1920
1921 case CSN_UINT:
1922 {
1923 guint8 no_of_bits = (guint8) pDescr->i;
1924 if (remaining_bits_len >= no_of_bits)
1925 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001926 if (no_of_bits <= 8)
1927 {
1928 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001929 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001930 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001931 }
1932 else if (no_of_bits <= 16)
1933 {
1934 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001935 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001936 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001937 }
1938 else if (no_of_bits <= 32)
1939 {
1940 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001941 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001942 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001943 }
1944 else
1945 {
1946 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1947 }
1948 }
1949 else
1950 {
1951 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1952 }
1953
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001954 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001955 bit_offset += no_of_bits;
1956 pDescr++;
1957 break;
1958 }
1959
1960 case CSN_UINT_OFFSET:
1961 {
1962 guint8 no_of_bits = (guint8) pDescr->i;
1963
1964 if (remaining_bits_len >= no_of_bits)
1965 {
1966 if (no_of_bits <= 8)
1967 {
1968 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001969 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001970 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001971 }
1972 else if (no_of_bits <= 16)
1973 {
1974 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001975 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001976 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001977 }
1978 else if (no_of_bits <= 32)
1979 {
1980 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001981 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001982 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001983 }
1984 else
1985 {
1986 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1987 }
1988 }
1989 else
1990 {
1991 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1992 }
1993
1994 remaining_bits_len -= no_of_bits;
1995 bit_offset += no_of_bits;
1996 pDescr++;
1997 break;
1998 }
1999
2000 case CSN_UINT_LH:
2001 {
2002 guint8 no_of_bits = (guint8) pDescr->i;
2003
2004 if (remaining_bits_len >= no_of_bits)
2005 {
2006 remaining_bits_len -= no_of_bits;
2007 if (no_of_bits <= 8)
2008 {
2009 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002010 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002011 // TODO : Change get_masked_bits8()
2012 writeIndex -= no_of_bits;
2013 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
2014 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002015 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002016 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002017
2018 }
2019 else
2020 {/* Maybe we should support more than 8 bits ? */
2021 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2022 }
2023 }
2024 else
2025 {
2026 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2027 }
2028
2029 remaining_bits_len -= no_of_bits;
2030 bit_offset += no_of_bits;
2031 pDescr++;
2032 break;
2033 }
2034
2035 case CSN_UINT_ARRAY:
2036 {
2037 guint8 no_of_bits = (guint8) pDescr->i;
2038 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2039
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002040 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002041 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2042 nCount = *pui16DATA(data, nCount);
2043 }
2044
2045 if (remaining_bits_len >= no_of_bits)
2046 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002047 if (no_of_bits <= 8)
2048 {
2049 pui8 = pui8DATA(data, pDescr->offset);
2050 do
2051 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002052 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002053 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002054 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002055 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002056 bit_offset += no_of_bits;
2057 } while (--nCount > 0);
2058 }
2059 else if (no_of_bits <= 16)
2060 {
2061 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2062 }
2063 else if (no_of_bits <= 32)
2064 {
2065 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2066 }
2067 else
2068 {
2069 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2070 }
2071 }
2072 else
2073 {
2074 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2075 }
2076 pDescr++;
2077 break;
2078 }
2079
2080 case CSN_VARIABLE_TARRAY_OFFSET:
2081 case CSN_VARIABLE_TARRAY:
2082 case CSN_TYPE_ARRAY:
2083 {
2084 gint16 Status;
2085 csnStream_t arT = *ar;
2086 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002087 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002088
2089 pui8 = pui8DATA(data, pDescr->offset);
2090 if (pDescr->type == CSN_VARIABLE_TARRAY)
2091 { /* Count specified in field */
2092 nCount = *pui8DATA(data, pDescr->i);
2093 }
2094 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2095 { /* Count specified in field */
2096 nCount = *pui8DATA(data, pDescr->i);
2097 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2098 }
2099
2100 while (nCount > 0)
2101 { /* resulting array of length 0 is possible
2102 * but no bits shall be read from bitstream
2103 */
2104
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002105 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002106 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2107 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2108 if (Status >= 0)
2109 {
2110 pui8 += nSize;
2111 remaining_bits_len = arT.remaining_bits_len;
2112 bit_offset = arT.bit_offset;
2113 }
2114 else
2115 {
2116 return Status;
2117 }
2118 nCount--;
2119 }
2120
2121 pDescr++;
2122 break;
2123 }
2124
2125 case CSN_BITMAP:
2126 { /* bitmap with given length. The result is left aligned! */
2127 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2128
2129 if (no_of_bits > 0)
2130 {
2131
2132 if (no_of_bits <= 32)
2133 {
2134 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002135 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002136 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002137 }
2138 else if (no_of_bits <= 64)
2139 {
2140 pui64 = pui64DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002141 bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002142 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002143 }
2144 else
2145 {
2146 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2147 }
2148
2149 remaining_bits_len -= no_of_bits;
2150 assert(remaining_bits_len >= 0);
2151 bit_offset += no_of_bits;
2152 }
2153 /* bitmap was successfully extracted or it was empty */
2154
2155 pDescr++;
2156 break;
2157 }
2158
2159 case CSN_TYPE:
2160 {
2161 gint16 Status;
2162 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002163 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002164 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2165 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002166 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002167 if (Status >= 0)
2168 {
2169 remaining_bits_len = arT.remaining_bits_len;
2170 bit_offset = arT.bit_offset;
2171 pDescr++;
2172 }
2173 else
2174 {
2175 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2176 return Status;
2177 }
2178
2179 break;
2180 }
2181
2182 default:
2183 { /* descriptions of union elements other than above are illegal */
2184 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2185 }
2186 }
2187
2188 pDescr = pDescrNext;
2189 break;
2190 }
2191
2192 case CSN_EXIST:
2193 case CSN_EXIST_LH:
2194 {
2195 guint8 fExist;
2196 unsigned exist = 0;
2197 pui8 = pui8DATA(data, pDescr->offset);
2198 exist = *pui8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002199 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002200 writeIndex--;
2201 if (CSN_EXIST_LH == pDescr->type)
2202 {
2203 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2204 }
2205 else
2206 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002207 fExist = bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002208 }
2209 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002210 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002211 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002212 remaining_bits_len--;
2213 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002214 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002215
2216 if (!exist)
2217 {
2218 ar->remaining_bits_len = remaining_bits_len;
2219 ar->bit_offset = bit_offset;
2220 return remaining_bits_len;
2221 }
2222 break;
2223 }
2224
2225 case CSN_NEXT_EXIST:
2226 {
2227 guint8 fExist;
2228
2229 pui8 = pui8DATA(data, pDescr->offset);
2230
2231 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002232 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002233 { /* no more bits to decode is fine here - end of message detected and allowed */
2234
2235 /* Skip i entries + this entry */
2236 pDescr += pDescr->i + 1;
2237
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002238 break;
2239 }
2240
Alexander Couzensccde5c92017-02-04 03:10:08 +01002241 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002242 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002243 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002244
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002245 remaining_bits_len--;
2246 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002247
2248 if (fExist == 0)
2249 { /* Skip 'i' entries */
2250 pDescr += pDescr->i;
2251 }
2252
2253 pDescr++;
2254 break;
2255 }
2256
2257 case CSN_NEXT_EXIST_LH:
2258 {
2259 guint8 fExist;
2260 pui8 = pui8DATA(data, pDescr->offset);
2261
2262 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2263 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2264 { /* no more bits to decode is fine here - end of message detected and allowed */
2265
2266 /* skip 'i' entries + this entry */
2267 pDescr += pDescr->i + 1;
2268
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002269 /* set the data member to "not exist" */
2270 //*pui8 = 0;
2271 break;
2272 }
2273
2274 /* the "regular" M_NEXT_EXIST_LH description element */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002275 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002276 writeIndex--;
2277 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2278 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002279 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002280 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002281
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002282 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002283 bit_offset++;
2284
2285 if (fExist == 0)
2286 { /* Skip 'i' entries */
2287 pDescr += pDescr->i;
2288 }
2289 pDescr++;
2290
2291 break;
2292 }
2293
2294 case CSN_VARIABLE_BITMAP_1:
2295 { /* Bitmap from here and to the end of message */
2296
2297 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2298
2299 /*no break -
2300 * with a length set we have a regular variable length bitmap so we continue */
2301 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002302 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002303 case CSN_VARIABLE_BITMAP:
2304 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2305 * <N: bit (5)> <bitmap: bit(N + offset)>
2306 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2307 * The result is right aligned!
2308 */
2309 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2310
2311 no_of_bits += pDescr->i; /* adjusted by offset */
2312
2313 if (no_of_bits > 0)
2314 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002315
2316 if (remaining_bits_len < 0)
2317 {
2318 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2319 }
2320
2321 { /* extract bits */
2322 guint8* pui8 = pui8DATA(data, pDescr->offset);
2323 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2324
2325 if (nB1 > 0)
2326 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002327 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002328 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002329 pui8++;
2330 no_of_bits -= nB1;
2331 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002332 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002333 }
2334
2335 /* remaining no_of_bits is a multiple of 8 or 0 */
2336 while (no_of_bits > 0)
2337 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002338 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002339 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002340 pui8++;
2341 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002342 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002343 }
2344 }
2345 }
2346 pDescr++;
2347 break;
2348 }
2349
2350 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2351 { /* Bitmap from here and to the end of message */
2352
2353 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2354
2355 /* no break -
2356 * with a length set we have a regular left aligned variable length bitmap so we continue
2357 */
2358 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002359 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002360 case CSN_LEFT_ALIGNED_VAR_BMP:
2361 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2362 * <N: bit (5)> <bitmap: bit(N + offset)>
2363 * bit array with length (in bits) specified in parameter (pDescr->descr)
2364 */
2365
2366 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2367
2368 no_of_bits += pDescr->i;/* size adjusted by offset */
2369
2370 if (no_of_bits > 0)
2371 {
2372 remaining_bits_len -= no_of_bits;
2373
2374 if (remaining_bits_len < 0)
2375 {
2376 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2377 }
2378
2379 { /* extract bits */
2380 guint8* pui8 = pui8DATA(data, pDescr->offset);
2381 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2382
2383 while (no_of_bits > 0)
2384 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002385 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002386 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002387 pui8++;
2388 no_of_bits -= 8;
2389 }
2390 if (nB1 > 0)
2391 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002392 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002393 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002394 pui8++;
2395 no_of_bits -= nB1;
2396 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2397 }
2398 }
2399
2400 }
2401
2402 /* bitmap was successfully extracted or it was empty */
2403 pDescr++;
2404 break;
2405 }
2406
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002407 case CSN_PADDING_BITS:
2408 { /* Padding from here and to the end of message */
2409 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2410 guint8 filler = 0x2b;
2411 if (remaining_bits_len > 0)
2412 {
2413 while (remaining_bits_len > 0)
2414 {
2415 guint8 bits_to_handle = remaining_bits_len%8;
2416 if (bits_to_handle > 0)
2417 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302418 /* section 11 of 44.060
2419 * The padding bits may be the 'null' string. Otherwise, the
2420 * padding bits starts with bit '0', followed by 'spare padding'
2421 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2422 */
2423 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Alexander Couzensccde5c92017-02-04 03:10:08 +01002424 bitvec_write_field(vector, &writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002425 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2426 remaining_bits_len -= bits_to_handle;
2427 bit_offset += bits_to_handle;
2428 }
2429 else if (bits_to_handle == 0)
2430 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002431 bitvec_write_field(vector, &writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002432 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2433 remaining_bits_len -= 8;
2434 bit_offset += 8;
2435 }
2436 }
2437 }
2438 if (remaining_bits_len < 0)
2439 {
2440 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2441 }
2442
2443 /* Padding was successfully extracted or it was empty */
2444 pDescr++;
2445 break;
2446 }
2447
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002448 case CSN_VARIABLE_ARRAY:
2449 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2450 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2451 * Array with length specified in parameter:
2452 * <count: bit (x)>
2453 * <list: octet(count + offset)>
2454 */
2455 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2456
2457 count += pDescr->i; /* Adjusted by offset */
2458
2459 if (count > 0)
2460 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002461 if (remaining_bits_len < 0)
2462 {
2463 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2464 }
2465
2466 pui8 = pui8DATA(data, pDescr->offset);
2467
2468 while (count > 0)
2469 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002470 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002471 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002472 pui8++;
2473 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002474 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002475 count--;
2476 }
2477 }
2478
2479 pDescr++;
2480 break;
2481 }
2482
2483 case CSN_RECURSIVE_ARRAY:
2484 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2485 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2486 * where <element> ::= bit(value)
2487 * <tag> ::= 0 | 1
2488 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2489 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2490 * REMARK: recursive way to specify an array but an iterative implementation!
2491 */
2492 gint16 no_of_bits = pDescr->i;
2493 guint8 ElementCount = 0;
2494 pui8 = pui8DATA(data, pDescr->offset);
2495 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2496 while (ElementCount > 0)
2497 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002498 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002499 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002500 bit_offset++;
2501 remaining_bits_len--;
2502
2503 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002504 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002505 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002506 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002507 ElementCount--;
2508
2509 if (remaining_bits_len < 0)
2510 {
2511 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2512 }
2513
2514 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002515 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002516 }
2517
Alexander Couzensccde5c92017-02-04 03:10:08 +01002518 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002519 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002520 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302521 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002522
2523 pDescr++;
2524 break;
2525 }
2526
2527 case CSN_RECURSIVE_TARRAY:
2528 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2529 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2530 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2531 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002532 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002533 guint8 ElementCount = 0;
2534 pui8 = pui8DATA(data, pDescr->offset);
2535 /* Store the counted number of elements of the array */
2536 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2537
2538 while (ElementCount > 0)
2539 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002540 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002541 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002542 bit_offset++;
2543
2544 remaining_bits_len--;
2545 ElementCount--;
2546
2547 { /* unpack the following data structure */
2548 csnStream_t arT = *ar;
2549 gint16 Status;
2550 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002551 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002552
2553 if (Status >= 0)
2554 { /* successful completion */
2555 pui8 += nSizeElement; /* -> to next data element */
2556 remaining_bits_len = arT.remaining_bits_len;
2557 bit_offset = arT.bit_offset;
2558 }
2559 else
2560 { /* something went awry */
2561 return Status;
2562 }
2563 }
2564
2565 if (remaining_bits_len < 0)
2566 {
2567 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2568 }
2569 }
2570
Alexander Couzensccde5c92017-02-04 03:10:08 +01002571 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002572 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002573 bit_offset++;
2574
2575 pDescr++;
2576 break;
2577 }
2578
2579 case CSN_RECURSIVE_TARRAY_2:
2580 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2581
2582 Tag = REVERSED_TAG;
2583
2584 /* NO break -
2585 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2586 */
2587 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002588 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002589 case CSN_RECURSIVE_TARRAY_1:
2590 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2591 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2592 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2593 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002594 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002595 guint8 ElementCount = 0;
2596 guint8 ElementNum = 0;
2597 csnStream_t arT = *ar;
2598 gint16 Status;
2599
2600 pui8 = pui8DATA(data, pDescr->offset);
2601 /* Store the count of the array */
2602 ElementCount = *pui8DATA(data, pDescr->i);
2603 ElementNum = ElementCount;
2604
2605 while (ElementCount > 0)
2606 { /* get data element */
2607 if (ElementCount != ElementNum)
2608 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002609 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002610 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002611 bit_offset++;
2612 remaining_bits_len--;
2613 }
2614 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002615 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002616 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002617 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002618 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002619 if (Status >= 0)
2620 { /* successful completion */
2621 pui8 += nSizeElement; /* -> to next */
2622 remaining_bits_len = arT.remaining_bits_len;
2623 bit_offset = arT.bit_offset;
2624 }
2625 else
2626 { /* something went awry */
2627 return Status;
2628 }
2629
2630 if (remaining_bits_len < 0)
2631 {
2632 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2633 }
2634
2635 }
Alexander Couzensccde5c92017-02-04 03:10:08 +01002636 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002637 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002638 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002639 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2640 pDescr++;
2641 break;
2642 }
2643
2644 case CSN_FIXED:
2645 { /* Verify the fixed bits */
2646 guint8 no_of_bits = (guint8) pDescr->i;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002647 bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002648 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002649 remaining_bits_len -= no_of_bits;
2650 bit_offset += no_of_bits;
2651 pDescr++;
2652 break;
2653 }
2654
2655 case CSN_CALLBACK:
2656 {
2657 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2658 break;
2659 }
2660
2661 case CSN_TRAP_ERROR:
2662 {
2663 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2664 }
2665
2666 case CSN_END:
2667 {
2668 ar->remaining_bits_len = remaining_bits_len;
2669 ar->bit_offset = bit_offset;
2670 return remaining_bits_len;
2671 }
2672
2673 default:
2674 {
2675 assert(0);
2676 }
2677
2678 }
2679
2680 } while (remaining_bits_len >= 0);
2681
2682 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2683}