blob: 7e75972aa6386059bc99ae8086f737988d27d9cd [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31#include <iostream>
32#include <cstdlib>
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040033#include <assert.h>
34#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020035#define __STDC_FORMAT_MACROS
36#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040038#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030039
Pau Espin Pedrold636f742020-02-03 15:37:08 +010040extern "C" {
41#include <osmocom/core/logging.h>
42#include <osmocom/core/utils.h>
43}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030044
45#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
46#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
47#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
48#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
49#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
50/* used to tag existence of next element in variable length lists */
51#define STANDARD_TAG 1
52#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030053
54using namespace std;
55static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
56
57
58/* Returns no_of_bits (up to 8) masked with 0x2B */
59
60static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040061get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030062{
63 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
64 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
65 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
66 guint8 result;
67 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
68 readIndex -= relative_bit_offset;
69 if (bit_shift >= 0)
70 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010071 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030072 readIndex-= bit_shift;
73 result &= maskBits[no_of_bits];
74 }
75 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010076 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010077 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030078 hight_part = (guint8) (hight_part << (-bit_shift));
Alexander Couzensccde5c92017-02-04 03:10:08 +010079 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030080 readIndex = readIndex - (8 - (-bit_shift));
81 result |= hight_part;
82 }
83 return result;
84}
85
86/**
87 * ================================================================================================
88 * set initial/start values in help data structure used for packing/unpacking operation
89 * ================================================================================================
90 */
91void
92csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
93{
94 ar->remaining_bits_len = remaining_bits_len;
95 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040096 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030097}
98
Pau Espin Pedrold636f742020-02-03 15:37:08 +010099static const struct value_string csn1_error_names[] = {
100 { CSN_OK, "General 0" },
101 { CSN_ERROR_GENERAL, "General -1" },
102 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
103 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
104 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
105 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
106 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "ILLEGAL BIT VALUE" },
107 { CSN_ERROR_ILLEGAL_BIT_VALUE, "Internal" },
108 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
109 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
110 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111};
112
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100113
114static gint16 ProcessError_impl(const char *file, int line, unsigned readIndex,
115 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116{
Pau Espin 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{
Alexander Couzensccde5c92017-02-04 03:10:08 +0100140 guint8 res = bitvec_read_field(vector, &readIndex, 1);
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
498 while (count > 0)
499 {
500 guint8 no_of_bits = pChoice->bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100501 guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300502 if (value == pChoice->value)
503 {
504 CSN_DESCR descr[2];
505 gint16 Status;
506 csnStream_t arT = *ar;
507
508 descr[0] = pChoice->descr;
509 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
510 descr[1].type = CSN_END;
511 pui8 = pui8DATA(data, pDescr->offset);
512 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400513 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100514 if (!pChoice->keep_bits) {
515 bit_offset += no_of_bits;
516 remaining_bits_len -= no_of_bits;
517 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300518
519 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100520 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300521
522 if (Status >= 0)
523 {
524 remaining_bits_len = arT.remaining_bits_len;
525 bit_offset = arT.bit_offset;
526 }
527 else
528 {
529 return Status;
530 }
531 break;
532 }
533
534 readIndex -= no_of_bits;
535 count--;
536 pChoice++;
537 i++;
538 }
539
540 pDescr++;
541 break;
542 }
543
544 case CSN_SERIALIZE:
545 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100546 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300547 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400548 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300549 gint16 Status = -1;
550
Alexander Couzensccde5c92017-02-04 03:10:08 +0100551 guint8 length = bitvec_read_field(vector, &readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300552
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400553 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400554 bit_offset += length_len;
555 remaining_bits_len -= length_len;
556
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100557 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100558 arT.direction = 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100559 LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100560 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300561
562 if (Status >= 0)
563 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100564 if (length > 0) {
565 remaining_bits_len -= length;
566 bit_offset += length;
567 } else {
568 remaining_bits_len = arT.remaining_bits_len;
569 bit_offset = arT.bit_offset;
570 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300571 pDescr++;
572 }
573 else
574 {
575 /* Has already been processed: */
576 return Status;
577 }
578
579 break;
580 }
581
582 case CSN_UNION_LH:
583 case CSN_UNION:
584 {
585 gint16 Bits;
586 guint8 index;
587 gint16 count = pDescr->i;
588 const CSN_DESCR* pDescrNext = pDescr;
589
590 pDescrNext += count + 1; /* now this is next after the union */
591 if ((count <= 0) || (count > 16))
592 {
593 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
594 }
595
596 /* Now get the bits to extract the index */
597 Bits = ixBitsTab[count];
598 index = 0;
599
600 while (Bits > 0)
601 {
602 index <<= 1;
603
604 if (CSN_UNION_LH == pDescr->type)
605 {
606 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
607 }
608 else
609 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100610 index |= bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300611 }
612 remaining_bits_len--;
613 bit_offset++;
614 Bits--;
615 }
616
617 /* Assign UnionType */
618 pui8 = pui8DATA(data, pDescr->offset);
619 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100620
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621
622 /* script index to continue on, limited in case we do not have a power of 2 */
623 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400624 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300625
626 switch (pDescr->type)
627 { /* get the right element of the union based on computed index */
628
629 case CSN_BIT:
630 {
631 pui8 = pui8DATA(data, pDescr->offset);
632 *pui8 = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100633 if (bitvec_read_field(vector, &readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300634 {
635 *pui8 = 0x01;
636 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400637 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300638 remaining_bits_len -= 1;
639 bit_offset++;
640 pDescr++;
641 break;
642 }
643
644 case CSN_NULL:
645 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100646 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300647 pDescr++;
648 break;
649 }
650
651 case CSN_UINT:
652 {
653 guint8 no_of_bits = (guint8) pDescr->i;
654 if (remaining_bits_len >= no_of_bits)
655 {
656 remaining_bits_len -= no_of_bits;
657
658 if (no_of_bits <= 8)
659 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100660 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300661 pui8 = pui8DATA(data, pDescr->offset);
662 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400663 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300664 }
665 else if (no_of_bits <= 16)
666 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100667 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300668 pui16 = pui16DATA(data, pDescr->offset);
669 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400670 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300671 }
672 else if (no_of_bits <= 32)
673 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100674 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300675 pui32 = pui32DATA(data, pDescr->offset);
676 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400677 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300678 }
679 else
680 {
681 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
682 }
683 }
684 else
685 {
686 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
687 }
688
689 bit_offset += no_of_bits;
690 pDescr++;
691 break;
692 }
693
694 case CSN_UINT_OFFSET:
695 {
696 guint8 no_of_bits = (guint8) pDescr->i;
697
698 if (remaining_bits_len >= no_of_bits)
699 {
700 if (no_of_bits <= 8)
701 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100702 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300703 pui8 = pui8DATA(data, pDescr->offset);
704 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400705 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300706 }
707 else if (no_of_bits <= 16)
708 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100709 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300710 pui16 = pui16DATA(data, pDescr->offset);
711 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400712 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300713 }
714 else if (no_of_bits <= 32)
715 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100716 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300717 pui32 = pui32DATA(data, pDescr->offset);
718 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400719 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300720 }
721 else
722 {
723 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
724 }
725 }
726 else
727 {
728 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
729 }
730
731 bit_offset += no_of_bits;
732 pDescr++;
733 break;
734 }
735
736 case CSN_UINT_LH:
737 {
738 guint8 no_of_bits = (guint8) pDescr->i;
739
740 if (remaining_bits_len >= no_of_bits)
741 {
742 if (no_of_bits <= 8)
743 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100744 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300745 pui8 = pui8DATA(data, pDescr->offset);
746 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400747 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300748 }
749 else
750 { /* Maybe we should support more than 8 bits ? */
751 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
752 }
753 }
754 else
755 {
756 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
757 }
758
759 bit_offset += no_of_bits;
760 pDescr++;
761 break;
762 }
763
764 case CSN_UINT_ARRAY:
765 {
766 guint8 no_of_bits = (guint8) pDescr->i;
767 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
768
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100769 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300770 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
771 nCount = *pui16DATA(data, nCount);
772 }
773
774 if (remaining_bits_len >= no_of_bits)
775 {
776 remaining_bits_len -= (no_of_bits * nCount);
777 if (no_of_bits <= 8)
778 {
779 pui8 = pui8DATA(data, pDescr->offset);
780
781 while (nCount > 0)
782 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100783 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400784 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300785 pui8++;
786 bit_offset += no_of_bits;
787 nCount--;
788 }
789 }
790 else if (no_of_bits <= 16)
791 {
792 pui16 = pui16DATA(data, pDescr->offset);
793
794 while (nCount > 0)
795 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100796 *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400797 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300798 pui16++;
799 bit_offset += no_of_bits;
800 nCount--;
801 }
802 }
803 else if (no_of_bits <= 32)
804 { /* not supported */
805 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
806 }
807 else
808 {
809 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
810 }
811 }
812 else
813 {
814 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
815 }
816
817 pDescr++;
818 break;
819 }
820
821 case CSN_VARIABLE_TARRAY_OFFSET:
822 case CSN_VARIABLE_TARRAY:
823 case CSN_TYPE_ARRAY:
824 {
825 gint16 Status;
826 csnStream_t arT = *ar;
827 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100828 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300829
830 pui8 = pui8DATA(data, pDescr->offset);
831
832 if (CSN_VARIABLE_TARRAY == pDescr->type)
833 { /* Count specified in field */
834 nCount = *pui8DATA(data, pDescr->i);
835 }
836 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
837 { /* Count specified in field */
838 nCount = *pui8DATA(data, pDescr->i);
839 nCount--; /* Offset 1 */
840 }
841
842 while (nCount--) /* Changed to handle length = 0. */
843 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400844 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300845 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100846 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300847 if (Status >= 0)
848 {
849 pui8 += nSize;
850 remaining_bits_len = arT.remaining_bits_len;
851 bit_offset = arT.bit_offset;
852 }
853 else
854 {
855 return Status;
856 }
857 }
858
859 pDescr++;
860 break;
861 }
862
863 case CSN_BITMAP:
864 { /* bitmap with given length. The result is left aligned! */
865 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
866
867 if (no_of_bits > 0)
868 {
869
870 if (no_of_bits <= 32)
871 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100872 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300873 pui32 = pui32DATA(data, pDescr->offset);
874 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300875 }
876 else if (no_of_bits <= 64)
877 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100878 guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300879 pui64 = pui64DATA(data, pDescr->offset);
880 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200881 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300882 }
883 else
884 {
885 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
886 }
887
888 remaining_bits_len -= no_of_bits;
889 assert(remaining_bits_len >= 0);
890 bit_offset += no_of_bits;
891 }
892 /* bitmap was successfully extracted or it was empty */
893
894 pDescr++;
895 break;
896 }
897
898 case CSN_TYPE:
899 {
900 gint16 Status;
901 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400902 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300903 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100904 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400905 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300906 if (Status >= 0)
907 {
908 remaining_bits_len = arT.remaining_bits_len;
909 bit_offset = arT.bit_offset;
910 pDescr++;
911 }
912 else
913 { /* return error code Has already been processed: */
914 return Status;
915 }
916
917 break;
918 }
919
920 default:
921 { /* descriptions of union elements other than above are illegal */
922 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
923 }
924 }
925
926 pDescr = pDescrNext;
927 break;
928 }
929
930 case CSN_EXIST:
931 case CSN_EXIST_LH:
932 {
933 guint8 fExist;
934
935 pui8 = pui8DATA(data, pDescr->offset);
936
937 if (CSN_EXIST_LH == pDescr->type)
938 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100939 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300940 }
941 else
942 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100943 fExist = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300944 }
945
946 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400947 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300948 pDescr++;
949 remaining_bits_len -= 1;
950
951 if (!fExist)
952 {
953 ar->remaining_bits_len = remaining_bits_len;
954 ar->bit_offset = bit_offset;
955 return remaining_bits_len;
956 }
957
958 break;
959 }
960
961 case CSN_NEXT_EXIST:
962 {
963 guint8 fExist;
964
965 pui8 = pui8DATA(data, pDescr->offset);
966
967 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400968 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300969 { /* no more bits to decode is fine here - end of message detected and allowed */
970
971 /* Skip i entries + this entry */
972 pDescr += pDescr->i + 1;
973
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300974 /* Set the data member to "not exist" */
975 *pui8 = 0;
976 break;
977 }
978
979 /* the "regular" M_NEXT_EXIST description element */
980
981 fExist = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100982 if (bitvec_read_field(vector, &readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300983 {
984 fExist = 0x01;
985 }
986
987 *pui8 = fExist;
988 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400989 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300990 ++bit_offset;
991
992 if (fExist == 0)
993 { /* Skip 'i' entries */
994 pDescr += pDescr->i;
995 }
996
997 pDescr++;
998 break;
999 }
1000
1001 case CSN_NEXT_EXIST_LH:
1002 {
1003 guint8 fExist;
1004 pui8 = pui8DATA(data, pDescr->offset);
1005
1006 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1007 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1008 { /* no more bits to decode is fine here - end of message detected and allowed */
1009
1010 /* skip 'i' entries + this entry */
1011 pDescr += pDescr->i + 1;
1012
1013 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1014 if ( pDescr->type != CSN_END )
1015 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1016 remaining_bits_len--;
1017 }
1018
1019 /* set the data member to "not exist" */
1020 *pui8 = 0;
1021 break;
1022 }
1023
1024 /* the "regular" M_NEXT_EXIST_LH description element */
1025 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001026 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001027 *pui8++ = fExist;
1028 remaining_bits_len -= 1;
1029
1030 bit_offset++;
1031
1032 if (fExist == 0)
1033 { /* Skip 'i' entries */
1034 pDescr += pDescr->i;
1035 }
1036 pDescr++;
1037
1038 break;
1039 }
1040
1041 case CSN_VARIABLE_BITMAP_1:
1042 { /* Bitmap from here and to the end of message */
1043
1044 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1045
1046 /*no break -
1047 * with a length set we have a regular variable length bitmap so we continue */
1048 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001049 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001050 case CSN_VARIABLE_BITMAP:
1051 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1052 * <N: bit (5)> <bitmap: bit(N + offset)>
1053 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1054 * The result is right aligned!
1055 */
1056 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1057
1058 no_of_bits += pDescr->i; /* adjusted by offset */
1059
1060 if (no_of_bits > 0)
1061 {
1062 remaining_bits_len -= no_of_bits;
1063
1064 if (remaining_bits_len < 0)
1065 {
1066 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1067 }
1068
1069 { /* extract bits */
1070 guint8* pui8 = pui8DATA(data, pDescr->offset);
1071 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1072
1073 if (nB1 > 0)
1074 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001075 *pui8 = bitvec_read_field(vector, &readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001076 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001077 pui8++;
1078 no_of_bits -= nB1;
1079 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1080 }
1081
1082 /* remaining no_of_bits is a multiple of 8 or 0 */
1083 while (no_of_bits > 0)
1084 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001085 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001086 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001087 pui8++;
1088 no_of_bits -= 8;
1089 }
1090 }
1091 }
1092 pDescr++;
1093 break;
1094 }
1095
1096 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1097 { /* Bitmap from here and to the end of message */
1098
1099 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1100
1101 /* no break -
1102 * with a length set we have a regular left aligned variable length bitmap so we continue
1103 */
1104 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001105 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001106 case CSN_LEFT_ALIGNED_VAR_BMP:
1107 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1108 * <N: bit (5)> <bitmap: bit(N + offset)>
1109 * bit array with length (in bits) specified in parameter (pDescr->descr)
1110 */
1111 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1112
1113 no_of_bits += pDescr->i;/* size adjusted by offset */
1114
1115 if (no_of_bits > 0)
1116 {
1117 remaining_bits_len -= no_of_bits;
1118
1119 if (remaining_bits_len < 0)
1120 {
1121 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1122 }
1123
1124 { /* extract bits */
1125 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001126
Neels Hofmeyr02415262016-09-02 02:15:26 +02001127 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001128 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001129 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001130 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001131 pui8++;
1132 no_of_bits -= 8;
1133 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001134 if (no_of_bits > 0)
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001135 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001136 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001137 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001138 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001139 bit_offset += no_of_bits;
1140 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001141 }
1142 }
1143 }
1144
1145 /* bitmap was successfully extracted or it was empty */
1146 pDescr++;
1147 break;
1148 }
1149
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001150 case CSN_PADDING_BITS:
1151 { /* Padding from here and to the end of message */
1152 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1153 if (remaining_bits_len > 0)
1154 {
1155 while (remaining_bits_len > 0)
1156 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001157 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001158 if (bits_to_handle > 0)
1159 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001160 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001161 remaining_bits_len -= bits_to_handle;
1162 bit_offset += bits_to_handle;
1163 }
1164 else if (bits_to_handle == 0)
1165 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001166 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001167 remaining_bits_len -= 8;
1168 bit_offset += 8;
1169 }
1170 }
1171 }
1172 if (remaining_bits_len < 0)
1173 {
1174 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1175 }
1176
1177 /* Padding was successfully extracted or it was empty */
1178 pDescr++;
1179 break;
1180 }
1181
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001182 case CSN_VARIABLE_ARRAY:
1183 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1184 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1185 * Array with length specified in parameter:
1186 * <count: bit (x)>
1187 * <list: octet(count + offset)>
1188 */
1189 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1190
1191 count += pDescr->i; /* Adjusted by offset */
1192
1193 if (count > 0)
1194 {
1195 remaining_bits_len -= count * 8;
1196
1197 if (remaining_bits_len < 0)
1198 {
1199 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1200 }
1201
1202 pui8 = pui8DATA(data, pDescr->offset);
1203
1204 while (count > 0)
1205 {
1206 readIndex -= 8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001207 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001208 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001209 pui8++;
1210 bit_offset += 8;
1211 count--;
1212 }
1213 }
1214
1215 pDescr++;
1216 break;
1217 }
1218
1219 case CSN_RECURSIVE_ARRAY:
1220 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1221 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1222 * where <element> ::= bit(value)
1223 * <tag> ::= 0 | 1
1224 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1225 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1226 * REMARK: recursive way to specify an array but an iterative implementation!
1227 */
1228 gint16 no_of_bits = pDescr->i;
1229 guint8 ElementCount = 0;
1230
1231 pui8 = pui8DATA(data, pDescr->offset);
1232
Alexander Couzensccde5c92017-02-04 03:10:08 +01001233 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001234 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001235 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001236 bit_offset++;
1237 remaining_bits_len--;
1238
1239 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001240 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001241 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001242 pui8++;
1243 remaining_bits_len -= no_of_bits;
1244 ElementCount++;
1245
1246 if (remaining_bits_len < 0)
1247 {
1248 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1249 }
1250
1251 bit_offset += no_of_bits;
1252 }
1253
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001254 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001255 /* existNextElement() returned FALSE, 1 bit consumed */
1256 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001257 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001258
1259 /* Store the counted number of elements of the array */
1260 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1261
1262 pDescr++;
1263 break;
1264 }
1265
1266 case CSN_RECURSIVE_TARRAY:
1267 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1268 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1269 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1270 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001271 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001272 guint8 ElementCount = 0;
1273 pui8 = pui8DATA(data, pDescr->offset);
1274
Alexander Couzensccde5c92017-02-04 03:10:08 +01001275 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001276 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001277 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001278 /* existNextElement() returned TRUE, 1 bit consumed */
1279 bit_offset++;
1280 remaining_bits_len--;
1281 ElementCount++;
1282
1283 { /* unpack the following data structure */
1284 csnStream_t arT = *ar;
1285 gint16 Status;
1286 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001287 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001288
1289 if (Status >= 0)
1290 { /* successful completion */
1291 pui8 += nSizeElement; /* -> to next data element */
1292 remaining_bits_len = arT.remaining_bits_len;
1293 bit_offset = arT.bit_offset;
1294 }
1295 else
1296 { /* something went awry */
1297 return Status;
1298 }
1299 }
1300
1301 if (remaining_bits_len < 0)
1302 {
1303 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1304 }
1305 }
1306
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001307 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001308
1309 /* existNextElement() returned FALSE, 1 bit consumed */
1310 bit_offset++;
1311
1312 /* Store the counted number of elements of the array */
1313 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1314
1315 pDescr++;
1316 break;
1317 }
1318
1319 case CSN_RECURSIVE_TARRAY_2:
1320 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1321
1322 Tag = REVERSED_TAG;
1323
1324 /* NO break -
1325 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1326 */
1327 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001328 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001329 case CSN_RECURSIVE_TARRAY_1:
1330 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1331 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1332 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1333 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001334 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001335 guint8 ElementCount = 0;
1336 csnStream_t arT = *ar;
1337 gboolean EndOfList = FALSE;
1338 gint16 Status;
1339 pui8 = pui8DATA(data, pDescr->offset);
1340
1341 do
1342 { /* get data element */
1343 ElementCount++;
1344
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001345 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001346
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001347 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001348 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001349
1350 if (Status >= 0)
1351 { /* successful completion */
1352 pui8 += nSizeElement; /* -> to next */
1353 remaining_bits_len = arT.remaining_bits_len;
1354 bit_offset = arT.bit_offset;
1355 }
1356 else
1357 { /* something went awry */
1358 return Status;
1359 }
1360
1361 if (remaining_bits_len < 0)
1362 {
1363 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1364 }
1365
1366 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001367 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001368 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001369
1370 bit_offset++;
1371 remaining_bits_len--; /* 1 bit consumed (tag) */
1372 } while (!EndOfList);
1373
1374
1375 /* Store the count of the array */
1376 *pui8DATA(data, pDescr->i) = ElementCount;
1377 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1378 pDescr++;
1379 break;
1380 }
1381
1382 case CSN_FIXED:
1383 { /* Verify the fixed bits */
1384 guint8 no_of_bits = (guint8) pDescr->i;
1385 guint32 ui32;
1386
1387 if (no_of_bits <= 32)
1388 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001389 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001390 }
1391 else
1392 {
1393 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1394 }
1395 if (ui32 != (unsigned)(gint32)pDescr->offset)
1396 {
1397 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1398 }
1399
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001400 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001401 remaining_bits_len -= no_of_bits;
1402 bit_offset += no_of_bits;
1403 pDescr++;
1404 break;
1405 }
1406
1407 case CSN_CALLBACK:
1408 {
1409 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1410 break;
1411 }
1412
1413 case CSN_TRAP_ERROR:
1414 {
1415 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1416 }
1417
1418 case CSN_END:
1419 {
1420 ar->remaining_bits_len = remaining_bits_len;
1421 ar->bit_offset = bit_offset;
1422 return remaining_bits_len;
1423 }
1424
1425 default:
1426 {
1427 assert(0);
1428 }
1429
1430
1431 }
1432
1433 } while (remaining_bits_len >= 0);
1434
1435 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1436}
1437
1438
1439
1440
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001441gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001442{
1443 gint remaining_bits_len = ar->remaining_bits_len;
1444 gint bit_offset = ar->bit_offset;
1445 guint8* pui8;
1446 guint16* pui16;
1447 guint32* pui32;
1448 guint64* pui64;
1449
1450 guint8 Tag = STANDARD_TAG;
1451
1452 if (remaining_bits_len <= 0)
1453 {
1454 return 0;
1455 }
1456
1457 do
1458 {
1459 switch (pDescr->type)
1460 {
1461 case CSN_BIT:
1462 {
1463 if (remaining_bits_len > 0)
1464 {
1465 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001466 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001467 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001468 /* end add the bit value to protocol tree */
1469 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001470 else if(pDescr->may_be_null)
1471 {
1472 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1473 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001474 else
1475 {
1476 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1477 }
1478
1479 pDescr++;
1480 remaining_bits_len--;
1481 bit_offset++;
1482 break;
1483 }
1484
1485 case CSN_NULL:
1486 { /* Empty member! */
1487 pDescr++;
1488 break;
1489 }
1490
1491 case CSN_UINT:
1492 {
1493 guint8 no_of_bits = (guint8) pDescr->i;
1494
1495 if (remaining_bits_len >= no_of_bits)
1496 {
1497 if (no_of_bits <= 8)
1498 {
1499 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001500 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001501 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001502 }
1503 else if (no_of_bits <= 16)
1504 {
1505 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001506 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001507 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001508 }
1509 else if (no_of_bits <= 32)
1510 {
1511 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001512 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001513 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001514 }
1515 else
1516 {
1517 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1518 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001519
1520 remaining_bits_len -= no_of_bits;
1521 bit_offset += no_of_bits;
1522 }
1523 else if(pDescr->may_be_null)
1524 {
1525 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001526 }
1527 else
1528 {
1529 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1530 }
1531
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001532 pDescr++;
1533 break;
1534 }
1535
1536 case CSN_UINT_OFFSET:
1537 {
1538 guint8 no_of_bits = (guint8) pDescr->i;
1539
1540 if (remaining_bits_len >= no_of_bits)
1541 {
1542 if (no_of_bits <= 8)
1543 {
1544 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001545 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001546 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001547 }
1548 else if (no_of_bits <= 16)
1549 {
1550 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001551 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001552 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001553 }
1554 else if (no_of_bits <= 32)
1555 {
1556 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001557 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001558 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001559 }
1560 else
1561 {
1562 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1563 }
1564 }
1565 else
1566 {
1567 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1568 }
1569
1570 remaining_bits_len -= no_of_bits;
1571 bit_offset += no_of_bits;
1572 pDescr++;
1573 break;
1574 }
1575
1576 case CSN_UINT_LH:
1577 {
1578 guint8 no_of_bits = (guint8) pDescr->i;
1579
1580 if (remaining_bits_len >= no_of_bits)
1581 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001582 if (no_of_bits <= 8)
1583 {
1584 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001585 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001586 // TODO : Change get_masked_bits8()
1587 writeIndex -= no_of_bits;
1588 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1589 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001590 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001591 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001592
1593 }
1594 else
1595 {/* Maybe we should support more than 8 bits ? */
1596 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1597 }
1598 }
1599 else
1600 {
1601 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1602 }
1603
1604 remaining_bits_len -= no_of_bits;
1605 bit_offset += no_of_bits;
1606 pDescr++;
1607 break;
1608 }
1609
1610 case CSN_UINT_ARRAY:
1611 {
1612 guint8 no_of_bits = (guint8) pDescr->i;
1613 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1614
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001615 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001616 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1617 nCount = *pui16DATA(data, nCount);
1618 }
1619
1620 if (remaining_bits_len >= no_of_bits)
1621 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001622 if (no_of_bits <= 8)
1623 {
1624 pui8 = pui8DATA(data, pDescr->offset);
1625 do
1626 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001627 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001628 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001629 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001630 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001631 bit_offset += no_of_bits;
1632 } while (--nCount > 0);
1633 }
1634 else if (no_of_bits <= 16)
1635 {
1636 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1637 }
1638 else if (no_of_bits <= 32)
1639 {
1640 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1641 }
1642 else
1643 {
1644 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1645 }
1646 }
1647 else
1648 {
1649 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1650 }
1651 pDescr++;
1652 break;
1653 }
1654
1655 case CSN_VARIABLE_TARRAY_OFFSET:
1656 case CSN_VARIABLE_TARRAY:
1657 case CSN_TYPE_ARRAY:
1658 {
1659 gint16 Status;
1660 csnStream_t arT = *ar;
1661 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001662 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001663
1664 pui8 = pui8DATA(data, pDescr->offset);
1665 if (pDescr->type == CSN_VARIABLE_TARRAY)
1666 { /* Count specified in field */
1667 nCount = *pui8DATA(data, pDescr->i);
1668 }
1669 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1670 { /* Count specified in field */
1671 nCount = *pui8DATA(data, pDescr->i);
1672 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1673 }
1674
1675 while (nCount > 0)
1676 { /* resulting array of length 0 is possible
1677 * but no bits shall be read from bitstream
1678 */
1679
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001680 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001681 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1682 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1683 if (Status >= 0)
1684 {
1685 pui8 += nSize;
1686 remaining_bits_len = arT.remaining_bits_len;
1687 bit_offset = arT.bit_offset;
1688
1689 }
1690 else
1691 {
1692 return Status;
1693 }
1694 nCount--;
1695 }
1696
1697 pDescr++;
1698 break;
1699 }
1700
1701 case CSN_BITMAP:
1702 { /* bitmap with given length. The result is left aligned! */
1703 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1704
1705 if (no_of_bits > 0)
1706 {
1707
1708 if (no_of_bits <= 32)
1709 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001710 for(unsigned ib = 0; ib < 4; ib++)
1711 {
1712 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001713 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001714 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001715 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001716 }
1717 else if (no_of_bits <= 64)
1718 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001719 for(unsigned ib = 0; ib < 8; ib++)
1720 {
1721 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001722 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001723 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001724 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001725 }
1726 else
1727 {
1728 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1729 }
1730
1731 remaining_bits_len -= no_of_bits;
1732 assert(remaining_bits_len >= 0);
1733 bit_offset += no_of_bits;
1734 }
1735 /* bitmap was successfully extracted or it was empty */
1736
1737 pDescr++;
1738 break;
1739 }
1740
1741 case CSN_TYPE:
1742 {
1743 gint16 Status;
1744 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001745 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001746 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1747 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001748 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001749 if (Status >= 0)
1750 {
1751
1752 remaining_bits_len = arT.remaining_bits_len;
1753 bit_offset = arT.bit_offset;
1754 pDescr++;
1755 }
1756 else
1757 {
1758 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1759 return Status;
1760 }
1761
1762 break;
1763 }
1764
1765 case CSN_CHOICE:
1766 {
1767 //gint16 count = pDescr->i;
1768 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001769 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001770
1771 pui8 = pui8DATA(data, pDescr->offset);
1772 i = *pui8;
1773 pChoice += i;
1774 guint8 no_of_bits = pChoice->bits;
1775 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001776 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001777 bitvec_write_field(vector, &writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001778
1779 CSN_DESCR descr[2];
1780 gint16 Status;
1781 csnStream_t arT = *ar;
1782
1783 descr[0] = pChoice->descr;
1784 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1785 descr[1].type = CSN_END;
1786 bit_offset += no_of_bits;
1787 remaining_bits_len -= no_of_bits;
1788
1789 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1790 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1791
1792 if (Status >= 0)
1793 {
1794 remaining_bits_len = arT.remaining_bits_len;
1795 bit_offset = arT.bit_offset;
1796 }
1797 else
1798 {
1799 return Status;
1800 }
1801
1802 pDescr++;
1803 break;
1804 }
1805
1806 case CSN_SERIALIZE:
1807 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001808 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001809 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001810 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001811 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001812 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001813
1814 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001815 lengthIndex = writeIndex;
1816 writeIndex += length_len;
1817 bit_offset += length_len;
1818 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001819 arT.direction = 0;
1820 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1821 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001822
Alexander Couzensccde5c92017-02-04 03:10:08 +01001823 bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001824 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001825
1826 if (Status >= 0)
1827 {
1828 remaining_bits_len = arT.remaining_bits_len;
1829 bit_offset = arT.bit_offset;
1830 pDescr++;
1831 }
1832 else
1833 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001834 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001835 return Status;
1836 }
1837
1838 break;
1839 }
1840
1841 case CSN_UNION_LH:
1842 case CSN_UNION:
1843 {
1844 gint16 Bits;
1845 guint8 index;
1846 gint16 count = pDescr->i;
1847 const CSN_DESCR* pDescrNext = pDescr;
1848
1849 pDescrNext += count + 1; /* now this is next after the union */
1850 if ((count <= 0) || (count > 16))
1851 {
1852 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1853 }
1854
1855 /* Now get the bits to extract the index */
1856 Bits = ixBitsTab[count];
1857 index = 0;
1858
1859 /* Assign UnionType */
1860 pui8 = pui8DATA(data, pDescr->offset);
1861 //read index from data and write to vector
Alexander Couzensccde5c92017-02-04 03:10:08 +01001862 bitvec_write_field(vector, &writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001863
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001864 //decode index
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001865 writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001866
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001867 while (Bits > 0)
1868 {
1869 index <<= 1;
1870
1871 if (CSN_UNION_LH == pDescr->type)
1872 {
1873 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1874 }
1875 else
1876 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001877 index |= bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001878 }
1879
1880 remaining_bits_len--;
1881 bit_offset++;
1882 Bits--;
1883 }
1884
1885 writeIndex -= Bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001886 bitvec_write_field(vector, &writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001887
1888
1889 /* script index to continue on, limited in case we do not have a power of 2 */
1890 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001891 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001892
1893 switch (pDescr->type)
1894 { /* get the right element of the union based on computed index */
1895
1896 case CSN_BIT:
1897 {
1898 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001899 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001900 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001901 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001902 bit_offset++;
1903 pDescr++;
1904 break;
1905 }
1906
1907 case CSN_NULL:
1908 { /* Empty member! */
1909 pDescr++;
1910 break;
1911 }
1912
1913 case CSN_UINT:
1914 {
1915 guint8 no_of_bits = (guint8) pDescr->i;
1916 if (remaining_bits_len >= no_of_bits)
1917 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001918 if (no_of_bits <= 8)
1919 {
1920 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001921 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001922 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001923 }
1924 else if (no_of_bits <= 16)
1925 {
1926 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001927 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001928 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001929 }
1930 else if (no_of_bits <= 32)
1931 {
1932 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001933 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001934 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001935 }
1936 else
1937 {
1938 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1939 }
1940 }
1941 else
1942 {
1943 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1944 }
1945
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001946 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001947 bit_offset += no_of_bits;
1948 pDescr++;
1949 break;
1950 }
1951
1952 case CSN_UINT_OFFSET:
1953 {
1954 guint8 no_of_bits = (guint8) pDescr->i;
1955
1956 if (remaining_bits_len >= no_of_bits)
1957 {
1958 if (no_of_bits <= 8)
1959 {
1960 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001961 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001962 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001963 }
1964 else if (no_of_bits <= 16)
1965 {
1966 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001967 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001968 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001969 }
1970 else if (no_of_bits <= 32)
1971 {
1972 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001973 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001974 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001975 }
1976 else
1977 {
1978 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1979 }
1980 }
1981 else
1982 {
1983 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1984 }
1985
1986 remaining_bits_len -= no_of_bits;
1987 bit_offset += no_of_bits;
1988 pDescr++;
1989 break;
1990 }
1991
1992 case CSN_UINT_LH:
1993 {
1994 guint8 no_of_bits = (guint8) pDescr->i;
1995
1996 if (remaining_bits_len >= no_of_bits)
1997 {
1998 remaining_bits_len -= no_of_bits;
1999 if (no_of_bits <= 8)
2000 {
2001 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002002 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002003 // TODO : Change get_masked_bits8()
2004 writeIndex -= no_of_bits;
2005 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
2006 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002007 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002008 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002009
2010 }
2011 else
2012 {/* Maybe we should support more than 8 bits ? */
2013 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2014 }
2015 }
2016 else
2017 {
2018 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2019 }
2020
2021 remaining_bits_len -= no_of_bits;
2022 bit_offset += no_of_bits;
2023 pDescr++;
2024 break;
2025 }
2026
2027 case CSN_UINT_ARRAY:
2028 {
2029 guint8 no_of_bits = (guint8) pDescr->i;
2030 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2031
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002032 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002033 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2034 nCount = *pui16DATA(data, nCount);
2035 }
2036
2037 if (remaining_bits_len >= no_of_bits)
2038 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002039 if (no_of_bits <= 8)
2040 {
2041 pui8 = pui8DATA(data, pDescr->offset);
2042 do
2043 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002044 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002045 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002046 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002047 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002048 bit_offset += no_of_bits;
2049 } while (--nCount > 0);
2050 }
2051 else if (no_of_bits <= 16)
2052 {
2053 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2054 }
2055 else if (no_of_bits <= 32)
2056 {
2057 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2058 }
2059 else
2060 {
2061 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2062 }
2063 }
2064 else
2065 {
2066 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2067 }
2068 pDescr++;
2069 break;
2070 }
2071
2072 case CSN_VARIABLE_TARRAY_OFFSET:
2073 case CSN_VARIABLE_TARRAY:
2074 case CSN_TYPE_ARRAY:
2075 {
2076 gint16 Status;
2077 csnStream_t arT = *ar;
2078 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002079 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002080
2081 pui8 = pui8DATA(data, pDescr->offset);
2082 if (pDescr->type == CSN_VARIABLE_TARRAY)
2083 { /* Count specified in field */
2084 nCount = *pui8DATA(data, pDescr->i);
2085 }
2086 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2087 { /* Count specified in field */
2088 nCount = *pui8DATA(data, pDescr->i);
2089 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2090 }
2091
2092 while (nCount > 0)
2093 { /* resulting array of length 0 is possible
2094 * but no bits shall be read from bitstream
2095 */
2096
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002097 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002098 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2099 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2100 if (Status >= 0)
2101 {
2102 pui8 += nSize;
2103 remaining_bits_len = arT.remaining_bits_len;
2104 bit_offset = arT.bit_offset;
2105 }
2106 else
2107 {
2108 return Status;
2109 }
2110 nCount--;
2111 }
2112
2113 pDescr++;
2114 break;
2115 }
2116
2117 case CSN_BITMAP:
2118 { /* bitmap with given length. The result is left aligned! */
2119 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2120
2121 if (no_of_bits > 0)
2122 {
2123
2124 if (no_of_bits <= 32)
2125 {
2126 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002127 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002128 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002129 }
2130 else if (no_of_bits <= 64)
2131 {
2132 pui64 = pui64DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002133 bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002134 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002135 }
2136 else
2137 {
2138 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2139 }
2140
2141 remaining_bits_len -= no_of_bits;
2142 assert(remaining_bits_len >= 0);
2143 bit_offset += no_of_bits;
2144 }
2145 /* bitmap was successfully extracted or it was empty */
2146
2147 pDescr++;
2148 break;
2149 }
2150
2151 case CSN_TYPE:
2152 {
2153 gint16 Status;
2154 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002155 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002156 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2157 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002158 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002159 if (Status >= 0)
2160 {
2161 remaining_bits_len = arT.remaining_bits_len;
2162 bit_offset = arT.bit_offset;
2163 pDescr++;
2164 }
2165 else
2166 {
2167 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2168 return Status;
2169 }
2170
2171 break;
2172 }
2173
2174 default:
2175 { /* descriptions of union elements other than above are illegal */
2176 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2177 }
2178 }
2179
2180 pDescr = pDescrNext;
2181 break;
2182 }
2183
2184 case CSN_EXIST:
2185 case CSN_EXIST_LH:
2186 {
2187 guint8 fExist;
2188 unsigned exist = 0;
2189 pui8 = pui8DATA(data, pDescr->offset);
2190 exist = *pui8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002191 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002192 writeIndex--;
2193 if (CSN_EXIST_LH == pDescr->type)
2194 {
2195 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2196 }
2197 else
2198 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002199 fExist = bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002200 }
2201 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002202 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002203 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002204 remaining_bits_len--;
2205 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002206 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002207
2208 if (!exist)
2209 {
2210 ar->remaining_bits_len = remaining_bits_len;
2211 ar->bit_offset = bit_offset;
2212 return remaining_bits_len;
2213 }
2214 break;
2215 }
2216
2217 case CSN_NEXT_EXIST:
2218 {
2219 guint8 fExist;
2220
2221 pui8 = pui8DATA(data, pDescr->offset);
2222
2223 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002224 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002225 { /* no more bits to decode is fine here - end of message detected and allowed */
2226
2227 /* Skip i entries + this entry */
2228 pDescr += pDescr->i + 1;
2229
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002230 break;
2231 }
2232
Alexander Couzensccde5c92017-02-04 03:10:08 +01002233 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002234 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002235 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002236
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002237 remaining_bits_len--;
2238 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002239
2240 if (fExist == 0)
2241 { /* Skip 'i' entries */
2242 pDescr += pDescr->i;
2243 }
2244
2245 pDescr++;
2246 break;
2247 }
2248
2249 case CSN_NEXT_EXIST_LH:
2250 {
2251 guint8 fExist;
2252 pui8 = pui8DATA(data, pDescr->offset);
2253
2254 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2255 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2256 { /* no more bits to decode is fine here - end of message detected and allowed */
2257
2258 /* skip 'i' entries + this entry */
2259 pDescr += pDescr->i + 1;
2260
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002261 /* set the data member to "not exist" */
2262 //*pui8 = 0;
2263 break;
2264 }
2265
2266 /* the "regular" M_NEXT_EXIST_LH description element */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002267 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002268 writeIndex--;
2269 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2270 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002271 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002272 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002273
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002274 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002275 bit_offset++;
2276
2277 if (fExist == 0)
2278 { /* Skip 'i' entries */
2279 pDescr += pDescr->i;
2280 }
2281 pDescr++;
2282
2283 break;
2284 }
2285
2286 case CSN_VARIABLE_BITMAP_1:
2287 { /* Bitmap from here and to the end of message */
2288
2289 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2290
2291 /*no break -
2292 * with a length set we have a regular variable length bitmap so we continue */
2293 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002294 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002295 case CSN_VARIABLE_BITMAP:
2296 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2297 * <N: bit (5)> <bitmap: bit(N + offset)>
2298 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2299 * The result is right aligned!
2300 */
2301 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2302
2303 no_of_bits += pDescr->i; /* adjusted by offset */
2304
2305 if (no_of_bits > 0)
2306 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002307
2308 if (remaining_bits_len < 0)
2309 {
2310 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2311 }
2312
2313 { /* extract bits */
2314 guint8* pui8 = pui8DATA(data, pDescr->offset);
2315 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2316
2317 if (nB1 > 0)
2318 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002319 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002320 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002321 pui8++;
2322 no_of_bits -= nB1;
2323 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002324 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002325 }
2326
2327 /* remaining no_of_bits is a multiple of 8 or 0 */
2328 while (no_of_bits > 0)
2329 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002330 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002331 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002332 pui8++;
2333 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002334 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002335 }
2336 }
2337 }
2338 pDescr++;
2339 break;
2340 }
2341
2342 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2343 { /* Bitmap from here and to the end of message */
2344
2345 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2346
2347 /* no break -
2348 * with a length set we have a regular left aligned variable length bitmap so we continue
2349 */
2350 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002351 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002352 case CSN_LEFT_ALIGNED_VAR_BMP:
2353 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2354 * <N: bit (5)> <bitmap: bit(N + offset)>
2355 * bit array with length (in bits) specified in parameter (pDescr->descr)
2356 */
2357
2358 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2359
2360 no_of_bits += pDescr->i;/* size adjusted by offset */
2361
2362 if (no_of_bits > 0)
2363 {
2364 remaining_bits_len -= no_of_bits;
2365
2366 if (remaining_bits_len < 0)
2367 {
2368 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2369 }
2370
2371 { /* extract bits */
2372 guint8* pui8 = pui8DATA(data, pDescr->offset);
2373 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2374
2375 while (no_of_bits > 0)
2376 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002377 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002378 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002379 pui8++;
2380 no_of_bits -= 8;
2381 }
2382 if (nB1 > 0)
2383 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002384 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002385 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002386 pui8++;
2387 no_of_bits -= nB1;
2388 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2389 }
2390 }
2391
2392 }
2393
2394 /* bitmap was successfully extracted or it was empty */
2395 pDescr++;
2396 break;
2397 }
2398
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002399 case CSN_PADDING_BITS:
2400 { /* Padding from here and to the end of message */
2401 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2402 guint8 filler = 0x2b;
2403 if (remaining_bits_len > 0)
2404 {
2405 while (remaining_bits_len > 0)
2406 {
2407 guint8 bits_to_handle = remaining_bits_len%8;
2408 if (bits_to_handle > 0)
2409 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302410 /* section 11 of 44.060
2411 * The padding bits may be the 'null' string. Otherwise, the
2412 * padding bits starts with bit '0', followed by 'spare padding'
2413 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2414 */
2415 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Alexander Couzensccde5c92017-02-04 03:10:08 +01002416 bitvec_write_field(vector, &writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002417 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2418 remaining_bits_len -= bits_to_handle;
2419 bit_offset += bits_to_handle;
2420 }
2421 else if (bits_to_handle == 0)
2422 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002423 bitvec_write_field(vector, &writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002424 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2425 remaining_bits_len -= 8;
2426 bit_offset += 8;
2427 }
2428 }
2429 }
2430 if (remaining_bits_len < 0)
2431 {
2432 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2433 }
2434
2435 /* Padding was successfully extracted or it was empty */
2436 pDescr++;
2437 break;
2438 }
2439
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002440 case CSN_VARIABLE_ARRAY:
2441 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2442 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2443 * Array with length specified in parameter:
2444 * <count: bit (x)>
2445 * <list: octet(count + offset)>
2446 */
2447 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2448
2449 count += pDescr->i; /* Adjusted by offset */
2450
2451 if (count > 0)
2452 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002453 if (remaining_bits_len < 0)
2454 {
2455 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2456 }
2457
2458 pui8 = pui8DATA(data, pDescr->offset);
2459
2460 while (count > 0)
2461 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002462 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002463 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002464 pui8++;
2465 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002466 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002467 count--;
2468 }
2469 }
2470
2471 pDescr++;
2472 break;
2473 }
2474
2475 case CSN_RECURSIVE_ARRAY:
2476 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2477 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2478 * where <element> ::= bit(value)
2479 * <tag> ::= 0 | 1
2480 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2481 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2482 * REMARK: recursive way to specify an array but an iterative implementation!
2483 */
2484 gint16 no_of_bits = pDescr->i;
2485 guint8 ElementCount = 0;
2486 pui8 = pui8DATA(data, pDescr->offset);
2487 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2488 while (ElementCount > 0)
2489 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002490 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002491 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002492 bit_offset++;
2493 remaining_bits_len--;
2494
2495 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002496 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002497 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002498 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002499 ElementCount--;
2500
2501 if (remaining_bits_len < 0)
2502 {
2503 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2504 }
2505
2506 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002507 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002508 }
2509
Alexander Couzensccde5c92017-02-04 03:10:08 +01002510 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002511 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002512 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302513 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002514
2515 pDescr++;
2516 break;
2517 }
2518
2519 case CSN_RECURSIVE_TARRAY:
2520 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2521 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2522 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2523 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002524 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002525 guint8 ElementCount = 0;
2526 pui8 = pui8DATA(data, pDescr->offset);
2527 /* Store the counted number of elements of the array */
2528 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2529
2530 while (ElementCount > 0)
2531 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002532 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002533 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002534 bit_offset++;
2535
2536 remaining_bits_len--;
2537 ElementCount--;
2538
2539 { /* unpack the following data structure */
2540 csnStream_t arT = *ar;
2541 gint16 Status;
2542 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002543 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002544
2545 if (Status >= 0)
2546 { /* successful completion */
2547 pui8 += nSizeElement; /* -> to next data element */
2548 remaining_bits_len = arT.remaining_bits_len;
2549 bit_offset = arT.bit_offset;
2550 }
2551 else
2552 { /* something went awry */
2553 return Status;
2554 }
2555 }
2556
2557 if (remaining_bits_len < 0)
2558 {
2559 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2560 }
2561 }
2562
Alexander Couzensccde5c92017-02-04 03:10:08 +01002563 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002564 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002565 bit_offset++;
2566
2567 pDescr++;
2568 break;
2569 }
2570
2571 case CSN_RECURSIVE_TARRAY_2:
2572 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2573
2574 Tag = REVERSED_TAG;
2575
2576 /* NO break -
2577 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2578 */
2579 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002580 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002581 case CSN_RECURSIVE_TARRAY_1:
2582 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2583 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2584 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2585 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002586 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002587 guint8 ElementCount = 0;
2588 guint8 ElementNum = 0;
2589 csnStream_t arT = *ar;
2590 gint16 Status;
2591
2592 pui8 = pui8DATA(data, pDescr->offset);
2593 /* Store the count of the array */
2594 ElementCount = *pui8DATA(data, pDescr->i);
2595 ElementNum = ElementCount;
2596
2597 while (ElementCount > 0)
2598 { /* get data element */
2599 if (ElementCount != ElementNum)
2600 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002601 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002602 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002603 bit_offset++;
2604 remaining_bits_len--;
2605 }
2606 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002607 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002608 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002609 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002610 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002611 if (Status >= 0)
2612 { /* successful completion */
2613 pui8 += nSizeElement; /* -> to next */
2614 remaining_bits_len = arT.remaining_bits_len;
2615 bit_offset = arT.bit_offset;
2616 }
2617 else
2618 { /* something went awry */
2619 return Status;
2620 }
2621
2622 if (remaining_bits_len < 0)
2623 {
2624 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2625 }
2626
2627 }
Alexander Couzensccde5c92017-02-04 03:10:08 +01002628 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002629 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002630 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002631 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2632 pDescr++;
2633 break;
2634 }
2635
2636 case CSN_FIXED:
2637 { /* Verify the fixed bits */
2638 guint8 no_of_bits = (guint8) pDescr->i;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002639 bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002640 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002641 remaining_bits_len -= no_of_bits;
2642 bit_offset += no_of_bits;
2643 pDescr++;
2644 break;
2645 }
2646
2647 case CSN_CALLBACK:
2648 {
2649 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2650 break;
2651 }
2652
2653 case CSN_TRAP_ERROR:
2654 {
2655 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2656 }
2657
2658 case CSN_END:
2659 {
2660 ar->remaining_bits_len = remaining_bits_len;
2661 ar->bit_offset = bit_offset;
2662 return remaining_bits_len;
2663 }
2664
2665 default:
2666 {
2667 assert(0);
2668 }
2669
2670 }
2671
2672 } while (remaining_bits_len >= 0);
2673
2674 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2675}