blob: 6fab9a95867eb3f4b2fd39bbecb5eaa568a0acb3 [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
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040031#include <assert.h>
32#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020033#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
Pau Espin Pedrold636f742020-02-03 15:37:08 +010038#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030040
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030050static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
51
52
53/* Returns no_of_bits (up to 8) masked with 0x2B */
54
55static guint8
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070056get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030057{
58 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
59 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
60 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
61 guint8 result;
62 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070063 *readIndex -= relative_bit_offset;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030064 if (bit_shift >= 0)
65 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070066 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
67 *readIndex-= bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030068 result &= maskBits[no_of_bits];
69 }
70 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010071 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070072 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030073 hight_part = (guint8) (hight_part << (-bit_shift));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070074 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
75 *readIndex = *readIndex - (8 - (-bit_shift));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030076 result |= hight_part;
77 }
78 return result;
79}
80
81/**
82 * ================================================================================================
83 * set initial/start values in help data structure used for packing/unpacking operation
84 * ================================================================================================
85 */
86void
87csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
88{
89 ar->remaining_bits_len = remaining_bits_len;
90 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040091 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030092}
93
Pau Espin Pedrold636f742020-02-03 15:37:08 +010094static const struct value_string csn1_error_names[] = {
95 { CSN_OK, "General 0" },
96 { CSN_ERROR_GENERAL, "General -1" },
97 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
98 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
99 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
100 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
Vadim Yanitskiyfee767f2020-02-11 05:28:02 +0700101 { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" },
102 { CSN_ERROR_INTERNAL, "INTERNAL" },
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100103 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
104 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
105 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300106};
107
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100108
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700109static gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100110 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111{
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100112 /* Don't add trailing newline, top caller is responsible for appending it */
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100113 if (err != CSN_OK)
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700114 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %u)",
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100115 sz, get_value_string(csn1_error_names, err), err,
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700116 pDescr ? pDescr->sz : "-", *readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300117 return err;
118}
119
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100120#define ProcessError(readIndex, sz, err, pDescr) \
121 ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
122
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300123
124/**
125 * ================================================================================================
126 * Return TRUE if tag in bit stream indicates existence of next list element,
127 * otherwise return FALSE.
128 * Will work for tag values equal to both 0 and 1.
129 * ================================================================================================
130 */
131
132static gboolean
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700133existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300134{
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700135 int res = bitvec_get_bit_pos(vector, (*readIndex)++);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300136 if (Tag == STANDARD_TAG)
137 {
138 return (res > 0);
139 }
140 return (res == 0);
141}
142
143
144gint16
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700145csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300146{
147 gint remaining_bits_len = ar->remaining_bits_len;
148 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100149 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300150 guint16* pui16;
151 guint32* pui32;
152 guint64* pui64;
153 guint8 Tag = STANDARD_TAG;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700154 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300155
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700156 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300157 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700158 return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300159 }
160
161 do
162 {
163 switch (pDescr->type)
164 {
165 case CSN_BIT:
166 {
167 if (remaining_bits_len > 0)
168 {
169 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700170 *pui8 = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400171 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 /* end add the bit value to protocol tree */
173 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400174 else if(pDescr->may_be_null)
175 {
176 pui8 = pui8DATA(data, pDescr->offset);
177 *pui8 = 0;
178 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
179 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300180 else
181 {
182 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
183 }
184
185 pDescr++;
186 remaining_bits_len--;
187 bit_offset++;
188 break;
189 }
190
191 case CSN_NULL:
192 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100193 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300194 pDescr++;
195 break;
196 }
197
198 case CSN_UINT:
199 {
200 guint8 no_of_bits = (guint8) pDescr->i;
201
202 if (remaining_bits_len >= no_of_bits)
203 {
204 if (no_of_bits <= 8)
205 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700206 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300207 pui8 = pui8DATA(data, pDescr->offset);
208 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400209 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300210 }
211 else if (no_of_bits <= 16)
212 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700213 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300214 pui16 = pui16DATA(data, pDescr->offset);
215 *pui16 = ui16;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700216 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300217 }
218 else if (no_of_bits <= 32)
219 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700220 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300221 pui32 = pui32DATA(data, pDescr->offset);
222 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400223 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300224 }
225 else
226 {
227 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
228 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400229 remaining_bits_len -= no_of_bits;
230 bit_offset += no_of_bits;
231 }
232 else if(pDescr->may_be_null)
233 {
234 if (no_of_bits <= 8)
235 {
236 pui8 = pui8DATA(data, pDescr->offset);
237 *pui8 = 0;
238 }
239 else if (no_of_bits <= 16)
240 {
241 pui16 = pui16DATA(data, pDescr->offset);
242 *pui16 = 0;
243 }
244 else if (no_of_bits <= 32)
245 {
246 pui32 = pui32DATA(data, pDescr->offset);
247 *pui32 = 0;
248 }
249 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300250 }
251 else
252 {
253 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
254 }
255
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300256 pDescr++;
257 break;
258 }
259
260 case CSN_UINT_OFFSET:
261 {
262 guint8 no_of_bits = (guint8) pDescr->i;
263
264 if (remaining_bits_len >= no_of_bits)
265 {
266 if (no_of_bits <= 8)
267 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700268 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300269 pui8 = pui8DATA(data, pDescr->offset);
270 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400271 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300272 }
273 else if (no_of_bits <= 16)
274 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700275 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300276 pui16 = pui16DATA(data, pDescr->offset);
277 *pui16 = ui16 + (guint16)pDescr->descr.value;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700278 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300279 }
280 else if (no_of_bits <= 32)
281 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700282 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300283 pui32 = pui32DATA(data, pDescr->offset);
284 *pui32 = ui32 + (guint16)pDescr->descr.value;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700285 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300286 }
287 else
288 {
289 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
290 }
291 }
292 else
293 {
294 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
295 }
296
297 remaining_bits_len -= no_of_bits;
298 bit_offset += no_of_bits;
299 pDescr++;
300 break;
301 }
302
303 case CSN_UINT_LH:
304 {
305 guint8 no_of_bits = (guint8) pDescr->i;
306
307 if (remaining_bits_len >= no_of_bits)
308 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300309 if (no_of_bits <= 8)
310 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100311 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300312 pui8 = pui8DATA(data, pDescr->offset);
313 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300315 }
316 else
317 {/* Maybe we should support more than 8 bits ? */
318 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
319 }
320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
324 }
325
326 remaining_bits_len -= no_of_bits;
327 bit_offset += no_of_bits;
328 pDescr++;
329 break;
330 }
331
332 case CSN_UINT_ARRAY:
333 {
334 guint8 no_of_bits = (guint8) pDescr->i;
335 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
336
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100337 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300338 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
339 nCount = *pui16DATA(data, nCount);
340 }
341
342 if (remaining_bits_len >= no_of_bits)
343 {
344 remaining_bits_len -= (no_of_bits*nCount);
345 if (no_of_bits <= 8)
346 {
347 pui8 = pui8DATA(data, pDescr->offset);
348 do
349 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700350 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400351 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300352 pui8++;
353 bit_offset += no_of_bits;
354 } while (--nCount > 0);
355 }
356 else if (no_of_bits <= 16)
357 {
358 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
359 }
360 else if (no_of_bits <= 32)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else
365 {
366 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
367 }
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
372 }
373 pDescr++;
374 break;
375 }
376
377 case CSN_VARIABLE_TARRAY_OFFSET:
378 case CSN_VARIABLE_TARRAY:
379 case CSN_TYPE_ARRAY:
380 {
381 gint16 Status;
382 csnStream_t arT = *ar;
383 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100384 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300385
386 pui8 = pui8DATA(data, pDescr->offset);
387 if (pDescr->type == CSN_VARIABLE_TARRAY)
388 { /* Count specified in field */
389 nCount = *pui8DATA(data, pDescr->i);
390 }
391 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
395 }
396
397 while (nCount > 0)
398 { /* resulting array of length 0 is possible
399 * but no bits shall be read from bitstream
400 */
401
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400402 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300403 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100404 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300405 if (Status >= 0)
406 {
407 pui8 += nSize;
408 remaining_bits_len = arT.remaining_bits_len;
409 bit_offset = arT.bit_offset;
410 }
411 else
412 {
413 return Status;
414 }
415 nCount--;
416 }
417
418 pDescr++;
419 break;
420 }
421
422 case CSN_BITMAP:
423 { /* bitmap with given length. The result is left aligned! */
424 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
425
426 if (no_of_bits > 0)
427 {
428
429 if (no_of_bits <= 32)
430 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700431 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400432 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700433 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400434 pui8 = pui8DATA(data, pDescr->offset+ib);
435 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400436 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 }
439 else if (no_of_bits <= 64)
440 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700441 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400442 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700443 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400444 pui8 = pui8DATA(data, pDescr->offset+ib);
445 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400446 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300448 }
449 else
450 {
451 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
452 }
453
454 remaining_bits_len -= no_of_bits;
455 assert(remaining_bits_len >= 0);
456 bit_offset += no_of_bits;
457 }
458 /* bitmap was successfully extracted or it was empty */
459
460 pDescr++;
461 break;
462 }
463
464 case CSN_TYPE:
465 {
466 gint16 Status;
467 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400468 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300469 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100470 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400471 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300472 if (Status >= 0)
473 {
474 remaining_bits_len = arT.remaining_bits_len;
475 bit_offset = arT.bit_offset;
476 pDescr++;
477 }
478 else
479 {
480 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
481 return Status;
482 }
483
484 break;
485 }
486
487 case CSN_CHOICE:
488 {
489 gint16 count = pDescr->i;
490 guint8 i = 0;
491 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
492
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700493 /* Make sure that the list of choice items is not empty */
494 if (!count)
495 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
496
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300497 while (count > 0)
498 {
499 guint8 no_of_bits = pChoice->bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700500 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300501 if (value == pChoice->value)
502 {
503 CSN_DESCR descr[2];
504 gint16 Status;
505 csnStream_t arT = *ar;
506
507 descr[0] = pChoice->descr;
508 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
509 descr[1].type = CSN_END;
510 pui8 = pui8DATA(data, pDescr->offset);
511 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400512 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100513 if (!pChoice->keep_bits) {
514 bit_offset += no_of_bits;
515 remaining_bits_len -= no_of_bits;
516 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300517
518 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100519 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300520
521 if (Status >= 0)
522 {
523 remaining_bits_len = arT.remaining_bits_len;
524 bit_offset = arT.bit_offset;
525 }
526 else
527 {
528 return Status;
529 }
530 break;
531 }
532
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700533 *readIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300534 count--;
535 pChoice++;
536 i++;
537 }
538
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700539 /* Neither of the choice items matched => unknown value */
540 if (!count)
541 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
542
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300543 pDescr++;
544 break;
545 }
546
547 case CSN_SERIALIZE:
548 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100549 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300550 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400551 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300552 gint16 Status = -1;
553
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700554 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300555
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700556 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400557 bit_offset += length_len;
558 remaining_bits_len -= length_len;
559
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100560 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100561 arT.direction = 1;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700562 LOGPC(DCSN1, LOGL_NOTICE, "offset = %u | ", pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100563 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300564
565 if (Status >= 0)
566 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100567 if (length > 0) {
568 remaining_bits_len -= length;
569 bit_offset += length;
570 } else {
571 remaining_bits_len = arT.remaining_bits_len;
572 bit_offset = arT.bit_offset;
573 }
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700574
575 /* Skip bits not handled by serialize(), if any */
576 if (Status > 0) {
577 LOGPC(DCSN1, LOGL_NOTICE, "skipped = %d | ", Status);
578 *readIndex += Status;
579 }
580
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300581 pDescr++;
582 }
583 else
584 {
585 /* Has already been processed: */
586 return Status;
587 }
588
589 break;
590 }
591
592 case CSN_UNION_LH:
593 case CSN_UNION:
594 {
595 gint16 Bits;
596 guint8 index;
597 gint16 count = pDescr->i;
598 const CSN_DESCR* pDescrNext = pDescr;
599
600 pDescrNext += count + 1; /* now this is next after the union */
601 if ((count <= 0) || (count > 16))
602 {
603 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
604 }
605
606 /* Now get the bits to extract the index */
607 Bits = ixBitsTab[count];
608 index = 0;
609
610 while (Bits > 0)
611 {
612 index <<= 1;
613
614 if (CSN_UNION_LH == pDescr->type)
615 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700616 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300617 }
618 else
619 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700620 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621 }
622 remaining_bits_len--;
623 bit_offset++;
624 Bits--;
625 }
626
627 /* Assign UnionType */
628 pui8 = pui8DATA(data, pDescr->offset);
629 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100630
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300631
632 /* script index to continue on, limited in case we do not have a power of 2 */
633 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400634 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300635
636 switch (pDescr->type)
637 { /* get the right element of the union based on computed index */
638
639 case CSN_BIT:
640 {
641 pui8 = pui8DATA(data, pDescr->offset);
642 *pui8 = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700643 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300644 {
645 *pui8 = 0x01;
646 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400647 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300648 remaining_bits_len -= 1;
649 bit_offset++;
650 pDescr++;
651 break;
652 }
653
654 case CSN_NULL:
655 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100656 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300657 pDescr++;
658 break;
659 }
660
661 case CSN_UINT:
662 {
663 guint8 no_of_bits = (guint8) pDescr->i;
664 if (remaining_bits_len >= no_of_bits)
665 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300666 if (no_of_bits <= 8)
667 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700668 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300669 pui8 = pui8DATA(data, pDescr->offset);
670 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400671 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300672 }
673 else if (no_of_bits <= 16)
674 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700675 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300676 pui16 = pui16DATA(data, pDescr->offset);
677 *pui16 = ui16;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700678 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300679 }
680 else if (no_of_bits <= 32)
681 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700682 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300683 pui32 = pui32DATA(data, pDescr->offset);
684 *pui32 = ui32;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700685 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300686 }
687 else
688 {
689 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
690 }
691 }
692 else
693 {
694 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
695 }
696
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700697 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300698 bit_offset += no_of_bits;
699 pDescr++;
700 break;
701 }
702
703 case CSN_UINT_OFFSET:
704 {
705 guint8 no_of_bits = (guint8) pDescr->i;
706
707 if (remaining_bits_len >= no_of_bits)
708 {
709 if (no_of_bits <= 8)
710 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700711 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300712 pui8 = pui8DATA(data, pDescr->offset);
713 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400714 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300715 }
716 else if (no_of_bits <= 16)
717 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700718 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300719 pui16 = pui16DATA(data, pDescr->offset);
720 *pui16 = ui16 + (guint16)pDescr->descr.value;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700721 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300722 }
723 else if (no_of_bits <= 32)
724 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700725 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300726 pui32 = pui32DATA(data, pDescr->offset);
727 *pui32 = ui32 + (guint16)pDescr->descr.value;
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700728 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300729 }
730 else
731 {
732 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
733 }
734 }
735 else
736 {
737 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
738 }
739
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700740 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300741 bit_offset += no_of_bits;
742 pDescr++;
743 break;
744 }
745
746 case CSN_UINT_LH:
747 {
748 guint8 no_of_bits = (guint8) pDescr->i;
749
750 if (remaining_bits_len >= no_of_bits)
751 {
752 if (no_of_bits <= 8)
753 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100754 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300755 pui8 = pui8DATA(data, pDescr->offset);
756 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400757 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300758 }
759 else
760 { /* Maybe we should support more than 8 bits ? */
761 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
762 }
763 }
764 else
765 {
766 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
767 }
768
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700769 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300770 bit_offset += no_of_bits;
771 pDescr++;
772 break;
773 }
774
775 case CSN_UINT_ARRAY:
776 {
777 guint8 no_of_bits = (guint8) pDescr->i;
778 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
779
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100780 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300781 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
782 nCount = *pui16DATA(data, nCount);
783 }
784
785 if (remaining_bits_len >= no_of_bits)
786 {
787 remaining_bits_len -= (no_of_bits * nCount);
788 if (no_of_bits <= 8)
789 {
790 pui8 = pui8DATA(data, pDescr->offset);
791
792 while (nCount > 0)
793 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700794 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400795 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300796 pui8++;
797 bit_offset += no_of_bits;
798 nCount--;
799 }
800 }
801 else if (no_of_bits <= 16)
802 {
803 pui16 = pui16DATA(data, pDescr->offset);
804
805 while (nCount > 0)
806 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700807 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400808 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300809 pui16++;
810 bit_offset += no_of_bits;
811 nCount--;
812 }
813 }
814 else if (no_of_bits <= 32)
815 { /* not supported */
816 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
817 }
818 else
819 {
820 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
821 }
822 }
823 else
824 {
825 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
826 }
827
828 pDescr++;
829 break;
830 }
831
832 case CSN_VARIABLE_TARRAY_OFFSET:
833 case CSN_VARIABLE_TARRAY:
834 case CSN_TYPE_ARRAY:
835 {
836 gint16 Status;
837 csnStream_t arT = *ar;
838 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100839 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300840
841 pui8 = pui8DATA(data, pDescr->offset);
842
843 if (CSN_VARIABLE_TARRAY == pDescr->type)
844 { /* Count specified in field */
845 nCount = *pui8DATA(data, pDescr->i);
846 }
847 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
848 { /* Count specified in field */
849 nCount = *pui8DATA(data, pDescr->i);
850 nCount--; /* Offset 1 */
851 }
852
853 while (nCount--) /* Changed to handle length = 0. */
854 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400855 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300856 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100857 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300858 if (Status >= 0)
859 {
860 pui8 += nSize;
861 remaining_bits_len = arT.remaining_bits_len;
862 bit_offset = arT.bit_offset;
863 }
864 else
865 {
866 return Status;
867 }
868 }
869
870 pDescr++;
871 break;
872 }
873
874 case CSN_BITMAP:
875 { /* bitmap with given length. The result is left aligned! */
876 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
877
878 if (no_of_bits > 0)
879 {
880
881 if (no_of_bits <= 32)
882 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700883 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300884 pui32 = pui32DATA(data, pDescr->offset);
885 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300886 }
887 else if (no_of_bits <= 64)
888 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700889 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300890 pui64 = pui64DATA(data, pDescr->offset);
891 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200892 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300893 }
894 else
895 {
896 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
897 }
898
899 remaining_bits_len -= no_of_bits;
900 assert(remaining_bits_len >= 0);
901 bit_offset += no_of_bits;
902 }
903 /* bitmap was successfully extracted or it was empty */
904
905 pDescr++;
906 break;
907 }
908
909 case CSN_TYPE:
910 {
911 gint16 Status;
912 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400913 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300914 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100915 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400916 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300917 if (Status >= 0)
918 {
919 remaining_bits_len = arT.remaining_bits_len;
920 bit_offset = arT.bit_offset;
921 pDescr++;
922 }
923 else
924 { /* return error code Has already been processed: */
925 return Status;
926 }
927
928 break;
929 }
930
931 default:
932 { /* descriptions of union elements other than above are illegal */
933 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
934 }
935 }
936
937 pDescr = pDescrNext;
938 break;
939 }
940
941 case CSN_EXIST:
942 case CSN_EXIST_LH:
943 {
944 guint8 fExist;
945
946 pui8 = pui8DATA(data, pDescr->offset);
947
948 if (CSN_EXIST_LH == pDescr->type)
949 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100950 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300951 }
952 else
953 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700954 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300955 }
956
957 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400958 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300959 pDescr++;
Vadim Yanitskiyd8e5e8b2020-02-17 18:16:20 +0700960 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300961 remaining_bits_len -= 1;
962
963 if (!fExist)
964 {
965 ar->remaining_bits_len = remaining_bits_len;
966 ar->bit_offset = bit_offset;
967 return remaining_bits_len;
968 }
969
970 break;
971 }
972
973 case CSN_NEXT_EXIST:
974 {
975 guint8 fExist;
976
977 pui8 = pui8DATA(data, pDescr->offset);
978
979 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400980 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300981 { /* no more bits to decode is fine here - end of message detected and allowed */
982
983 /* Skip i entries + this entry */
984 pDescr += pDescr->i + 1;
985
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300986 /* Set the data member to "not exist" */
987 *pui8 = 0;
988 break;
989 }
990
991 /* the "regular" M_NEXT_EXIST description element */
992
993 fExist = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700994 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300995 {
996 fExist = 0x01;
997 }
998
999 *pui8 = fExist;
1000 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001001 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001002 ++bit_offset;
1003
1004 if (fExist == 0)
1005 { /* Skip 'i' entries */
1006 pDescr += pDescr->i;
1007 }
1008
1009 pDescr++;
1010 break;
1011 }
1012
1013 case CSN_NEXT_EXIST_LH:
1014 {
1015 guint8 fExist;
1016 pui8 = pui8DATA(data, pDescr->offset);
1017
1018 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1019 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1020 { /* no more bits to decode is fine here - end of message detected and allowed */
1021
1022 /* skip 'i' entries + this entry */
1023 pDescr += pDescr->i + 1;
1024
1025 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1026 if ( pDescr->type != CSN_END )
1027 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1028 remaining_bits_len--;
1029 }
1030
1031 /* set the data member to "not exist" */
1032 *pui8 = 0;
1033 break;
1034 }
1035
1036 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001037 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001038 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001039 *pui8++ = fExist;
1040 remaining_bits_len -= 1;
1041
1042 bit_offset++;
1043
1044 if (fExist == 0)
1045 { /* Skip 'i' entries */
1046 pDescr += pDescr->i;
1047 }
1048 pDescr++;
1049
1050 break;
1051 }
1052
1053 case CSN_VARIABLE_BITMAP_1:
1054 { /* Bitmap from here and to the end of message */
1055
1056 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1057
1058 /*no break -
1059 * with a length set we have a regular variable length bitmap so we continue */
1060 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001061 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001062 case CSN_VARIABLE_BITMAP:
1063 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1064 * <N: bit (5)> <bitmap: bit(N + offset)>
1065 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1066 * The result is right aligned!
1067 */
1068 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1069
1070 no_of_bits += pDescr->i; /* adjusted by offset */
1071
1072 if (no_of_bits > 0)
1073 {
1074 remaining_bits_len -= no_of_bits;
1075
1076 if (remaining_bits_len < 0)
1077 {
1078 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1079 }
1080
1081 { /* extract bits */
1082 guint8* pui8 = pui8DATA(data, pDescr->offset);
1083 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1084
1085 if (nB1 > 0)
1086 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001087 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001088 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001089 pui8++;
1090 no_of_bits -= nB1;
1091 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1092 }
1093
1094 /* remaining no_of_bits is a multiple of 8 or 0 */
1095 while (no_of_bits > 0)
1096 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001097 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001098 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001099 pui8++;
1100 no_of_bits -= 8;
1101 }
1102 }
1103 }
1104 pDescr++;
1105 break;
1106 }
1107
1108 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1109 { /* Bitmap from here and to the end of message */
1110
1111 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1112
1113 /* no break -
1114 * with a length set we have a regular left aligned variable length bitmap so we continue
1115 */
1116 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001117 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001118 case CSN_LEFT_ALIGNED_VAR_BMP:
1119 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1120 * <N: bit (5)> <bitmap: bit(N + offset)>
1121 * bit array with length (in bits) specified in parameter (pDescr->descr)
1122 */
1123 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1124
1125 no_of_bits += pDescr->i;/* size adjusted by offset */
1126
1127 if (no_of_bits > 0)
1128 {
1129 remaining_bits_len -= no_of_bits;
1130
1131 if (remaining_bits_len < 0)
1132 {
1133 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1134 }
1135
1136 { /* extract bits */
1137 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001138
Neels Hofmeyr02415262016-09-02 02:15:26 +02001139 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001140 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001141 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001142 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001143 pui8++;
1144 no_of_bits -= 8;
1145 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001146 if (no_of_bits > 0)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001147 {
1148 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001149 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001150 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001151 bit_offset += no_of_bits;
1152 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001153 }
1154 }
1155 }
1156
1157 /* bitmap was successfully extracted or it was empty */
1158 pDescr++;
1159 break;
1160 }
1161
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001162 case CSN_PADDING_BITS:
1163 { /* Padding from here and to the end of message */
1164 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1165 if (remaining_bits_len > 0)
1166 {
1167 while (remaining_bits_len > 0)
1168 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001169 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001170 if (bits_to_handle > 0)
1171 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001172 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001173 remaining_bits_len -= bits_to_handle;
1174 bit_offset += bits_to_handle;
1175 }
1176 else if (bits_to_handle == 0)
1177 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001178 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001179 remaining_bits_len -= 8;
1180 bit_offset += 8;
1181 }
1182 }
1183 }
1184 if (remaining_bits_len < 0)
1185 {
1186 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1187 }
1188
1189 /* Padding was successfully extracted or it was empty */
1190 pDescr++;
1191 break;
1192 }
1193
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001194 case CSN_VARIABLE_ARRAY:
1195 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1196 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1197 * Array with length specified in parameter:
1198 * <count: bit (x)>
1199 * <list: octet(count + offset)>
1200 */
1201 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1202
1203 count += pDescr->i; /* Adjusted by offset */
1204
1205 if (count > 0)
1206 {
1207 remaining_bits_len -= count * 8;
1208
1209 if (remaining_bits_len < 0)
1210 {
1211 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1212 }
1213
1214 pui8 = pui8DATA(data, pDescr->offset);
1215
1216 while (count > 0)
1217 {
1218 readIndex -= 8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001219 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001220 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001221 pui8++;
1222 bit_offset += 8;
1223 count--;
1224 }
1225 }
1226
1227 pDescr++;
1228 break;
1229 }
1230
1231 case CSN_RECURSIVE_ARRAY:
1232 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1233 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1234 * where <element> ::= bit(value)
1235 * <tag> ::= 0 | 1
1236 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1237 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1238 * REMARK: recursive way to specify an array but an iterative implementation!
1239 */
1240 gint16 no_of_bits = pDescr->i;
1241 guint8 ElementCount = 0;
1242
1243 pui8 = pui8DATA(data, pDescr->offset);
1244
Alexander Couzensccde5c92017-02-04 03:10:08 +01001245 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001246 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001247 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001248 bit_offset++;
1249 remaining_bits_len--;
1250
1251 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001252 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001253 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001254 pui8++;
1255 remaining_bits_len -= no_of_bits;
1256 ElementCount++;
1257
1258 if (remaining_bits_len < 0)
1259 {
1260 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1261 }
1262
1263 bit_offset += no_of_bits;
1264 }
1265
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001266 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001267 /* existNextElement() returned FALSE, 1 bit consumed */
1268 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001269 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001270
1271 /* Store the counted number of elements of the array */
1272 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1273
1274 pDescr++;
1275 break;
1276 }
1277
1278 case CSN_RECURSIVE_TARRAY:
1279 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1280 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1281 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1282 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001283 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001284 guint8 ElementCount = 0;
1285 pui8 = pui8DATA(data, pDescr->offset);
1286
Alexander Couzensccde5c92017-02-04 03:10:08 +01001287 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001288 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001289 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001290 /* existNextElement() returned TRUE, 1 bit consumed */
1291 bit_offset++;
1292 remaining_bits_len--;
1293 ElementCount++;
1294
1295 { /* unpack the following data structure */
1296 csnStream_t arT = *ar;
1297 gint16 Status;
1298 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001299 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001300
1301 if (Status >= 0)
1302 { /* successful completion */
1303 pui8 += nSizeElement; /* -> to next data element */
1304 remaining_bits_len = arT.remaining_bits_len;
1305 bit_offset = arT.bit_offset;
1306 }
1307 else
1308 { /* something went awry */
1309 return Status;
1310 }
1311 }
1312
1313 if (remaining_bits_len < 0)
1314 {
1315 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1316 }
1317 }
1318
Vadim Yanitskiy4b57b6d2020-02-17 19:39:52 +07001319 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001320
1321 /* existNextElement() returned FALSE, 1 bit consumed */
Vadim Yanitskiye87066d2020-02-17 18:02:32 +07001322 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001323 bit_offset++;
1324
1325 /* Store the counted number of elements of the array */
1326 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1327
1328 pDescr++;
1329 break;
1330 }
1331
1332 case CSN_RECURSIVE_TARRAY_2:
1333 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1334
1335 Tag = REVERSED_TAG;
1336
1337 /* NO break -
1338 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1339 */
1340 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001341 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001342 case CSN_RECURSIVE_TARRAY_1:
1343 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1344 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1345 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1346 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001347 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001348 guint8 ElementCount = 0;
1349 csnStream_t arT = *ar;
1350 gboolean EndOfList = FALSE;
1351 gint16 Status;
1352 pui8 = pui8DATA(data, pDescr->offset);
1353
1354 do
1355 { /* get data element */
1356 ElementCount++;
1357
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001358 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001359
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001360 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001361 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001362
1363 if (Status >= 0)
1364 { /* successful completion */
1365 pui8 += nSizeElement; /* -> to next */
1366 remaining_bits_len = arT.remaining_bits_len;
1367 bit_offset = arT.bit_offset;
1368 }
1369 else
1370 { /* something went awry */
1371 return Status;
1372 }
1373
1374 if (remaining_bits_len < 0)
1375 {
1376 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1377 }
1378
1379 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001380 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001381 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001382
1383 bit_offset++;
1384 remaining_bits_len--; /* 1 bit consumed (tag) */
1385 } while (!EndOfList);
1386
1387
1388 /* Store the count of the array */
1389 *pui8DATA(data, pDescr->i) = ElementCount;
1390 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1391 pDescr++;
1392 break;
1393 }
1394
1395 case CSN_FIXED:
1396 { /* Verify the fixed bits */
1397 guint8 no_of_bits = (guint8) pDescr->i;
1398 guint32 ui32;
1399
1400 if (no_of_bits <= 32)
1401 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001402 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001403 }
1404 else
1405 {
1406 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1407 }
1408 if (ui32 != (unsigned)(gint32)pDescr->offset)
1409 {
1410 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1411 }
1412
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001413 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001414 remaining_bits_len -= no_of_bits;
1415 bit_offset += no_of_bits;
1416 pDescr++;
1417 break;
1418 }
1419
1420 case CSN_CALLBACK:
1421 {
1422 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1423 break;
1424 }
1425
1426 case CSN_TRAP_ERROR:
1427 {
1428 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1429 }
1430
1431 case CSN_END:
1432 {
1433 ar->remaining_bits_len = remaining_bits_len;
1434 ar->bit_offset = bit_offset;
1435 return remaining_bits_len;
1436 }
1437
1438 default:
1439 {
1440 assert(0);
1441 }
1442
1443
1444 }
1445
1446 } while (remaining_bits_len >= 0);
1447
1448 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1449}
1450
1451
1452
1453
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001454gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001455{
1456 gint remaining_bits_len = ar->remaining_bits_len;
1457 gint bit_offset = ar->bit_offset;
1458 guint8* pui8;
1459 guint16* pui16;
1460 guint32* pui32;
1461 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001462 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001463
1464 guint8 Tag = STANDARD_TAG;
1465
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001466 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001467 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001468 return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001469 }
1470
1471 do
1472 {
1473 switch (pDescr->type)
1474 {
1475 case CSN_BIT:
1476 {
1477 if (remaining_bits_len > 0)
1478 {
1479 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001480 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001481 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001482 /* end add the bit value to protocol tree */
1483 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001484 else if(pDescr->may_be_null)
1485 {
1486 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1487 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001488 else
1489 {
1490 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1491 }
1492
1493 pDescr++;
1494 remaining_bits_len--;
1495 bit_offset++;
1496 break;
1497 }
1498
1499 case CSN_NULL:
1500 { /* Empty member! */
1501 pDescr++;
1502 break;
1503 }
1504
1505 case CSN_UINT:
1506 {
1507 guint8 no_of_bits = (guint8) pDescr->i;
1508
1509 if (remaining_bits_len >= no_of_bits)
1510 {
1511 if (no_of_bits <= 8)
1512 {
1513 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001514 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001515 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001516 }
1517 else if (no_of_bits <= 16)
1518 {
1519 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001520 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001521 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001522 }
1523 else if (no_of_bits <= 32)
1524 {
1525 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001526 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001527 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001528 }
1529 else
1530 {
1531 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1532 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001533
1534 remaining_bits_len -= no_of_bits;
1535 bit_offset += no_of_bits;
1536 }
1537 else if(pDescr->may_be_null)
1538 {
1539 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001540 }
1541 else
1542 {
1543 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1544 }
1545
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001546 pDescr++;
1547 break;
1548 }
1549
1550 case CSN_UINT_OFFSET:
1551 {
1552 guint8 no_of_bits = (guint8) pDescr->i;
1553
1554 if (remaining_bits_len >= no_of_bits)
1555 {
1556 if (no_of_bits <= 8)
1557 {
1558 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001559 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001560 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001561 }
1562 else if (no_of_bits <= 16)
1563 {
1564 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001565 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001566 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001567 }
1568 else if (no_of_bits <= 32)
1569 {
1570 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001571 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001572 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001573 }
1574 else
1575 {
1576 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1577 }
1578 }
1579 else
1580 {
1581 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1582 }
1583
1584 remaining_bits_len -= no_of_bits;
1585 bit_offset += no_of_bits;
1586 pDescr++;
1587 break;
1588 }
1589
1590 case CSN_UINT_LH:
1591 {
1592 guint8 no_of_bits = (guint8) pDescr->i;
1593
1594 if (remaining_bits_len >= no_of_bits)
1595 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001596 if (no_of_bits <= 8)
1597 {
1598 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001599 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001600 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001601 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001602 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001603 *writeIndex -= no_of_bits;
1604 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001605 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001606
1607 }
1608 else
1609 {/* Maybe we should support more than 8 bits ? */
1610 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1611 }
1612 }
1613 else
1614 {
1615 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1616 }
1617
1618 remaining_bits_len -= no_of_bits;
1619 bit_offset += no_of_bits;
1620 pDescr++;
1621 break;
1622 }
1623
1624 case CSN_UINT_ARRAY:
1625 {
1626 guint8 no_of_bits = (guint8) pDescr->i;
1627 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1628
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001629 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001630 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1631 nCount = *pui16DATA(data, nCount);
1632 }
1633
1634 if (remaining_bits_len >= no_of_bits)
1635 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001636 if (no_of_bits <= 8)
1637 {
1638 pui8 = pui8DATA(data, pDescr->offset);
1639 do
1640 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001641 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001642 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001643 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001644 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001645 bit_offset += no_of_bits;
1646 } while (--nCount > 0);
1647 }
1648 else if (no_of_bits <= 16)
1649 {
1650 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1651 }
1652 else if (no_of_bits <= 32)
1653 {
1654 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1655 }
1656 else
1657 {
1658 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1659 }
1660 }
1661 else
1662 {
1663 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1664 }
1665 pDescr++;
1666 break;
1667 }
1668
1669 case CSN_VARIABLE_TARRAY_OFFSET:
1670 case CSN_VARIABLE_TARRAY:
1671 case CSN_TYPE_ARRAY:
1672 {
1673 gint16 Status;
1674 csnStream_t arT = *ar;
1675 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001676 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001677
1678 pui8 = pui8DATA(data, pDescr->offset);
1679 if (pDescr->type == CSN_VARIABLE_TARRAY)
1680 { /* Count specified in field */
1681 nCount = *pui8DATA(data, pDescr->i);
1682 }
1683 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1684 { /* Count specified in field */
1685 nCount = *pui8DATA(data, pDescr->i);
1686 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1687 }
1688
1689 while (nCount > 0)
1690 { /* resulting array of length 0 is possible
1691 * but no bits shall be read from bitstream
1692 */
1693
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001694 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001695 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1696 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1697 if (Status >= 0)
1698 {
1699 pui8 += nSize;
1700 remaining_bits_len = arT.remaining_bits_len;
1701 bit_offset = arT.bit_offset;
1702
1703 }
1704 else
1705 {
1706 return Status;
1707 }
1708 nCount--;
1709 }
1710
1711 pDescr++;
1712 break;
1713 }
1714
1715 case CSN_BITMAP:
1716 { /* bitmap with given length. The result is left aligned! */
1717 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1718
1719 if (no_of_bits > 0)
1720 {
1721
1722 if (no_of_bits <= 32)
1723 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001724 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001725 {
1726 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001727 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001728 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001729 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001730 }
1731 else if (no_of_bits <= 64)
1732 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001733 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001734 {
1735 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001736 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001737 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001738 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001739 }
1740 else
1741 {
1742 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1743 }
1744
1745 remaining_bits_len -= no_of_bits;
1746 assert(remaining_bits_len >= 0);
1747 bit_offset += no_of_bits;
1748 }
1749 /* bitmap was successfully extracted or it was empty */
1750
1751 pDescr++;
1752 break;
1753 }
1754
1755 case CSN_TYPE:
1756 {
1757 gint16 Status;
1758 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001759 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001760 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1761 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001762 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001763 if (Status >= 0)
1764 {
1765
1766 remaining_bits_len = arT.remaining_bits_len;
1767 bit_offset = arT.bit_offset;
1768 pDescr++;
1769 }
1770 else
1771 {
1772 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1773 return Status;
1774 }
1775
1776 break;
1777 }
1778
1779 case CSN_CHOICE:
1780 {
1781 //gint16 count = pDescr->i;
1782 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001783 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001784
1785 pui8 = pui8DATA(data, pDescr->offset);
1786 i = *pui8;
1787 pChoice += i;
1788 guint8 no_of_bits = pChoice->bits;
1789 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001790 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001791 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001792
1793 CSN_DESCR descr[2];
1794 gint16 Status;
1795 csnStream_t arT = *ar;
1796
1797 descr[0] = pChoice->descr;
1798 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1799 descr[1].type = CSN_END;
1800 bit_offset += no_of_bits;
1801 remaining_bits_len -= no_of_bits;
1802
1803 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1804 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1805
1806 if (Status >= 0)
1807 {
1808 remaining_bits_len = arT.remaining_bits_len;
1809 bit_offset = arT.bit_offset;
1810 }
1811 else
1812 {
1813 return Status;
1814 }
1815
1816 pDescr++;
1817 break;
1818 }
1819
1820 case CSN_SERIALIZE:
1821 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001822 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001823 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001824 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001825 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001826 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001827
1828 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001829 lengthIndex = *writeIndex;
1830 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001831 bit_offset += length_len;
1832 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001833 arT.direction = 0;
1834 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1835 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001836
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001837 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
1838 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001839
1840 if (Status >= 0)
1841 {
1842 remaining_bits_len = arT.remaining_bits_len;
1843 bit_offset = arT.bit_offset;
1844 pDescr++;
1845 }
1846 else
1847 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001848 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001849 return Status;
1850 }
1851
1852 break;
1853 }
1854
1855 case CSN_UNION_LH:
1856 case CSN_UNION:
1857 {
1858 gint16 Bits;
1859 guint8 index;
1860 gint16 count = pDescr->i;
1861 const CSN_DESCR* pDescrNext = pDescr;
1862
1863 pDescrNext += count + 1; /* now this is next after the union */
1864 if ((count <= 0) || (count > 16))
1865 {
1866 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1867 }
1868
1869 /* Now get the bits to extract the index */
1870 Bits = ixBitsTab[count];
1871 index = 0;
1872
1873 /* Assign UnionType */
1874 pui8 = pui8DATA(data, pDescr->offset);
1875 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001876 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001877
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001878 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001879 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001880
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001881 while (Bits > 0)
1882 {
1883 index <<= 1;
1884
1885 if (CSN_UNION_LH == pDescr->type)
1886 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001887 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001888 }
1889 else
1890 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001891 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001892 }
1893
1894 remaining_bits_len--;
1895 bit_offset++;
1896 Bits--;
1897 }
1898
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001899 *writeIndex -= Bits;
1900 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001901
1902
1903 /* script index to continue on, limited in case we do not have a power of 2 */
1904 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001905 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001906
1907 switch (pDescr->type)
1908 { /* get the right element of the union based on computed index */
1909
1910 case CSN_BIT:
1911 {
1912 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001913 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001914 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001915 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001916 bit_offset++;
1917 pDescr++;
1918 break;
1919 }
1920
1921 case CSN_NULL:
1922 { /* Empty member! */
1923 pDescr++;
1924 break;
1925 }
1926
1927 case CSN_UINT:
1928 {
1929 guint8 no_of_bits = (guint8) pDescr->i;
1930 if (remaining_bits_len >= no_of_bits)
1931 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001932 if (no_of_bits <= 8)
1933 {
1934 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001935 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001936 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001937 }
1938 else if (no_of_bits <= 16)
1939 {
1940 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001941 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001942 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001943 }
1944 else if (no_of_bits <= 32)
1945 {
1946 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001947 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001948 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001949 }
1950 else
1951 {
1952 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1953 }
1954 }
1955 else
1956 {
1957 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1958 }
1959
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001960 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001961 bit_offset += no_of_bits;
1962 pDescr++;
1963 break;
1964 }
1965
1966 case CSN_UINT_OFFSET:
1967 {
1968 guint8 no_of_bits = (guint8) pDescr->i;
1969
1970 if (remaining_bits_len >= no_of_bits)
1971 {
1972 if (no_of_bits <= 8)
1973 {
1974 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001975 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001976 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001977 }
1978 else if (no_of_bits <= 16)
1979 {
1980 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001981 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001982 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001983 }
1984 else if (no_of_bits <= 32)
1985 {
1986 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001987 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07001988 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001989 }
1990 else
1991 {
1992 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1993 }
1994 }
1995 else
1996 {
1997 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1998 }
1999
2000 remaining_bits_len -= no_of_bits;
2001 bit_offset += no_of_bits;
2002 pDescr++;
2003 break;
2004 }
2005
2006 case CSN_UINT_LH:
2007 {
2008 guint8 no_of_bits = (guint8) pDescr->i;
2009
2010 if (remaining_bits_len >= no_of_bits)
2011 {
2012 remaining_bits_len -= no_of_bits;
2013 if (no_of_bits <= 8)
2014 {
2015 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002016 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002017 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002018 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002019 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002020 *writeIndex -= no_of_bits;
2021 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002022 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002023
2024 }
2025 else
2026 {/* Maybe we should support more than 8 bits ? */
2027 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2028 }
2029 }
2030 else
2031 {
2032 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2033 }
2034
2035 remaining_bits_len -= no_of_bits;
2036 bit_offset += no_of_bits;
2037 pDescr++;
2038 break;
2039 }
2040
2041 case CSN_UINT_ARRAY:
2042 {
2043 guint8 no_of_bits = (guint8) pDescr->i;
2044 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2045
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002046 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002047 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2048 nCount = *pui16DATA(data, nCount);
2049 }
2050
2051 if (remaining_bits_len >= no_of_bits)
2052 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002053 if (no_of_bits <= 8)
2054 {
2055 pui8 = pui8DATA(data, pDescr->offset);
2056 do
2057 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002058 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002059 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002060 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002061 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002062 bit_offset += no_of_bits;
2063 } while (--nCount > 0);
2064 }
2065 else if (no_of_bits <= 16)
2066 {
2067 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2068 }
2069 else if (no_of_bits <= 32)
2070 {
2071 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2072 }
2073 else
2074 {
2075 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2076 }
2077 }
2078 else
2079 {
2080 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2081 }
2082 pDescr++;
2083 break;
2084 }
2085
2086 case CSN_VARIABLE_TARRAY_OFFSET:
2087 case CSN_VARIABLE_TARRAY:
2088 case CSN_TYPE_ARRAY:
2089 {
2090 gint16 Status;
2091 csnStream_t arT = *ar;
2092 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002093 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002094
2095 pui8 = pui8DATA(data, pDescr->offset);
2096 if (pDescr->type == CSN_VARIABLE_TARRAY)
2097 { /* Count specified in field */
2098 nCount = *pui8DATA(data, pDescr->i);
2099 }
2100 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2101 { /* Count specified in field */
2102 nCount = *pui8DATA(data, pDescr->i);
2103 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2104 }
2105
2106 while (nCount > 0)
2107 { /* resulting array of length 0 is possible
2108 * but no bits shall be read from bitstream
2109 */
2110
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002111 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002112 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2113 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2114 if (Status >= 0)
2115 {
2116 pui8 += nSize;
2117 remaining_bits_len = arT.remaining_bits_len;
2118 bit_offset = arT.bit_offset;
2119 }
2120 else
2121 {
2122 return Status;
2123 }
2124 nCount--;
2125 }
2126
2127 pDescr++;
2128 break;
2129 }
2130
2131 case CSN_BITMAP:
2132 { /* bitmap with given length. The result is left aligned! */
2133 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2134
2135 if (no_of_bits > 0)
2136 {
2137
2138 if (no_of_bits <= 32)
2139 {
2140 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002141 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Vadim Yanitskiy15530492020-02-17 19:38:22 +07002142 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002143 }
2144 else if (no_of_bits <= 64)
2145 {
2146 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002147 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002148 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002149 }
2150 else
2151 {
2152 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2153 }
2154
2155 remaining_bits_len -= no_of_bits;
2156 assert(remaining_bits_len >= 0);
2157 bit_offset += no_of_bits;
2158 }
2159 /* bitmap was successfully extracted or it was empty */
2160
2161 pDescr++;
2162 break;
2163 }
2164
2165 case CSN_TYPE:
2166 {
2167 gint16 Status;
2168 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002169 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002170 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2171 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002172 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002173 if (Status >= 0)
2174 {
2175 remaining_bits_len = arT.remaining_bits_len;
2176 bit_offset = arT.bit_offset;
2177 pDescr++;
2178 }
2179 else
2180 {
2181 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2182 return Status;
2183 }
2184
2185 break;
2186 }
2187
2188 default:
2189 { /* descriptions of union elements other than above are illegal */
2190 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2191 }
2192 }
2193
2194 pDescr = pDescrNext;
2195 break;
2196 }
2197
2198 case CSN_EXIST:
2199 case CSN_EXIST_LH:
2200 {
2201 guint8 fExist;
2202 unsigned exist = 0;
2203 pui8 = pui8DATA(data, pDescr->offset);
2204 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002205 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002206 writeIndex--;
2207 if (CSN_EXIST_LH == pDescr->type)
2208 {
2209 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2210 }
2211 else
2212 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002213 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002214 }
2215 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002216 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002217 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002218 remaining_bits_len--;
2219 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002220 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002221
2222 if (!exist)
2223 {
2224 ar->remaining_bits_len = remaining_bits_len;
2225 ar->bit_offset = bit_offset;
2226 return remaining_bits_len;
2227 }
2228 break;
2229 }
2230
2231 case CSN_NEXT_EXIST:
2232 {
2233 guint8 fExist;
2234
2235 pui8 = pui8DATA(data, pDescr->offset);
2236
2237 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002238 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002239 { /* no more bits to decode is fine here - end of message detected and allowed */
2240
2241 /* Skip i entries + this entry */
2242 pDescr += pDescr->i + 1;
2243
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002244 break;
2245 }
2246
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002247 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002248 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002249 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002250
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002251 remaining_bits_len--;
2252 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002253
2254 if (fExist == 0)
2255 { /* Skip 'i' entries */
2256 pDescr += pDescr->i;
2257 }
2258
2259 pDescr++;
2260 break;
2261 }
2262
2263 case CSN_NEXT_EXIST_LH:
2264 {
2265 guint8 fExist;
2266 pui8 = pui8DATA(data, pDescr->offset);
2267
2268 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2269 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2270 { /* no more bits to decode is fine here - end of message detected and allowed */
2271
2272 /* skip 'i' entries + this entry */
2273 pDescr += pDescr->i + 1;
2274
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002275 /* set the data member to "not exist" */
2276 //*pui8 = 0;
2277 break;
2278 }
2279
2280 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002281 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002282 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002283 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002284 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002285 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002286 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002287
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002288 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002289 bit_offset++;
2290
2291 if (fExist == 0)
2292 { /* Skip 'i' entries */
2293 pDescr += pDescr->i;
2294 }
2295 pDescr++;
2296
2297 break;
2298 }
2299
2300 case CSN_VARIABLE_BITMAP_1:
2301 { /* Bitmap from here and to the end of message */
2302
2303 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2304
2305 /*no break -
2306 * with a length set we have a regular variable length bitmap so we continue */
2307 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002308 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002309 case CSN_VARIABLE_BITMAP:
2310 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2311 * <N: bit (5)> <bitmap: bit(N + offset)>
2312 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2313 * The result is right aligned!
2314 */
2315 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2316
2317 no_of_bits += pDescr->i; /* adjusted by offset */
2318
2319 if (no_of_bits > 0)
2320 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002321
2322 if (remaining_bits_len < 0)
2323 {
2324 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2325 }
2326
2327 { /* extract bits */
2328 guint8* pui8 = pui8DATA(data, pDescr->offset);
2329 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2330
2331 if (nB1 > 0)
2332 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002333 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002334 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002335 pui8++;
2336 no_of_bits -= nB1;
2337 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002338 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002339 }
2340
2341 /* remaining no_of_bits is a multiple of 8 or 0 */
2342 while (no_of_bits > 0)
2343 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002344 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002345 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002346 pui8++;
2347 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002348 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002349 }
2350 }
2351 }
2352 pDescr++;
2353 break;
2354 }
2355
2356 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2357 { /* Bitmap from here and to the end of message */
2358
2359 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2360
2361 /* no break -
2362 * with a length set we have a regular left aligned variable length bitmap so we continue
2363 */
2364 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002365 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002366 case CSN_LEFT_ALIGNED_VAR_BMP:
2367 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2368 * <N: bit (5)> <bitmap: bit(N + offset)>
2369 * bit array with length (in bits) specified in parameter (pDescr->descr)
2370 */
2371
2372 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2373
2374 no_of_bits += pDescr->i;/* size adjusted by offset */
2375
2376 if (no_of_bits > 0)
2377 {
2378 remaining_bits_len -= no_of_bits;
2379
2380 if (remaining_bits_len < 0)
2381 {
2382 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2383 }
2384
2385 { /* extract bits */
2386 guint8* pui8 = pui8DATA(data, pDescr->offset);
2387 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2388
2389 while (no_of_bits > 0)
2390 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002391 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002392 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002393 pui8++;
2394 no_of_bits -= 8;
2395 }
2396 if (nB1 > 0)
2397 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002398 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002399 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002400 pui8++;
2401 no_of_bits -= nB1;
2402 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2403 }
2404 }
2405
2406 }
2407
2408 /* bitmap was successfully extracted or it was empty */
2409 pDescr++;
2410 break;
2411 }
2412
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002413 case CSN_PADDING_BITS:
2414 { /* Padding from here and to the end of message */
2415 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2416 guint8 filler = 0x2b;
2417 if (remaining_bits_len > 0)
2418 {
2419 while (remaining_bits_len > 0)
2420 {
2421 guint8 bits_to_handle = remaining_bits_len%8;
2422 if (bits_to_handle > 0)
2423 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302424 /* section 11 of 44.060
2425 * The padding bits may be the 'null' string. Otherwise, the
2426 * padding bits starts with bit '0', followed by 'spare padding'
2427 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2428 */
2429 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002430 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002431 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2432 remaining_bits_len -= bits_to_handle;
2433 bit_offset += bits_to_handle;
2434 }
2435 else if (bits_to_handle == 0)
2436 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002437 bitvec_write_field(vector, writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002438 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2439 remaining_bits_len -= 8;
2440 bit_offset += 8;
2441 }
2442 }
2443 }
2444 if (remaining_bits_len < 0)
2445 {
2446 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2447 }
2448
2449 /* Padding was successfully extracted or it was empty */
2450 pDescr++;
2451 break;
2452 }
2453
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002454 case CSN_VARIABLE_ARRAY:
2455 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2456 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2457 * Array with length specified in parameter:
2458 * <count: bit (x)>
2459 * <list: octet(count + offset)>
2460 */
2461 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2462
2463 count += pDescr->i; /* Adjusted by offset */
2464
2465 if (count > 0)
2466 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002467 if (remaining_bits_len < 0)
2468 {
2469 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2470 }
2471
2472 pui8 = pui8DATA(data, pDescr->offset);
2473
2474 while (count > 0)
2475 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002476 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002477 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002478 pui8++;
2479 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002480 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002481 count--;
2482 }
2483 }
2484
2485 pDescr++;
2486 break;
2487 }
2488
2489 case CSN_RECURSIVE_ARRAY:
2490 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2491 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2492 * where <element> ::= bit(value)
2493 * <tag> ::= 0 | 1
2494 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2495 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2496 * REMARK: recursive way to specify an array but an iterative implementation!
2497 */
2498 gint16 no_of_bits = pDescr->i;
2499 guint8 ElementCount = 0;
2500 pui8 = pui8DATA(data, pDescr->offset);
2501 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2502 while (ElementCount > 0)
2503 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002504 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002505 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002506 bit_offset++;
2507 remaining_bits_len--;
2508
2509 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002510 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002511 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002512 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002513 ElementCount--;
2514
2515 if (remaining_bits_len < 0)
2516 {
2517 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2518 }
2519
2520 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002521 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002522 }
2523
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002524 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002525 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002526 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302527 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002528
2529 pDescr++;
2530 break;
2531 }
2532
2533 case CSN_RECURSIVE_TARRAY:
2534 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2535 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2536 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2537 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002538 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002539 guint8 ElementCount = 0;
2540 pui8 = pui8DATA(data, pDescr->offset);
2541 /* Store the counted number of elements of the array */
2542 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2543
2544 while (ElementCount > 0)
2545 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002546 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002547 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002548 bit_offset++;
2549
2550 remaining_bits_len--;
2551 ElementCount--;
2552
2553 { /* unpack the following data structure */
2554 csnStream_t arT = *ar;
2555 gint16 Status;
2556 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002557 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002558
2559 if (Status >= 0)
2560 { /* successful completion */
2561 pui8 += nSizeElement; /* -> to next data element */
2562 remaining_bits_len = arT.remaining_bits_len;
2563 bit_offset = arT.bit_offset;
2564 }
2565 else
2566 { /* something went awry */
2567 return Status;
2568 }
2569 }
2570
2571 if (remaining_bits_len < 0)
2572 {
2573 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2574 }
2575 }
2576
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002577 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002578 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002579 bit_offset++;
2580
2581 pDescr++;
2582 break;
2583 }
2584
2585 case CSN_RECURSIVE_TARRAY_2:
2586 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2587
2588 Tag = REVERSED_TAG;
2589
2590 /* NO break -
2591 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2592 */
2593 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002594 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002595 case CSN_RECURSIVE_TARRAY_1:
2596 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2597 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2598 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2599 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002600 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002601 guint8 ElementCount = 0;
2602 guint8 ElementNum = 0;
2603 csnStream_t arT = *ar;
2604 gint16 Status;
2605
2606 pui8 = pui8DATA(data, pDescr->offset);
2607 /* Store the count of the array */
2608 ElementCount = *pui8DATA(data, pDescr->i);
2609 ElementNum = ElementCount;
2610
2611 while (ElementCount > 0)
2612 { /* get data element */
2613 if (ElementCount != ElementNum)
2614 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002615 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002616 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002617 bit_offset++;
2618 remaining_bits_len--;
2619 }
2620 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002621 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002622 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002623 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002624 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002625 if (Status >= 0)
2626 { /* successful completion */
2627 pui8 += nSizeElement; /* -> to next */
2628 remaining_bits_len = arT.remaining_bits_len;
2629 bit_offset = arT.bit_offset;
2630 }
2631 else
2632 { /* something went awry */
2633 return Status;
2634 }
2635
2636 if (remaining_bits_len < 0)
2637 {
2638 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2639 }
2640
2641 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002642 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002643 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002644 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002645 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2646 pDescr++;
2647 break;
2648 }
2649
2650 case CSN_FIXED:
2651 { /* Verify the fixed bits */
2652 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002653 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002654 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002655 remaining_bits_len -= no_of_bits;
2656 bit_offset += no_of_bits;
2657 pDescr++;
2658 break;
2659 }
2660
2661 case CSN_CALLBACK:
2662 {
2663 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2664 break;
2665 }
2666
2667 case CSN_TRAP_ERROR:
2668 {
2669 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2670 }
2671
2672 case CSN_END:
2673 {
2674 ar->remaining_bits_len = remaining_bits_len;
2675 ar->bit_offset = bit_offset;
2676 return remaining_bits_len;
2677 }
2678
2679 default:
2680 {
2681 assert(0);
2682 }
2683
2684 }
2685
2686 } while (remaining_bits_len >= 0);
2687
2688 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2689}