blob: eedad75555ed2f12db627f64d80fd084c6bed094 [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)
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100114 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %d)",
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
156 if (remaining_bits_len <= 0)
157 {
158 return 0;
159 }
160
161 do
162 {
163 switch (pDescr->type)
164 {
165 case CSN_BIT:
166 {
167 if (remaining_bits_len > 0)
168 {
169 pui8 = pui8DATA(data, pDescr->offset);
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;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400216 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", 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;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400278 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", 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;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400285 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", 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 {
309 remaining_bits_len -= no_of_bits;
310 if (no_of_bits <= 8)
311 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100312 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300313 pui8 = pui8DATA(data, pDescr->offset);
314 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400315 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300316 }
317 else
318 {/* Maybe we should support more than 8 bits ? */
319 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
320 }
321 }
322 else
323 {
324 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
325 }
326
327 remaining_bits_len -= no_of_bits;
328 bit_offset += no_of_bits;
329 pDescr++;
330 break;
331 }
332
333 case CSN_UINT_ARRAY:
334 {
335 guint8 no_of_bits = (guint8) pDescr->i;
336 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
337
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100338 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300339 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
340 nCount = *pui16DATA(data, nCount);
341 }
342
343 if (remaining_bits_len >= no_of_bits)
344 {
345 remaining_bits_len -= (no_of_bits*nCount);
346 if (no_of_bits <= 8)
347 {
348 pui8 = pui8DATA(data, pDescr->offset);
349 do
350 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700351 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400352 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300353 pui8++;
354 bit_offset += no_of_bits;
355 } while (--nCount > 0);
356 }
357 else if (no_of_bits <= 16)
358 {
359 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
360 }
361 else if (no_of_bits <= 32)
362 {
363 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
364 }
365 else
366 {
367 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
368 }
369 }
370 else
371 {
372 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
373 }
374 pDescr++;
375 break;
376 }
377
378 case CSN_VARIABLE_TARRAY_OFFSET:
379 case CSN_VARIABLE_TARRAY:
380 case CSN_TYPE_ARRAY:
381 {
382 gint16 Status;
383 csnStream_t arT = *ar;
384 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100385 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300386
387 pui8 = pui8DATA(data, pDescr->offset);
388 if (pDescr->type == CSN_VARIABLE_TARRAY)
389 { /* Count specified in field */
390 nCount = *pui8DATA(data, pDescr->i);
391 }
392 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
393 { /* Count specified in field */
394 nCount = *pui8DATA(data, pDescr->i);
395 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
396 }
397
398 while (nCount > 0)
399 { /* resulting array of length 0 is possible
400 * but no bits shall be read from bitstream
401 */
402
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400403 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300404 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100405 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300406 if (Status >= 0)
407 {
408 pui8 += nSize;
409 remaining_bits_len = arT.remaining_bits_len;
410 bit_offset = arT.bit_offset;
411 }
412 else
413 {
414 return Status;
415 }
416 nCount--;
417 }
418
419 pDescr++;
420 break;
421 }
422
423 case CSN_BITMAP:
424 { /* bitmap with given length. The result is left aligned! */
425 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
426
427 if (no_of_bits > 0)
428 {
429
430 if (no_of_bits <= 32)
431 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700432 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400433 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700434 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400435 pui8 = pui8DATA(data, pDescr->offset+ib);
436 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400437 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400438 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300439 }
440 else if (no_of_bits <= 64)
441 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700442 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400443 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700444 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400445 pui8 = pui8DATA(data, pDescr->offset+ib);
446 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400447 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400448 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300449 }
450 else
451 {
452 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
453 }
454
455 remaining_bits_len -= no_of_bits;
456 assert(remaining_bits_len >= 0);
457 bit_offset += no_of_bits;
458 }
459 /* bitmap was successfully extracted or it was empty */
460
461 pDescr++;
462 break;
463 }
464
465 case CSN_TYPE:
466 {
467 gint16 Status;
468 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400469 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300470 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100471 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400472 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300473 if (Status >= 0)
474 {
475 remaining_bits_len = arT.remaining_bits_len;
476 bit_offset = arT.bit_offset;
477 pDescr++;
478 }
479 else
480 {
481 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
482 return Status;
483 }
484
485 break;
486 }
487
488 case CSN_CHOICE:
489 {
490 gint16 count = pDescr->i;
491 guint8 i = 0;
492 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
493
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700494 /* Make sure that the list of choice items is not empty */
495 if (!count)
496 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
497
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300498 while (count > 0)
499 {
500 guint8 no_of_bits = pChoice->bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700501 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300502 if (value == pChoice->value)
503 {
504 CSN_DESCR descr[2];
505 gint16 Status;
506 csnStream_t arT = *ar;
507
508 descr[0] = pChoice->descr;
509 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
510 descr[1].type = CSN_END;
511 pui8 = pui8DATA(data, pDescr->offset);
512 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400513 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100514 if (!pChoice->keep_bits) {
515 bit_offset += no_of_bits;
516 remaining_bits_len -= no_of_bits;
517 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300518
519 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100520 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300521
522 if (Status >= 0)
523 {
524 remaining_bits_len = arT.remaining_bits_len;
525 bit_offset = arT.bit_offset;
526 }
527 else
528 {
529 return Status;
530 }
531 break;
532 }
533
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700534 *readIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300535 count--;
536 pChoice++;
537 i++;
538 }
539
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700540 /* Neither of the choice items matched => unknown value */
541 if (!count)
542 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
543
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300544 pDescr++;
545 break;
546 }
547
548 case CSN_SERIALIZE:
549 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100550 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300551 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400552 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300553 gint16 Status = -1;
554
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700555 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300556
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400557 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400558 bit_offset += length_len;
559 remaining_bits_len -= length_len;
560
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100561 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100562 arT.direction = 1;
Vadim Yanitskiy8a87f912020-02-17 01:19:10 +0700563 LOGPC(DCSN1, LOGL_NOTICE, "offset = %d | ", (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100564 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300565
566 if (Status >= 0)
567 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100568 if (length > 0) {
569 remaining_bits_len -= length;
570 bit_offset += length;
571 } else {
572 remaining_bits_len = arT.remaining_bits_len;
573 bit_offset = arT.bit_offset;
574 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300575 pDescr++;
576 }
577 else
578 {
579 /* Has already been processed: */
580 return Status;
581 }
582
583 break;
584 }
585
586 case CSN_UNION_LH:
587 case CSN_UNION:
588 {
589 gint16 Bits;
590 guint8 index;
591 gint16 count = pDescr->i;
592 const CSN_DESCR* pDescrNext = pDescr;
593
594 pDescrNext += count + 1; /* now this is next after the union */
595 if ((count <= 0) || (count > 16))
596 {
597 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
598 }
599
600 /* Now get the bits to extract the index */
601 Bits = ixBitsTab[count];
602 index = 0;
603
604 while (Bits > 0)
605 {
606 index <<= 1;
607
608 if (CSN_UNION_LH == pDescr->type)
609 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700610 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300611 }
612 else
613 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700614 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300615 }
616 remaining_bits_len--;
617 bit_offset++;
618 Bits--;
619 }
620
621 /* Assign UnionType */
622 pui8 = pui8DATA(data, pDescr->offset);
623 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100624
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300625
626 /* script index to continue on, limited in case we do not have a power of 2 */
627 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400628 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300629
630 switch (pDescr->type)
631 { /* get the right element of the union based on computed index */
632
633 case CSN_BIT:
634 {
635 pui8 = pui8DATA(data, pDescr->offset);
636 *pui8 = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700637 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300638 {
639 *pui8 = 0x01;
640 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400641 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300642 remaining_bits_len -= 1;
643 bit_offset++;
644 pDescr++;
645 break;
646 }
647
648 case CSN_NULL:
649 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100650 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300651 pDescr++;
652 break;
653 }
654
655 case CSN_UINT:
656 {
657 guint8 no_of_bits = (guint8) pDescr->i;
658 if (remaining_bits_len >= no_of_bits)
659 {
660 remaining_bits_len -= no_of_bits;
661
662 if (no_of_bits <= 8)
663 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700664 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300665 pui8 = pui8DATA(data, pDescr->offset);
666 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400667 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300668 }
669 else if (no_of_bits <= 16)
670 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700671 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300672 pui16 = pui16DATA(data, pDescr->offset);
673 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400674 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300675 }
676 else if (no_of_bits <= 32)
677 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700678 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300679 pui32 = pui32DATA(data, pDescr->offset);
680 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400681 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300682 }
683 else
684 {
685 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
686 }
687 }
688 else
689 {
690 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
691 }
692
693 bit_offset += no_of_bits;
694 pDescr++;
695 break;
696 }
697
698 case CSN_UINT_OFFSET:
699 {
700 guint8 no_of_bits = (guint8) pDescr->i;
701
702 if (remaining_bits_len >= no_of_bits)
703 {
704 if (no_of_bits <= 8)
705 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700706 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300707 pui8 = pui8DATA(data, pDescr->offset);
708 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400709 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300710 }
711 else if (no_of_bits <= 16)
712 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700713 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300714 pui16 = pui16DATA(data, pDescr->offset);
715 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400716 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300717 }
718 else if (no_of_bits <= 32)
719 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700720 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300721 pui32 = pui32DATA(data, pDescr->offset);
722 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400723 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300724 }
725 else
726 {
727 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
728 }
729 }
730 else
731 {
732 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
733 }
734
735 bit_offset += no_of_bits;
736 pDescr++;
737 break;
738 }
739
740 case CSN_UINT_LH:
741 {
742 guint8 no_of_bits = (guint8) pDescr->i;
743
744 if (remaining_bits_len >= no_of_bits)
745 {
746 if (no_of_bits <= 8)
747 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100748 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300749 pui8 = pui8DATA(data, pDescr->offset);
750 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400751 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300752 }
753 else
754 { /* Maybe we should support more than 8 bits ? */
755 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
756 }
757 }
758 else
759 {
760 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
761 }
762
763 bit_offset += no_of_bits;
764 pDescr++;
765 break;
766 }
767
768 case CSN_UINT_ARRAY:
769 {
770 guint8 no_of_bits = (guint8) pDescr->i;
771 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
772
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100773 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300774 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
775 nCount = *pui16DATA(data, nCount);
776 }
777
778 if (remaining_bits_len >= no_of_bits)
779 {
780 remaining_bits_len -= (no_of_bits * nCount);
781 if (no_of_bits <= 8)
782 {
783 pui8 = pui8DATA(data, pDescr->offset);
784
785 while (nCount > 0)
786 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700787 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400788 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300789 pui8++;
790 bit_offset += no_of_bits;
791 nCount--;
792 }
793 }
794 else if (no_of_bits <= 16)
795 {
796 pui16 = pui16DATA(data, pDescr->offset);
797
798 while (nCount > 0)
799 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700800 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400801 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300802 pui16++;
803 bit_offset += no_of_bits;
804 nCount--;
805 }
806 }
807 else if (no_of_bits <= 32)
808 { /* not supported */
809 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
810 }
811 else
812 {
813 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
814 }
815 }
816 else
817 {
818 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
819 }
820
821 pDescr++;
822 break;
823 }
824
825 case CSN_VARIABLE_TARRAY_OFFSET:
826 case CSN_VARIABLE_TARRAY:
827 case CSN_TYPE_ARRAY:
828 {
829 gint16 Status;
830 csnStream_t arT = *ar;
831 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100832 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300833
834 pui8 = pui8DATA(data, pDescr->offset);
835
836 if (CSN_VARIABLE_TARRAY == pDescr->type)
837 { /* Count specified in field */
838 nCount = *pui8DATA(data, pDescr->i);
839 }
840 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
841 { /* Count specified in field */
842 nCount = *pui8DATA(data, pDescr->i);
843 nCount--; /* Offset 1 */
844 }
845
846 while (nCount--) /* Changed to handle length = 0. */
847 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400848 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300849 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100850 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300851 if (Status >= 0)
852 {
853 pui8 += nSize;
854 remaining_bits_len = arT.remaining_bits_len;
855 bit_offset = arT.bit_offset;
856 }
857 else
858 {
859 return Status;
860 }
861 }
862
863 pDescr++;
864 break;
865 }
866
867 case CSN_BITMAP:
868 { /* bitmap with given length. The result is left aligned! */
869 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
870
871 if (no_of_bits > 0)
872 {
873
874 if (no_of_bits <= 32)
875 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700876 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300877 pui32 = pui32DATA(data, pDescr->offset);
878 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300879 }
880 else if (no_of_bits <= 64)
881 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700882 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300883 pui64 = pui64DATA(data, pDescr->offset);
884 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200885 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300886 }
887 else
888 {
889 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
890 }
891
892 remaining_bits_len -= no_of_bits;
893 assert(remaining_bits_len >= 0);
894 bit_offset += no_of_bits;
895 }
896 /* bitmap was successfully extracted or it was empty */
897
898 pDescr++;
899 break;
900 }
901
902 case CSN_TYPE:
903 {
904 gint16 Status;
905 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400906 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300907 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100908 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400909 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300910 if (Status >= 0)
911 {
912 remaining_bits_len = arT.remaining_bits_len;
913 bit_offset = arT.bit_offset;
914 pDescr++;
915 }
916 else
917 { /* return error code Has already been processed: */
918 return Status;
919 }
920
921 break;
922 }
923
924 default:
925 { /* descriptions of union elements other than above are illegal */
926 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
927 }
928 }
929
930 pDescr = pDescrNext;
931 break;
932 }
933
934 case CSN_EXIST:
935 case CSN_EXIST_LH:
936 {
937 guint8 fExist;
938
939 pui8 = pui8DATA(data, pDescr->offset);
940
941 if (CSN_EXIST_LH == pDescr->type)
942 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100943 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300944 }
945 else
946 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700947 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300948 }
949
950 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400951 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300952 pDescr++;
953 remaining_bits_len -= 1;
954
955 if (!fExist)
956 {
957 ar->remaining_bits_len = remaining_bits_len;
958 ar->bit_offset = bit_offset;
959 return remaining_bits_len;
960 }
961
962 break;
963 }
964
965 case CSN_NEXT_EXIST:
966 {
967 guint8 fExist;
968
969 pui8 = pui8DATA(data, pDescr->offset);
970
971 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400972 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300973 { /* no more bits to decode is fine here - end of message detected and allowed */
974
975 /* Skip i entries + this entry */
976 pDescr += pDescr->i + 1;
977
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300978 /* Set the data member to "not exist" */
979 *pui8 = 0;
980 break;
981 }
982
983 /* the "regular" M_NEXT_EXIST description element */
984
985 fExist = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700986 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300987 {
988 fExist = 0x01;
989 }
990
991 *pui8 = fExist;
992 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400993 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300994 ++bit_offset;
995
996 if (fExist == 0)
997 { /* Skip 'i' entries */
998 pDescr += pDescr->i;
999 }
1000
1001 pDescr++;
1002 break;
1003 }
1004
1005 case CSN_NEXT_EXIST_LH:
1006 {
1007 guint8 fExist;
1008 pui8 = pui8DATA(data, pDescr->offset);
1009
1010 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1011 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1012 { /* no more bits to decode is fine here - end of message detected and allowed */
1013
1014 /* skip 'i' entries + this entry */
1015 pDescr += pDescr->i + 1;
1016
1017 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1018 if ( pDescr->type != CSN_END )
1019 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1020 remaining_bits_len--;
1021 }
1022
1023 /* set the data member to "not exist" */
1024 *pui8 = 0;
1025 break;
1026 }
1027
1028 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001029 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001030 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001031 *pui8++ = fExist;
1032 remaining_bits_len -= 1;
1033
1034 bit_offset++;
1035
1036 if (fExist == 0)
1037 { /* Skip 'i' entries */
1038 pDescr += pDescr->i;
1039 }
1040 pDescr++;
1041
1042 break;
1043 }
1044
1045 case CSN_VARIABLE_BITMAP_1:
1046 { /* Bitmap from here and to the end of message */
1047
1048 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1049
1050 /*no break -
1051 * with a length set we have a regular variable length bitmap so we continue */
1052 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001053 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001054 case CSN_VARIABLE_BITMAP:
1055 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1056 * <N: bit (5)> <bitmap: bit(N + offset)>
1057 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1058 * The result is right aligned!
1059 */
1060 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1061
1062 no_of_bits += pDescr->i; /* adjusted by offset */
1063
1064 if (no_of_bits > 0)
1065 {
1066 remaining_bits_len -= no_of_bits;
1067
1068 if (remaining_bits_len < 0)
1069 {
1070 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1071 }
1072
1073 { /* extract bits */
1074 guint8* pui8 = pui8DATA(data, pDescr->offset);
1075 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1076
1077 if (nB1 > 0)
1078 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001079 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001080 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001081 pui8++;
1082 no_of_bits -= nB1;
1083 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1084 }
1085
1086 /* remaining no_of_bits is a multiple of 8 or 0 */
1087 while (no_of_bits > 0)
1088 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001089 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001090 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001091 pui8++;
1092 no_of_bits -= 8;
1093 }
1094 }
1095 }
1096 pDescr++;
1097 break;
1098 }
1099
1100 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1101 { /* Bitmap from here and to the end of message */
1102
1103 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1104
1105 /* no break -
1106 * with a length set we have a regular left aligned variable length bitmap so we continue
1107 */
1108 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001109 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001110 case CSN_LEFT_ALIGNED_VAR_BMP:
1111 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1112 * <N: bit (5)> <bitmap: bit(N + offset)>
1113 * bit array with length (in bits) specified in parameter (pDescr->descr)
1114 */
1115 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1116
1117 no_of_bits += pDescr->i;/* size adjusted by offset */
1118
1119 if (no_of_bits > 0)
1120 {
1121 remaining_bits_len -= no_of_bits;
1122
1123 if (remaining_bits_len < 0)
1124 {
1125 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1126 }
1127
1128 { /* extract bits */
1129 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001130
Neels Hofmeyr02415262016-09-02 02:15:26 +02001131 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001132 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001133 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001134 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001135 pui8++;
1136 no_of_bits -= 8;
1137 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001138 if (no_of_bits > 0)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001139 {
1140 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001141 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001142 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001143 bit_offset += no_of_bits;
1144 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001145 }
1146 }
1147 }
1148
1149 /* bitmap was successfully extracted or it was empty */
1150 pDescr++;
1151 break;
1152 }
1153
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001154 case CSN_PADDING_BITS:
1155 { /* Padding from here and to the end of message */
1156 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1157 if (remaining_bits_len > 0)
1158 {
1159 while (remaining_bits_len > 0)
1160 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001161 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001162 if (bits_to_handle > 0)
1163 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001164 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001165 remaining_bits_len -= bits_to_handle;
1166 bit_offset += bits_to_handle;
1167 }
1168 else if (bits_to_handle == 0)
1169 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001170 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001171 remaining_bits_len -= 8;
1172 bit_offset += 8;
1173 }
1174 }
1175 }
1176 if (remaining_bits_len < 0)
1177 {
1178 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1179 }
1180
1181 /* Padding was successfully extracted or it was empty */
1182 pDescr++;
1183 break;
1184 }
1185
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001186 case CSN_VARIABLE_ARRAY:
1187 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1188 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1189 * Array with length specified in parameter:
1190 * <count: bit (x)>
1191 * <list: octet(count + offset)>
1192 */
1193 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1194
1195 count += pDescr->i; /* Adjusted by offset */
1196
1197 if (count > 0)
1198 {
1199 remaining_bits_len -= count * 8;
1200
1201 if (remaining_bits_len < 0)
1202 {
1203 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1204 }
1205
1206 pui8 = pui8DATA(data, pDescr->offset);
1207
1208 while (count > 0)
1209 {
1210 readIndex -= 8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001211 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001212 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001213 pui8++;
1214 bit_offset += 8;
1215 count--;
1216 }
1217 }
1218
1219 pDescr++;
1220 break;
1221 }
1222
1223 case CSN_RECURSIVE_ARRAY:
1224 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1225 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1226 * where <element> ::= bit(value)
1227 * <tag> ::= 0 | 1
1228 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1229 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1230 * REMARK: recursive way to specify an array but an iterative implementation!
1231 */
1232 gint16 no_of_bits = pDescr->i;
1233 guint8 ElementCount = 0;
1234
1235 pui8 = pui8DATA(data, pDescr->offset);
1236
Alexander Couzensccde5c92017-02-04 03:10:08 +01001237 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001238 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001239 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001240 bit_offset++;
1241 remaining_bits_len--;
1242
1243 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001244 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001245 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001246 pui8++;
1247 remaining_bits_len -= no_of_bits;
1248 ElementCount++;
1249
1250 if (remaining_bits_len < 0)
1251 {
1252 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1253 }
1254
1255 bit_offset += no_of_bits;
1256 }
1257
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001258 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001259 /* existNextElement() returned FALSE, 1 bit consumed */
1260 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001261 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001262
1263 /* Store the counted number of elements of the array */
1264 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1265
1266 pDescr++;
1267 break;
1268 }
1269
1270 case CSN_RECURSIVE_TARRAY:
1271 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1272 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1273 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1274 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001275 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001276 guint8 ElementCount = 0;
1277 pui8 = pui8DATA(data, pDescr->offset);
1278
Alexander Couzensccde5c92017-02-04 03:10:08 +01001279 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001280 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001281 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001282 /* existNextElement() returned TRUE, 1 bit consumed */
1283 bit_offset++;
1284 remaining_bits_len--;
1285 ElementCount++;
1286
1287 { /* unpack the following data structure */
1288 csnStream_t arT = *ar;
1289 gint16 Status;
1290 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001291 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001292
1293 if (Status >= 0)
1294 { /* successful completion */
1295 pui8 += nSizeElement; /* -> to next data element */
1296 remaining_bits_len = arT.remaining_bits_len;
1297 bit_offset = arT.bit_offset;
1298 }
1299 else
1300 { /* something went awry */
1301 return Status;
1302 }
1303 }
1304
1305 if (remaining_bits_len < 0)
1306 {
1307 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1308 }
1309 }
1310
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001311 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001312
1313 /* existNextElement() returned FALSE, 1 bit consumed */
1314 bit_offset++;
1315
1316 /* Store the counted number of elements of the array */
1317 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1318
1319 pDescr++;
1320 break;
1321 }
1322
1323 case CSN_RECURSIVE_TARRAY_2:
1324 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1325
1326 Tag = REVERSED_TAG;
1327
1328 /* NO break -
1329 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1330 */
1331 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001332 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001333 case CSN_RECURSIVE_TARRAY_1:
1334 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1335 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1336 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1337 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001338 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001339 guint8 ElementCount = 0;
1340 csnStream_t arT = *ar;
1341 gboolean EndOfList = FALSE;
1342 gint16 Status;
1343 pui8 = pui8DATA(data, pDescr->offset);
1344
1345 do
1346 { /* get data element */
1347 ElementCount++;
1348
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001349 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001350
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001351 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001352 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001353
1354 if (Status >= 0)
1355 { /* successful completion */
1356 pui8 += nSizeElement; /* -> to next */
1357 remaining_bits_len = arT.remaining_bits_len;
1358 bit_offset = arT.bit_offset;
1359 }
1360 else
1361 { /* something went awry */
1362 return Status;
1363 }
1364
1365 if (remaining_bits_len < 0)
1366 {
1367 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1368 }
1369
1370 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001371 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001372 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001373
1374 bit_offset++;
1375 remaining_bits_len--; /* 1 bit consumed (tag) */
1376 } while (!EndOfList);
1377
1378
1379 /* Store the count of the array */
1380 *pui8DATA(data, pDescr->i) = ElementCount;
1381 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1382 pDescr++;
1383 break;
1384 }
1385
1386 case CSN_FIXED:
1387 { /* Verify the fixed bits */
1388 guint8 no_of_bits = (guint8) pDescr->i;
1389 guint32 ui32;
1390
1391 if (no_of_bits <= 32)
1392 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001393 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001394 }
1395 else
1396 {
1397 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1398 }
1399 if (ui32 != (unsigned)(gint32)pDescr->offset)
1400 {
1401 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1402 }
1403
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001404 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001405 remaining_bits_len -= no_of_bits;
1406 bit_offset += no_of_bits;
1407 pDescr++;
1408 break;
1409 }
1410
1411 case CSN_CALLBACK:
1412 {
1413 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1414 break;
1415 }
1416
1417 case CSN_TRAP_ERROR:
1418 {
1419 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1420 }
1421
1422 case CSN_END:
1423 {
1424 ar->remaining_bits_len = remaining_bits_len;
1425 ar->bit_offset = bit_offset;
1426 return remaining_bits_len;
1427 }
1428
1429 default:
1430 {
1431 assert(0);
1432 }
1433
1434
1435 }
1436
1437 } while (remaining_bits_len >= 0);
1438
1439 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1440}
1441
1442
1443
1444
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001445gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001446{
1447 gint remaining_bits_len = ar->remaining_bits_len;
1448 gint bit_offset = ar->bit_offset;
1449 guint8* pui8;
1450 guint16* pui16;
1451 guint32* pui32;
1452 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001453 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001454
1455 guint8 Tag = STANDARD_TAG;
1456
1457 if (remaining_bits_len <= 0)
1458 {
1459 return 0;
1460 }
1461
1462 do
1463 {
1464 switch (pDescr->type)
1465 {
1466 case CSN_BIT:
1467 {
1468 if (remaining_bits_len > 0)
1469 {
1470 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001471 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001472 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001473 /* end add the bit value to protocol tree */
1474 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001475 else if(pDescr->may_be_null)
1476 {
1477 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1478 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001479 else
1480 {
1481 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1482 }
1483
1484 pDescr++;
1485 remaining_bits_len--;
1486 bit_offset++;
1487 break;
1488 }
1489
1490 case CSN_NULL:
1491 { /* Empty member! */
1492 pDescr++;
1493 break;
1494 }
1495
1496 case CSN_UINT:
1497 {
1498 guint8 no_of_bits = (guint8) pDescr->i;
1499
1500 if (remaining_bits_len >= no_of_bits)
1501 {
1502 if (no_of_bits <= 8)
1503 {
1504 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001505 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001506 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001507 }
1508 else if (no_of_bits <= 16)
1509 {
1510 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001511 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001512 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001513 }
1514 else if (no_of_bits <= 32)
1515 {
1516 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001517 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001518 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001519 }
1520 else
1521 {
1522 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1523 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001524
1525 remaining_bits_len -= no_of_bits;
1526 bit_offset += no_of_bits;
1527 }
1528 else if(pDescr->may_be_null)
1529 {
1530 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001531 }
1532 else
1533 {
1534 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1535 }
1536
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001537 pDescr++;
1538 break;
1539 }
1540
1541 case CSN_UINT_OFFSET:
1542 {
1543 guint8 no_of_bits = (guint8) pDescr->i;
1544
1545 if (remaining_bits_len >= no_of_bits)
1546 {
1547 if (no_of_bits <= 8)
1548 {
1549 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001550 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001551 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001552 }
1553 else if (no_of_bits <= 16)
1554 {
1555 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001556 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001557 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001558 }
1559 else if (no_of_bits <= 32)
1560 {
1561 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001562 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001563 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001564 }
1565 else
1566 {
1567 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1568 }
1569 }
1570 else
1571 {
1572 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1573 }
1574
1575 remaining_bits_len -= no_of_bits;
1576 bit_offset += no_of_bits;
1577 pDescr++;
1578 break;
1579 }
1580
1581 case CSN_UINT_LH:
1582 {
1583 guint8 no_of_bits = (guint8) pDescr->i;
1584
1585 if (remaining_bits_len >= no_of_bits)
1586 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001587 if (no_of_bits <= 8)
1588 {
1589 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001590 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001591 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001592 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001593 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001594 *writeIndex -= no_of_bits;
1595 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001596 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001597
1598 }
1599 else
1600 {/* Maybe we should support more than 8 bits ? */
1601 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1602 }
1603 }
1604 else
1605 {
1606 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1607 }
1608
1609 remaining_bits_len -= no_of_bits;
1610 bit_offset += no_of_bits;
1611 pDescr++;
1612 break;
1613 }
1614
1615 case CSN_UINT_ARRAY:
1616 {
1617 guint8 no_of_bits = (guint8) pDescr->i;
1618 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1619
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001620 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001621 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1622 nCount = *pui16DATA(data, nCount);
1623 }
1624
1625 if (remaining_bits_len >= no_of_bits)
1626 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001627 if (no_of_bits <= 8)
1628 {
1629 pui8 = pui8DATA(data, pDescr->offset);
1630 do
1631 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001632 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001633 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001634 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001635 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001636 bit_offset += no_of_bits;
1637 } while (--nCount > 0);
1638 }
1639 else if (no_of_bits <= 16)
1640 {
1641 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1642 }
1643 else if (no_of_bits <= 32)
1644 {
1645 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1646 }
1647 else
1648 {
1649 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1650 }
1651 }
1652 else
1653 {
1654 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1655 }
1656 pDescr++;
1657 break;
1658 }
1659
1660 case CSN_VARIABLE_TARRAY_OFFSET:
1661 case CSN_VARIABLE_TARRAY:
1662 case CSN_TYPE_ARRAY:
1663 {
1664 gint16 Status;
1665 csnStream_t arT = *ar;
1666 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001667 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001668
1669 pui8 = pui8DATA(data, pDescr->offset);
1670 if (pDescr->type == CSN_VARIABLE_TARRAY)
1671 { /* Count specified in field */
1672 nCount = *pui8DATA(data, pDescr->i);
1673 }
1674 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1675 { /* Count specified in field */
1676 nCount = *pui8DATA(data, pDescr->i);
1677 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1678 }
1679
1680 while (nCount > 0)
1681 { /* resulting array of length 0 is possible
1682 * but no bits shall be read from bitstream
1683 */
1684
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001685 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001686 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1687 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1688 if (Status >= 0)
1689 {
1690 pui8 += nSize;
1691 remaining_bits_len = arT.remaining_bits_len;
1692 bit_offset = arT.bit_offset;
1693
1694 }
1695 else
1696 {
1697 return Status;
1698 }
1699 nCount--;
1700 }
1701
1702 pDescr++;
1703 break;
1704 }
1705
1706 case CSN_BITMAP:
1707 { /* bitmap with given length. The result is left aligned! */
1708 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1709
1710 if (no_of_bits > 0)
1711 {
1712
1713 if (no_of_bits <= 32)
1714 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001715 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001716 {
1717 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001718 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001719 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001720 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001721 }
1722 else if (no_of_bits <= 64)
1723 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001724 for(ib = 0; ib < 8; 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
1732 {
1733 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1734 }
1735
1736 remaining_bits_len -= no_of_bits;
1737 assert(remaining_bits_len >= 0);
1738 bit_offset += no_of_bits;
1739 }
1740 /* bitmap was successfully extracted or it was empty */
1741
1742 pDescr++;
1743 break;
1744 }
1745
1746 case CSN_TYPE:
1747 {
1748 gint16 Status;
1749 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001750 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001751 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1752 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001753 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001754 if (Status >= 0)
1755 {
1756
1757 remaining_bits_len = arT.remaining_bits_len;
1758 bit_offset = arT.bit_offset;
1759 pDescr++;
1760 }
1761 else
1762 {
1763 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1764 return Status;
1765 }
1766
1767 break;
1768 }
1769
1770 case CSN_CHOICE:
1771 {
1772 //gint16 count = pDescr->i;
1773 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001774 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001775
1776 pui8 = pui8DATA(data, pDescr->offset);
1777 i = *pui8;
1778 pChoice += i;
1779 guint8 no_of_bits = pChoice->bits;
1780 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001781 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001782 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001783
1784 CSN_DESCR descr[2];
1785 gint16 Status;
1786 csnStream_t arT = *ar;
1787
1788 descr[0] = pChoice->descr;
1789 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1790 descr[1].type = CSN_END;
1791 bit_offset += no_of_bits;
1792 remaining_bits_len -= no_of_bits;
1793
1794 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1795 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1796
1797 if (Status >= 0)
1798 {
1799 remaining_bits_len = arT.remaining_bits_len;
1800 bit_offset = arT.bit_offset;
1801 }
1802 else
1803 {
1804 return Status;
1805 }
1806
1807 pDescr++;
1808 break;
1809 }
1810
1811 case CSN_SERIALIZE:
1812 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001813 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001814 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001815 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001816 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001817 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001818
1819 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001820 lengthIndex = *writeIndex;
1821 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001822 bit_offset += length_len;
1823 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001824 arT.direction = 0;
1825 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1826 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001827
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001828 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
1829 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001830
1831 if (Status >= 0)
1832 {
1833 remaining_bits_len = arT.remaining_bits_len;
1834 bit_offset = arT.bit_offset;
1835 pDescr++;
1836 }
1837 else
1838 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001839 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001840 return Status;
1841 }
1842
1843 break;
1844 }
1845
1846 case CSN_UNION_LH:
1847 case CSN_UNION:
1848 {
1849 gint16 Bits;
1850 guint8 index;
1851 gint16 count = pDescr->i;
1852 const CSN_DESCR* pDescrNext = pDescr;
1853
1854 pDescrNext += count + 1; /* now this is next after the union */
1855 if ((count <= 0) || (count > 16))
1856 {
1857 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1858 }
1859
1860 /* Now get the bits to extract the index */
1861 Bits = ixBitsTab[count];
1862 index = 0;
1863
1864 /* Assign UnionType */
1865 pui8 = pui8DATA(data, pDescr->offset);
1866 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001867 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001868
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001869 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001870 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001871
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001872 while (Bits > 0)
1873 {
1874 index <<= 1;
1875
1876 if (CSN_UNION_LH == pDescr->type)
1877 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001878 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001879 }
1880 else
1881 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001882 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001883 }
1884
1885 remaining_bits_len--;
1886 bit_offset++;
1887 Bits--;
1888 }
1889
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001890 *writeIndex -= Bits;
1891 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001892
1893
1894 /* script index to continue on, limited in case we do not have a power of 2 */
1895 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001896 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001897
1898 switch (pDescr->type)
1899 { /* get the right element of the union based on computed index */
1900
1901 case CSN_BIT:
1902 {
1903 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001904 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001905 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001906 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001907 bit_offset++;
1908 pDescr++;
1909 break;
1910 }
1911
1912 case CSN_NULL:
1913 { /* Empty member! */
1914 pDescr++;
1915 break;
1916 }
1917
1918 case CSN_UINT:
1919 {
1920 guint8 no_of_bits = (guint8) pDescr->i;
1921 if (remaining_bits_len >= no_of_bits)
1922 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001923 if (no_of_bits <= 8)
1924 {
1925 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001926 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001927 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001928 }
1929 else if (no_of_bits <= 16)
1930 {
1931 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001932 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001933 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001934 }
1935 else if (no_of_bits <= 32)
1936 {
1937 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001938 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001939 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001940 }
1941 else
1942 {
1943 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1944 }
1945 }
1946 else
1947 {
1948 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1949 }
1950
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001951 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001952 bit_offset += no_of_bits;
1953 pDescr++;
1954 break;
1955 }
1956
1957 case CSN_UINT_OFFSET:
1958 {
1959 guint8 no_of_bits = (guint8) pDescr->i;
1960
1961 if (remaining_bits_len >= no_of_bits)
1962 {
1963 if (no_of_bits <= 8)
1964 {
1965 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001966 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001967 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001968 }
1969 else if (no_of_bits <= 16)
1970 {
1971 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001972 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001973 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001974 }
1975 else if (no_of_bits <= 32)
1976 {
1977 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001978 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001979 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001980 }
1981 else
1982 {
1983 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1984 }
1985 }
1986 else
1987 {
1988 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1989 }
1990
1991 remaining_bits_len -= no_of_bits;
1992 bit_offset += no_of_bits;
1993 pDescr++;
1994 break;
1995 }
1996
1997 case CSN_UINT_LH:
1998 {
1999 guint8 no_of_bits = (guint8) pDescr->i;
2000
2001 if (remaining_bits_len >= no_of_bits)
2002 {
2003 remaining_bits_len -= no_of_bits;
2004 if (no_of_bits <= 8)
2005 {
2006 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002007 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002008 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002009 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002010 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002011 *writeIndex -= no_of_bits;
2012 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002013 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002014
2015 }
2016 else
2017 {/* Maybe we should support more than 8 bits ? */
2018 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2019 }
2020 }
2021 else
2022 {
2023 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2024 }
2025
2026 remaining_bits_len -= no_of_bits;
2027 bit_offset += no_of_bits;
2028 pDescr++;
2029 break;
2030 }
2031
2032 case CSN_UINT_ARRAY:
2033 {
2034 guint8 no_of_bits = (guint8) pDescr->i;
2035 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2036
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002037 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002038 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2039 nCount = *pui16DATA(data, nCount);
2040 }
2041
2042 if (remaining_bits_len >= no_of_bits)
2043 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002044 if (no_of_bits <= 8)
2045 {
2046 pui8 = pui8DATA(data, pDescr->offset);
2047 do
2048 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002049 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002050 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002051 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002052 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002053 bit_offset += no_of_bits;
2054 } while (--nCount > 0);
2055 }
2056 else if (no_of_bits <= 16)
2057 {
2058 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2059 }
2060 else if (no_of_bits <= 32)
2061 {
2062 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2063 }
2064 else
2065 {
2066 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2067 }
2068 }
2069 else
2070 {
2071 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2072 }
2073 pDescr++;
2074 break;
2075 }
2076
2077 case CSN_VARIABLE_TARRAY_OFFSET:
2078 case CSN_VARIABLE_TARRAY:
2079 case CSN_TYPE_ARRAY:
2080 {
2081 gint16 Status;
2082 csnStream_t arT = *ar;
2083 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002084 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002085
2086 pui8 = pui8DATA(data, pDescr->offset);
2087 if (pDescr->type == CSN_VARIABLE_TARRAY)
2088 { /* Count specified in field */
2089 nCount = *pui8DATA(data, pDescr->i);
2090 }
2091 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2092 { /* Count specified in field */
2093 nCount = *pui8DATA(data, pDescr->i);
2094 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2095 }
2096
2097 while (nCount > 0)
2098 { /* resulting array of length 0 is possible
2099 * but no bits shall be read from bitstream
2100 */
2101
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002102 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002103 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2104 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2105 if (Status >= 0)
2106 {
2107 pui8 += nSize;
2108 remaining_bits_len = arT.remaining_bits_len;
2109 bit_offset = arT.bit_offset;
2110 }
2111 else
2112 {
2113 return Status;
2114 }
2115 nCount--;
2116 }
2117
2118 pDescr++;
2119 break;
2120 }
2121
2122 case CSN_BITMAP:
2123 { /* bitmap with given length. The result is left aligned! */
2124 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2125
2126 if (no_of_bits > 0)
2127 {
2128
2129 if (no_of_bits <= 32)
2130 {
2131 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002132 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002133 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002134 }
2135 else if (no_of_bits <= 64)
2136 {
2137 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002138 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002139 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002140 }
2141 else
2142 {
2143 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2144 }
2145
2146 remaining_bits_len -= no_of_bits;
2147 assert(remaining_bits_len >= 0);
2148 bit_offset += no_of_bits;
2149 }
2150 /* bitmap was successfully extracted or it was empty */
2151
2152 pDescr++;
2153 break;
2154 }
2155
2156 case CSN_TYPE:
2157 {
2158 gint16 Status;
2159 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002160 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002161 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2162 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002163 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002164 if (Status >= 0)
2165 {
2166 remaining_bits_len = arT.remaining_bits_len;
2167 bit_offset = arT.bit_offset;
2168 pDescr++;
2169 }
2170 else
2171 {
2172 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2173 return Status;
2174 }
2175
2176 break;
2177 }
2178
2179 default:
2180 { /* descriptions of union elements other than above are illegal */
2181 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2182 }
2183 }
2184
2185 pDescr = pDescrNext;
2186 break;
2187 }
2188
2189 case CSN_EXIST:
2190 case CSN_EXIST_LH:
2191 {
2192 guint8 fExist;
2193 unsigned exist = 0;
2194 pui8 = pui8DATA(data, pDescr->offset);
2195 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002196 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002197 writeIndex--;
2198 if (CSN_EXIST_LH == pDescr->type)
2199 {
2200 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2201 }
2202 else
2203 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002204 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002205 }
2206 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002207 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002208 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002209 remaining_bits_len--;
2210 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002211 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002212
2213 if (!exist)
2214 {
2215 ar->remaining_bits_len = remaining_bits_len;
2216 ar->bit_offset = bit_offset;
2217 return remaining_bits_len;
2218 }
2219 break;
2220 }
2221
2222 case CSN_NEXT_EXIST:
2223 {
2224 guint8 fExist;
2225
2226 pui8 = pui8DATA(data, pDescr->offset);
2227
2228 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002229 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002230 { /* no more bits to decode is fine here - end of message detected and allowed */
2231
2232 /* Skip i entries + this entry */
2233 pDescr += pDescr->i + 1;
2234
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002235 break;
2236 }
2237
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002238 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002239 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002240 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002241
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002242 remaining_bits_len--;
2243 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002244
2245 if (fExist == 0)
2246 { /* Skip 'i' entries */
2247 pDescr += pDescr->i;
2248 }
2249
2250 pDescr++;
2251 break;
2252 }
2253
2254 case CSN_NEXT_EXIST_LH:
2255 {
2256 guint8 fExist;
2257 pui8 = pui8DATA(data, pDescr->offset);
2258
2259 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2260 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2261 { /* no more bits to decode is fine here - end of message detected and allowed */
2262
2263 /* skip 'i' entries + this entry */
2264 pDescr += pDescr->i + 1;
2265
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002266 /* set the data member to "not exist" */
2267 //*pui8 = 0;
2268 break;
2269 }
2270
2271 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002272 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002273 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002274 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002275 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002276 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002277 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002278
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002279 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002280 bit_offset++;
2281
2282 if (fExist == 0)
2283 { /* Skip 'i' entries */
2284 pDescr += pDescr->i;
2285 }
2286 pDescr++;
2287
2288 break;
2289 }
2290
2291 case CSN_VARIABLE_BITMAP_1:
2292 { /* Bitmap from here and to the end of message */
2293
2294 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2295
2296 /*no break -
2297 * with a length set we have a regular variable length bitmap so we continue */
2298 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002299 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002300 case CSN_VARIABLE_BITMAP:
2301 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2302 * <N: bit (5)> <bitmap: bit(N + offset)>
2303 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2304 * The result is right aligned!
2305 */
2306 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2307
2308 no_of_bits += pDescr->i; /* adjusted by offset */
2309
2310 if (no_of_bits > 0)
2311 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002312
2313 if (remaining_bits_len < 0)
2314 {
2315 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2316 }
2317
2318 { /* extract bits */
2319 guint8* pui8 = pui8DATA(data, pDescr->offset);
2320 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2321
2322 if (nB1 > 0)
2323 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002324 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002325 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002326 pui8++;
2327 no_of_bits -= nB1;
2328 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002329 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002330 }
2331
2332 /* remaining no_of_bits is a multiple of 8 or 0 */
2333 while (no_of_bits > 0)
2334 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002335 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002336 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002337 pui8++;
2338 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002339 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002340 }
2341 }
2342 }
2343 pDescr++;
2344 break;
2345 }
2346
2347 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2348 { /* Bitmap from here and to the end of message */
2349
2350 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2351
2352 /* no break -
2353 * with a length set we have a regular left aligned variable length bitmap so we continue
2354 */
2355 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002356 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002357 case CSN_LEFT_ALIGNED_VAR_BMP:
2358 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2359 * <N: bit (5)> <bitmap: bit(N + offset)>
2360 * bit array with length (in bits) specified in parameter (pDescr->descr)
2361 */
2362
2363 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2364
2365 no_of_bits += pDescr->i;/* size adjusted by offset */
2366
2367 if (no_of_bits > 0)
2368 {
2369 remaining_bits_len -= no_of_bits;
2370
2371 if (remaining_bits_len < 0)
2372 {
2373 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2374 }
2375
2376 { /* extract bits */
2377 guint8* pui8 = pui8DATA(data, pDescr->offset);
2378 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2379
2380 while (no_of_bits > 0)
2381 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002382 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002383 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002384 pui8++;
2385 no_of_bits -= 8;
2386 }
2387 if (nB1 > 0)
2388 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002389 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002390 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002391 pui8++;
2392 no_of_bits -= nB1;
2393 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2394 }
2395 }
2396
2397 }
2398
2399 /* bitmap was successfully extracted or it was empty */
2400 pDescr++;
2401 break;
2402 }
2403
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002404 case CSN_PADDING_BITS:
2405 { /* Padding from here and to the end of message */
2406 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2407 guint8 filler = 0x2b;
2408 if (remaining_bits_len > 0)
2409 {
2410 while (remaining_bits_len > 0)
2411 {
2412 guint8 bits_to_handle = remaining_bits_len%8;
2413 if (bits_to_handle > 0)
2414 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302415 /* section 11 of 44.060
2416 * The padding bits may be the 'null' string. Otherwise, the
2417 * padding bits starts with bit '0', followed by 'spare padding'
2418 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2419 */
2420 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002421 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002422 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2423 remaining_bits_len -= bits_to_handle;
2424 bit_offset += bits_to_handle;
2425 }
2426 else if (bits_to_handle == 0)
2427 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002428 bitvec_write_field(vector, writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002429 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2430 remaining_bits_len -= 8;
2431 bit_offset += 8;
2432 }
2433 }
2434 }
2435 if (remaining_bits_len < 0)
2436 {
2437 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2438 }
2439
2440 /* Padding was successfully extracted or it was empty */
2441 pDescr++;
2442 break;
2443 }
2444
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002445 case CSN_VARIABLE_ARRAY:
2446 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2447 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2448 * Array with length specified in parameter:
2449 * <count: bit (x)>
2450 * <list: octet(count + offset)>
2451 */
2452 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2453
2454 count += pDescr->i; /* Adjusted by offset */
2455
2456 if (count > 0)
2457 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002458 if (remaining_bits_len < 0)
2459 {
2460 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2461 }
2462
2463 pui8 = pui8DATA(data, pDescr->offset);
2464
2465 while (count > 0)
2466 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002467 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002468 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002469 pui8++;
2470 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002471 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002472 count--;
2473 }
2474 }
2475
2476 pDescr++;
2477 break;
2478 }
2479
2480 case CSN_RECURSIVE_ARRAY:
2481 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2482 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2483 * where <element> ::= bit(value)
2484 * <tag> ::= 0 | 1
2485 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2486 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2487 * REMARK: recursive way to specify an array but an iterative implementation!
2488 */
2489 gint16 no_of_bits = pDescr->i;
2490 guint8 ElementCount = 0;
2491 pui8 = pui8DATA(data, pDescr->offset);
2492 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2493 while (ElementCount > 0)
2494 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002495 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002496 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002497 bit_offset++;
2498 remaining_bits_len--;
2499
2500 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002501 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002502 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002503 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002504 ElementCount--;
2505
2506 if (remaining_bits_len < 0)
2507 {
2508 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2509 }
2510
2511 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002512 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002513 }
2514
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002515 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002516 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002517 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302518 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002519
2520 pDescr++;
2521 break;
2522 }
2523
2524 case CSN_RECURSIVE_TARRAY:
2525 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2526 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2527 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2528 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002529 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002530 guint8 ElementCount = 0;
2531 pui8 = pui8DATA(data, pDescr->offset);
2532 /* Store the counted number of elements of the array */
2533 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2534
2535 while (ElementCount > 0)
2536 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002537 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002538 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002539 bit_offset++;
2540
2541 remaining_bits_len--;
2542 ElementCount--;
2543
2544 { /* unpack the following data structure */
2545 csnStream_t arT = *ar;
2546 gint16 Status;
2547 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002548 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002549
2550 if (Status >= 0)
2551 { /* successful completion */
2552 pui8 += nSizeElement; /* -> to next data element */
2553 remaining_bits_len = arT.remaining_bits_len;
2554 bit_offset = arT.bit_offset;
2555 }
2556 else
2557 { /* something went awry */
2558 return Status;
2559 }
2560 }
2561
2562 if (remaining_bits_len < 0)
2563 {
2564 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2565 }
2566 }
2567
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002568 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002569 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002570 bit_offset++;
2571
2572 pDescr++;
2573 break;
2574 }
2575
2576 case CSN_RECURSIVE_TARRAY_2:
2577 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2578
2579 Tag = REVERSED_TAG;
2580
2581 /* NO break -
2582 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2583 */
2584 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002585 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002586 case CSN_RECURSIVE_TARRAY_1:
2587 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2588 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2589 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2590 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002591 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002592 guint8 ElementCount = 0;
2593 guint8 ElementNum = 0;
2594 csnStream_t arT = *ar;
2595 gint16 Status;
2596
2597 pui8 = pui8DATA(data, pDescr->offset);
2598 /* Store the count of the array */
2599 ElementCount = *pui8DATA(data, pDescr->i);
2600 ElementNum = ElementCount;
2601
2602 while (ElementCount > 0)
2603 { /* get data element */
2604 if (ElementCount != ElementNum)
2605 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002606 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002607 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002608 bit_offset++;
2609 remaining_bits_len--;
2610 }
2611 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002612 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002613 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002614 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002615 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002616 if (Status >= 0)
2617 { /* successful completion */
2618 pui8 += nSizeElement; /* -> to next */
2619 remaining_bits_len = arT.remaining_bits_len;
2620 bit_offset = arT.bit_offset;
2621 }
2622 else
2623 { /* something went awry */
2624 return Status;
2625 }
2626
2627 if (remaining_bits_len < 0)
2628 {
2629 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2630 }
2631
2632 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002633 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002634 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002635 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002636 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2637 pDescr++;
2638 break;
2639 }
2640
2641 case CSN_FIXED:
2642 { /* Verify the fixed bits */
2643 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002644 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002645 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002646 remaining_bits_len -= no_of_bits;
2647 bit_offset += no_of_bits;
2648 pDescr++;
2649 break;
2650 }
2651
2652 case CSN_CALLBACK:
2653 {
2654 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2655 break;
2656 }
2657
2658 case CSN_TRAP_ERROR:
2659 {
2660 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2661 }
2662
2663 case CSN_END:
2664 {
2665 ar->remaining_bits_len = remaining_bits_len;
2666 ar->bit_offset = bit_offset;
2667 return remaining_bits_len;
2668 }
2669
2670 default:
2671 {
2672 assert(0);
2673 }
2674
2675 }
2676
2677 } while (remaining_bits_len >= 0);
2678
2679 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2680}