blob: 2f0532723cab813254fefbdae7f0961a3ab4ed22 [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 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300309 if (no_of_bits <= 8)
310 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100311 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300312 pui8 = pui8DATA(data, pDescr->offset);
313 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300315 }
316 else
317 {/* Maybe we should support more than 8 bits ? */
318 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
319 }
320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
324 }
325
326 remaining_bits_len -= no_of_bits;
327 bit_offset += no_of_bits;
328 pDescr++;
329 break;
330 }
331
332 case CSN_UINT_ARRAY:
333 {
334 guint8 no_of_bits = (guint8) pDescr->i;
335 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
336
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100337 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300338 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
339 nCount = *pui16DATA(data, nCount);
340 }
341
342 if (remaining_bits_len >= no_of_bits)
343 {
344 remaining_bits_len -= (no_of_bits*nCount);
345 if (no_of_bits <= 8)
346 {
347 pui8 = pui8DATA(data, pDescr->offset);
348 do
349 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700350 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400351 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300352 pui8++;
353 bit_offset += no_of_bits;
354 } while (--nCount > 0);
355 }
356 else if (no_of_bits <= 16)
357 {
358 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
359 }
360 else if (no_of_bits <= 32)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else
365 {
366 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
367 }
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
372 }
373 pDescr++;
374 break;
375 }
376
377 case CSN_VARIABLE_TARRAY_OFFSET:
378 case CSN_VARIABLE_TARRAY:
379 case CSN_TYPE_ARRAY:
380 {
381 gint16 Status;
382 csnStream_t arT = *ar;
383 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100384 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300385
386 pui8 = pui8DATA(data, pDescr->offset);
387 if (pDescr->type == CSN_VARIABLE_TARRAY)
388 { /* Count specified in field */
389 nCount = *pui8DATA(data, pDescr->i);
390 }
391 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
395 }
396
397 while (nCount > 0)
398 { /* resulting array of length 0 is possible
399 * but no bits shall be read from bitstream
400 */
401
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400402 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300403 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100404 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300405 if (Status >= 0)
406 {
407 pui8 += nSize;
408 remaining_bits_len = arT.remaining_bits_len;
409 bit_offset = arT.bit_offset;
410 }
411 else
412 {
413 return Status;
414 }
415 nCount--;
416 }
417
418 pDescr++;
419 break;
420 }
421
422 case CSN_BITMAP:
423 { /* bitmap with given length. The result is left aligned! */
424 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
425
426 if (no_of_bits > 0)
427 {
428
429 if (no_of_bits <= 32)
430 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700431 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400432 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700433 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400434 pui8 = pui8DATA(data, pDescr->offset+ib);
435 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400436 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 }
439 else if (no_of_bits <= 64)
440 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700441 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400442 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700443 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400444 pui8 = pui8DATA(data, pDescr->offset+ib);
445 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400446 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300448 }
449 else
450 {
451 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
452 }
453
454 remaining_bits_len -= no_of_bits;
455 assert(remaining_bits_len >= 0);
456 bit_offset += no_of_bits;
457 }
458 /* bitmap was successfully extracted or it was empty */
459
460 pDescr++;
461 break;
462 }
463
464 case CSN_TYPE:
465 {
466 gint16 Status;
467 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400468 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300469 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100470 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400471 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300472 if (Status >= 0)
473 {
474 remaining_bits_len = arT.remaining_bits_len;
475 bit_offset = arT.bit_offset;
476 pDescr++;
477 }
478 else
479 {
480 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
481 return Status;
482 }
483
484 break;
485 }
486
487 case CSN_CHOICE:
488 {
489 gint16 count = pDescr->i;
490 guint8 i = 0;
491 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
492
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700493 /* Make sure that the list of choice items is not empty */
494 if (!count)
495 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
496
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300497 while (count > 0)
498 {
499 guint8 no_of_bits = pChoice->bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700500 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300501 if (value == pChoice->value)
502 {
503 CSN_DESCR descr[2];
504 gint16 Status;
505 csnStream_t arT = *ar;
506
507 descr[0] = pChoice->descr;
508 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
509 descr[1].type = CSN_END;
510 pui8 = pui8DATA(data, pDescr->offset);
511 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400512 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100513 if (!pChoice->keep_bits) {
514 bit_offset += no_of_bits;
515 remaining_bits_len -= no_of_bits;
516 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300517
518 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100519 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300520
521 if (Status >= 0)
522 {
523 remaining_bits_len = arT.remaining_bits_len;
524 bit_offset = arT.bit_offset;
525 }
526 else
527 {
528 return Status;
529 }
530 break;
531 }
532
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700533 *readIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300534 count--;
535 pChoice++;
536 i++;
537 }
538
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700539 /* Neither of the choice items matched => unknown value */
540 if (!count)
541 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
542
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300543 pDescr++;
544 break;
545 }
546
547 case CSN_SERIALIZE:
548 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100549 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300550 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400551 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300552 gint16 Status = -1;
553
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700554 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300555
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400556 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400557 bit_offset += length_len;
558 remaining_bits_len -= length_len;
559
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100560 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100561 arT.direction = 1;
Vadim Yanitskiy8a87f912020-02-17 01:19:10 +0700562 LOGPC(DCSN1, LOGL_NOTICE, "offset = %d | ", (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100563 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300564
565 if (Status >= 0)
566 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100567 if (length > 0) {
568 remaining_bits_len -= length;
569 bit_offset += length;
570 } else {
571 remaining_bits_len = arT.remaining_bits_len;
572 bit_offset = arT.bit_offset;
573 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300574 pDescr++;
575 }
576 else
577 {
578 /* Has already been processed: */
579 return Status;
580 }
581
582 break;
583 }
584
585 case CSN_UNION_LH:
586 case CSN_UNION:
587 {
588 gint16 Bits;
589 guint8 index;
590 gint16 count = pDescr->i;
591 const CSN_DESCR* pDescrNext = pDescr;
592
593 pDescrNext += count + 1; /* now this is next after the union */
594 if ((count <= 0) || (count > 16))
595 {
596 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
597 }
598
599 /* Now get the bits to extract the index */
600 Bits = ixBitsTab[count];
601 index = 0;
602
603 while (Bits > 0)
604 {
605 index <<= 1;
606
607 if (CSN_UNION_LH == pDescr->type)
608 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700609 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300610 }
611 else
612 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700613 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300614 }
615 remaining_bits_len--;
616 bit_offset++;
617 Bits--;
618 }
619
620 /* Assign UnionType */
621 pui8 = pui8DATA(data, pDescr->offset);
622 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100623
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300624
625 /* script index to continue on, limited in case we do not have a power of 2 */
626 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400627 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300628
629 switch (pDescr->type)
630 { /* get the right element of the union based on computed index */
631
632 case CSN_BIT:
633 {
634 pui8 = pui8DATA(data, pDescr->offset);
635 *pui8 = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700636 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300637 {
638 *pui8 = 0x01;
639 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400640 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300641 remaining_bits_len -= 1;
642 bit_offset++;
643 pDescr++;
644 break;
645 }
646
647 case CSN_NULL:
648 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100649 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300650 pDescr++;
651 break;
652 }
653
654 case CSN_UINT:
655 {
656 guint8 no_of_bits = (guint8) pDescr->i;
657 if (remaining_bits_len >= no_of_bits)
658 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300659 if (no_of_bits <= 8)
660 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700661 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300662 pui8 = pui8DATA(data, pDescr->offset);
663 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400664 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300665 }
666 else if (no_of_bits <= 16)
667 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700668 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300669 pui16 = pui16DATA(data, pDescr->offset);
670 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400671 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300672 }
673 else if (no_of_bits <= 32)
674 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700675 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300676 pui32 = pui32DATA(data, pDescr->offset);
677 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400678 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300679 }
680 else
681 {
682 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
683 }
684 }
685 else
686 {
687 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
688 }
689
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700690 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300691 bit_offset += no_of_bits;
692 pDescr++;
693 break;
694 }
695
696 case CSN_UINT_OFFSET:
697 {
698 guint8 no_of_bits = (guint8) pDescr->i;
699
700 if (remaining_bits_len >= no_of_bits)
701 {
702 if (no_of_bits <= 8)
703 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700704 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300705 pui8 = pui8DATA(data, pDescr->offset);
706 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400707 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300708 }
709 else if (no_of_bits <= 16)
710 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700711 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300712 pui16 = pui16DATA(data, pDescr->offset);
713 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400714 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300715 }
716 else if (no_of_bits <= 32)
717 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700718 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300719 pui32 = pui32DATA(data, pDescr->offset);
720 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400721 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300722 }
723 else
724 {
725 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
726 }
727 }
728 else
729 {
730 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
731 }
732
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700733 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300734 bit_offset += no_of_bits;
735 pDescr++;
736 break;
737 }
738
739 case CSN_UINT_LH:
740 {
741 guint8 no_of_bits = (guint8) pDescr->i;
742
743 if (remaining_bits_len >= no_of_bits)
744 {
745 if (no_of_bits <= 8)
746 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100747 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300748 pui8 = pui8DATA(data, pDescr->offset);
749 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400750 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300751 }
752 else
753 { /* Maybe we should support more than 8 bits ? */
754 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
755 }
756 }
757 else
758 {
759 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
760 }
761
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700762 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300763 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++;
Vadim Yanitskiyd8e5e8b2020-02-17 18:16:20 +0700953 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300954 remaining_bits_len -= 1;
955
956 if (!fExist)
957 {
958 ar->remaining_bits_len = remaining_bits_len;
959 ar->bit_offset = bit_offset;
960 return remaining_bits_len;
961 }
962
963 break;
964 }
965
966 case CSN_NEXT_EXIST:
967 {
968 guint8 fExist;
969
970 pui8 = pui8DATA(data, pDescr->offset);
971
972 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400973 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300974 { /* no more bits to decode is fine here - end of message detected and allowed */
975
976 /* Skip i entries + this entry */
977 pDescr += pDescr->i + 1;
978
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300979 /* Set the data member to "not exist" */
980 *pui8 = 0;
981 break;
982 }
983
984 /* the "regular" M_NEXT_EXIST description element */
985
986 fExist = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700987 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300988 {
989 fExist = 0x01;
990 }
991
992 *pui8 = fExist;
993 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400994 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300995 ++bit_offset;
996
997 if (fExist == 0)
998 { /* Skip 'i' entries */
999 pDescr += pDescr->i;
1000 }
1001
1002 pDescr++;
1003 break;
1004 }
1005
1006 case CSN_NEXT_EXIST_LH:
1007 {
1008 guint8 fExist;
1009 pui8 = pui8DATA(data, pDescr->offset);
1010
1011 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1012 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1013 { /* no more bits to decode is fine here - end of message detected and allowed */
1014
1015 /* skip 'i' entries + this entry */
1016 pDescr += pDescr->i + 1;
1017
1018 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1019 if ( pDescr->type != CSN_END )
1020 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1021 remaining_bits_len--;
1022 }
1023
1024 /* set the data member to "not exist" */
1025 *pui8 = 0;
1026 break;
1027 }
1028
1029 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001030 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001031 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001032 *pui8++ = fExist;
1033 remaining_bits_len -= 1;
1034
1035 bit_offset++;
1036
1037 if (fExist == 0)
1038 { /* Skip 'i' entries */
1039 pDescr += pDescr->i;
1040 }
1041 pDescr++;
1042
1043 break;
1044 }
1045
1046 case CSN_VARIABLE_BITMAP_1:
1047 { /* Bitmap from here and to the end of message */
1048
1049 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1050
1051 /*no break -
1052 * with a length set we have a regular variable length bitmap so we continue */
1053 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001054 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001055 case CSN_VARIABLE_BITMAP:
1056 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1057 * <N: bit (5)> <bitmap: bit(N + offset)>
1058 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1059 * The result is right aligned!
1060 */
1061 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1062
1063 no_of_bits += pDescr->i; /* adjusted by offset */
1064
1065 if (no_of_bits > 0)
1066 {
1067 remaining_bits_len -= no_of_bits;
1068
1069 if (remaining_bits_len < 0)
1070 {
1071 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1072 }
1073
1074 { /* extract bits */
1075 guint8* pui8 = pui8DATA(data, pDescr->offset);
1076 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1077
1078 if (nB1 > 0)
1079 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001080 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001081 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001082 pui8++;
1083 no_of_bits -= nB1;
1084 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1085 }
1086
1087 /* remaining no_of_bits is a multiple of 8 or 0 */
1088 while (no_of_bits > 0)
1089 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001090 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001091 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001092 pui8++;
1093 no_of_bits -= 8;
1094 }
1095 }
1096 }
1097 pDescr++;
1098 break;
1099 }
1100
1101 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1102 { /* Bitmap from here and to the end of message */
1103
1104 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1105
1106 /* no break -
1107 * with a length set we have a regular left aligned variable length bitmap so we continue
1108 */
1109 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001110 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001111 case CSN_LEFT_ALIGNED_VAR_BMP:
1112 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1113 * <N: bit (5)> <bitmap: bit(N + offset)>
1114 * bit array with length (in bits) specified in parameter (pDescr->descr)
1115 */
1116 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1117
1118 no_of_bits += pDescr->i;/* size adjusted by offset */
1119
1120 if (no_of_bits > 0)
1121 {
1122 remaining_bits_len -= no_of_bits;
1123
1124 if (remaining_bits_len < 0)
1125 {
1126 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1127 }
1128
1129 { /* extract bits */
1130 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001131
Neels Hofmeyr02415262016-09-02 02:15:26 +02001132 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001133 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001134 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001135 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001136 pui8++;
1137 no_of_bits -= 8;
1138 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001139 if (no_of_bits > 0)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001140 {
1141 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001142 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001143 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001144 bit_offset += no_of_bits;
1145 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001146 }
1147 }
1148 }
1149
1150 /* bitmap was successfully extracted or it was empty */
1151 pDescr++;
1152 break;
1153 }
1154
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001155 case CSN_PADDING_BITS:
1156 { /* Padding from here and to the end of message */
1157 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1158 if (remaining_bits_len > 0)
1159 {
1160 while (remaining_bits_len > 0)
1161 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001162 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001163 if (bits_to_handle > 0)
1164 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001165 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001166 remaining_bits_len -= bits_to_handle;
1167 bit_offset += bits_to_handle;
1168 }
1169 else if (bits_to_handle == 0)
1170 {
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001171 LOGPC(DCSN1, LOGL_NOTICE, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001172 remaining_bits_len -= 8;
1173 bit_offset += 8;
1174 }
1175 }
1176 }
1177 if (remaining_bits_len < 0)
1178 {
1179 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1180 }
1181
1182 /* Padding was successfully extracted or it was empty */
1183 pDescr++;
1184 break;
1185 }
1186
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001187 case CSN_VARIABLE_ARRAY:
1188 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1189 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1190 * Array with length specified in parameter:
1191 * <count: bit (x)>
1192 * <list: octet(count + offset)>
1193 */
1194 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1195
1196 count += pDescr->i; /* Adjusted by offset */
1197
1198 if (count > 0)
1199 {
1200 remaining_bits_len -= count * 8;
1201
1202 if (remaining_bits_len < 0)
1203 {
1204 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1205 }
1206
1207 pui8 = pui8DATA(data, pDescr->offset);
1208
1209 while (count > 0)
1210 {
1211 readIndex -= 8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001212 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001213 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001214 pui8++;
1215 bit_offset += 8;
1216 count--;
1217 }
1218 }
1219
1220 pDescr++;
1221 break;
1222 }
1223
1224 case CSN_RECURSIVE_ARRAY:
1225 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1226 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1227 * where <element> ::= bit(value)
1228 * <tag> ::= 0 | 1
1229 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1230 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1231 * REMARK: recursive way to specify an array but an iterative implementation!
1232 */
1233 gint16 no_of_bits = pDescr->i;
1234 guint8 ElementCount = 0;
1235
1236 pui8 = pui8DATA(data, pDescr->offset);
1237
Alexander Couzensccde5c92017-02-04 03:10:08 +01001238 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001239 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001240 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001241 bit_offset++;
1242 remaining_bits_len--;
1243
1244 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001245 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001246 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001247 pui8++;
1248 remaining_bits_len -= no_of_bits;
1249 ElementCount++;
1250
1251 if (remaining_bits_len < 0)
1252 {
1253 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1254 }
1255
1256 bit_offset += no_of_bits;
1257 }
1258
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001259 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001260 /* existNextElement() returned FALSE, 1 bit consumed */
1261 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001262 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001263
1264 /* Store the counted number of elements of the array */
1265 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1266
1267 pDescr++;
1268 break;
1269 }
1270
1271 case CSN_RECURSIVE_TARRAY:
1272 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1273 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1274 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1275 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001276 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001277 guint8 ElementCount = 0;
1278 pui8 = pui8DATA(data, pDescr->offset);
1279
Alexander Couzensccde5c92017-02-04 03:10:08 +01001280 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001281 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001282 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001283 /* existNextElement() returned TRUE, 1 bit consumed */
1284 bit_offset++;
1285 remaining_bits_len--;
1286 ElementCount++;
1287
1288 { /* unpack the following data structure */
1289 csnStream_t arT = *ar;
1290 gint16 Status;
1291 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001292 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001293
1294 if (Status >= 0)
1295 { /* successful completion */
1296 pui8 += nSizeElement; /* -> to next data element */
1297 remaining_bits_len = arT.remaining_bits_len;
1298 bit_offset = arT.bit_offset;
1299 }
1300 else
1301 { /* something went awry */
1302 return Status;
1303 }
1304 }
1305
1306 if (remaining_bits_len < 0)
1307 {
1308 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1309 }
1310 }
1311
Vadim Yanitskiy28b4d272020-02-05 06:06:35 +07001312 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001313
1314 /* existNextElement() returned FALSE, 1 bit consumed */
Vadim Yanitskiye87066d2020-02-17 18:02:32 +07001315 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001316 bit_offset++;
1317
1318 /* Store the counted number of elements of the array */
1319 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1320
1321 pDescr++;
1322 break;
1323 }
1324
1325 case CSN_RECURSIVE_TARRAY_2:
1326 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1327
1328 Tag = REVERSED_TAG;
1329
1330 /* NO break -
1331 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1332 */
1333 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001334 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001335 case CSN_RECURSIVE_TARRAY_1:
1336 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1337 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1338 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1339 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001340 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001341 guint8 ElementCount = 0;
1342 csnStream_t arT = *ar;
1343 gboolean EndOfList = FALSE;
1344 gint16 Status;
1345 pui8 = pui8DATA(data, pDescr->offset);
1346
1347 do
1348 { /* get data element */
1349 ElementCount++;
1350
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001351 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001352
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001353 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001354 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001355
1356 if (Status >= 0)
1357 { /* successful completion */
1358 pui8 += nSizeElement; /* -> to next */
1359 remaining_bits_len = arT.remaining_bits_len;
1360 bit_offset = arT.bit_offset;
1361 }
1362 else
1363 { /* something went awry */
1364 return Status;
1365 }
1366
1367 if (remaining_bits_len < 0)
1368 {
1369 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1370 }
1371
1372 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001373 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001374 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001375
1376 bit_offset++;
1377 remaining_bits_len--; /* 1 bit consumed (tag) */
1378 } while (!EndOfList);
1379
1380
1381 /* Store the count of the array */
1382 *pui8DATA(data, pDescr->i) = ElementCount;
1383 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1384 pDescr++;
1385 break;
1386 }
1387
1388 case CSN_FIXED:
1389 { /* Verify the fixed bits */
1390 guint8 no_of_bits = (guint8) pDescr->i;
1391 guint32 ui32;
1392
1393 if (no_of_bits <= 32)
1394 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001395 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001396 }
1397 else
1398 {
1399 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1400 }
1401 if (ui32 != (unsigned)(gint32)pDescr->offset)
1402 {
1403 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1404 }
1405
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001406 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001407 remaining_bits_len -= no_of_bits;
1408 bit_offset += no_of_bits;
1409 pDescr++;
1410 break;
1411 }
1412
1413 case CSN_CALLBACK:
1414 {
1415 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1416 break;
1417 }
1418
1419 case CSN_TRAP_ERROR:
1420 {
1421 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1422 }
1423
1424 case CSN_END:
1425 {
1426 ar->remaining_bits_len = remaining_bits_len;
1427 ar->bit_offset = bit_offset;
1428 return remaining_bits_len;
1429 }
1430
1431 default:
1432 {
1433 assert(0);
1434 }
1435
1436
1437 }
1438
1439 } while (remaining_bits_len >= 0);
1440
1441 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1442}
1443
1444
1445
1446
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001447gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001448{
1449 gint remaining_bits_len = ar->remaining_bits_len;
1450 gint bit_offset = ar->bit_offset;
1451 guint8* pui8;
1452 guint16* pui16;
1453 guint32* pui32;
1454 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001455 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001456
1457 guint8 Tag = STANDARD_TAG;
1458
1459 if (remaining_bits_len <= 0)
1460 {
1461 return 0;
1462 }
1463
1464 do
1465 {
1466 switch (pDescr->type)
1467 {
1468 case CSN_BIT:
1469 {
1470 if (remaining_bits_len > 0)
1471 {
1472 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001473 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001474 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001475 /* end add the bit value to protocol tree */
1476 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001477 else if(pDescr->may_be_null)
1478 {
1479 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1480 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001481 else
1482 {
1483 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1484 }
1485
1486 pDescr++;
1487 remaining_bits_len--;
1488 bit_offset++;
1489 break;
1490 }
1491
1492 case CSN_NULL:
1493 { /* Empty member! */
1494 pDescr++;
1495 break;
1496 }
1497
1498 case CSN_UINT:
1499 {
1500 guint8 no_of_bits = (guint8) pDescr->i;
1501
1502 if (remaining_bits_len >= no_of_bits)
1503 {
1504 if (no_of_bits <= 8)
1505 {
1506 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001507 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001508 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001509 }
1510 else if (no_of_bits <= 16)
1511 {
1512 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001513 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001514 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001515 }
1516 else if (no_of_bits <= 32)
1517 {
1518 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001519 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001520 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001521 }
1522 else
1523 {
1524 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1525 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001526
1527 remaining_bits_len -= no_of_bits;
1528 bit_offset += no_of_bits;
1529 }
1530 else if(pDescr->may_be_null)
1531 {
1532 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001533 }
1534 else
1535 {
1536 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1537 }
1538
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001539 pDescr++;
1540 break;
1541 }
1542
1543 case CSN_UINT_OFFSET:
1544 {
1545 guint8 no_of_bits = (guint8) pDescr->i;
1546
1547 if (remaining_bits_len >= no_of_bits)
1548 {
1549 if (no_of_bits <= 8)
1550 {
1551 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001552 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001553 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001554 }
1555 else if (no_of_bits <= 16)
1556 {
1557 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001558 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001559 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001560 }
1561 else if (no_of_bits <= 32)
1562 {
1563 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001564 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001565 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001566 }
1567 else
1568 {
1569 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1570 }
1571 }
1572 else
1573 {
1574 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1575 }
1576
1577 remaining_bits_len -= no_of_bits;
1578 bit_offset += no_of_bits;
1579 pDescr++;
1580 break;
1581 }
1582
1583 case CSN_UINT_LH:
1584 {
1585 guint8 no_of_bits = (guint8) pDescr->i;
1586
1587 if (remaining_bits_len >= no_of_bits)
1588 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001589 if (no_of_bits <= 8)
1590 {
1591 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001592 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001593 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001594 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001595 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001596 *writeIndex -= no_of_bits;
1597 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001598 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001599
1600 }
1601 else
1602 {/* Maybe we should support more than 8 bits ? */
1603 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1604 }
1605 }
1606 else
1607 {
1608 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1609 }
1610
1611 remaining_bits_len -= no_of_bits;
1612 bit_offset += no_of_bits;
1613 pDescr++;
1614 break;
1615 }
1616
1617 case CSN_UINT_ARRAY:
1618 {
1619 guint8 no_of_bits = (guint8) pDescr->i;
1620 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1621
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001622 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001623 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1624 nCount = *pui16DATA(data, nCount);
1625 }
1626
1627 if (remaining_bits_len >= no_of_bits)
1628 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001629 if (no_of_bits <= 8)
1630 {
1631 pui8 = pui8DATA(data, pDescr->offset);
1632 do
1633 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001634 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001635 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001636 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001637 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001638 bit_offset += no_of_bits;
1639 } while (--nCount > 0);
1640 }
1641 else if (no_of_bits <= 16)
1642 {
1643 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1644 }
1645 else if (no_of_bits <= 32)
1646 {
1647 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1648 }
1649 else
1650 {
1651 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1652 }
1653 }
1654 else
1655 {
1656 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1657 }
1658 pDescr++;
1659 break;
1660 }
1661
1662 case CSN_VARIABLE_TARRAY_OFFSET:
1663 case CSN_VARIABLE_TARRAY:
1664 case CSN_TYPE_ARRAY:
1665 {
1666 gint16 Status;
1667 csnStream_t arT = *ar;
1668 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001669 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001670
1671 pui8 = pui8DATA(data, pDescr->offset);
1672 if (pDescr->type == CSN_VARIABLE_TARRAY)
1673 { /* Count specified in field */
1674 nCount = *pui8DATA(data, pDescr->i);
1675 }
1676 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1677 { /* Count specified in field */
1678 nCount = *pui8DATA(data, pDescr->i);
1679 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1680 }
1681
1682 while (nCount > 0)
1683 { /* resulting array of length 0 is possible
1684 * but no bits shall be read from bitstream
1685 */
1686
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001687 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001688 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1689 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1690 if (Status >= 0)
1691 {
1692 pui8 += nSize;
1693 remaining_bits_len = arT.remaining_bits_len;
1694 bit_offset = arT.bit_offset;
1695
1696 }
1697 else
1698 {
1699 return Status;
1700 }
1701 nCount--;
1702 }
1703
1704 pDescr++;
1705 break;
1706 }
1707
1708 case CSN_BITMAP:
1709 { /* bitmap with given length. The result is left aligned! */
1710 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1711
1712 if (no_of_bits > 0)
1713 {
1714
1715 if (no_of_bits <= 32)
1716 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001717 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001718 {
1719 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001720 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001721 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001722 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001723 }
1724 else if (no_of_bits <= 64)
1725 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001726 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001727 {
1728 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001729 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001730 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001731 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001732 }
1733 else
1734 {
1735 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1736 }
1737
1738 remaining_bits_len -= no_of_bits;
1739 assert(remaining_bits_len >= 0);
1740 bit_offset += no_of_bits;
1741 }
1742 /* bitmap was successfully extracted or it was empty */
1743
1744 pDescr++;
1745 break;
1746 }
1747
1748 case CSN_TYPE:
1749 {
1750 gint16 Status;
1751 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001752 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001753 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1754 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001755 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001756 if (Status >= 0)
1757 {
1758
1759 remaining_bits_len = arT.remaining_bits_len;
1760 bit_offset = arT.bit_offset;
1761 pDescr++;
1762 }
1763 else
1764 {
1765 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1766 return Status;
1767 }
1768
1769 break;
1770 }
1771
1772 case CSN_CHOICE:
1773 {
1774 //gint16 count = pDescr->i;
1775 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001776 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001777
1778 pui8 = pui8DATA(data, pDescr->offset);
1779 i = *pui8;
1780 pChoice += i;
1781 guint8 no_of_bits = pChoice->bits;
1782 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001783 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001784 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001785
1786 CSN_DESCR descr[2];
1787 gint16 Status;
1788 csnStream_t arT = *ar;
1789
1790 descr[0] = pChoice->descr;
1791 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1792 descr[1].type = CSN_END;
1793 bit_offset += no_of_bits;
1794 remaining_bits_len -= no_of_bits;
1795
1796 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1797 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1798
1799 if (Status >= 0)
1800 {
1801 remaining_bits_len = arT.remaining_bits_len;
1802 bit_offset = arT.bit_offset;
1803 }
1804 else
1805 {
1806 return Status;
1807 }
1808
1809 pDescr++;
1810 break;
1811 }
1812
1813 case CSN_SERIALIZE:
1814 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001815 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001816 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001817 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001818 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001819 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001820
1821 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001822 lengthIndex = *writeIndex;
1823 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001824 bit_offset += length_len;
1825 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001826 arT.direction = 0;
1827 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1828 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001829
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001830 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
1831 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001832
1833 if (Status >= 0)
1834 {
1835 remaining_bits_len = arT.remaining_bits_len;
1836 bit_offset = arT.bit_offset;
1837 pDescr++;
1838 }
1839 else
1840 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001841 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001842 return Status;
1843 }
1844
1845 break;
1846 }
1847
1848 case CSN_UNION_LH:
1849 case CSN_UNION:
1850 {
1851 gint16 Bits;
1852 guint8 index;
1853 gint16 count = pDescr->i;
1854 const CSN_DESCR* pDescrNext = pDescr;
1855
1856 pDescrNext += count + 1; /* now this is next after the union */
1857 if ((count <= 0) || (count > 16))
1858 {
1859 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1860 }
1861
1862 /* Now get the bits to extract the index */
1863 Bits = ixBitsTab[count];
1864 index = 0;
1865
1866 /* Assign UnionType */
1867 pui8 = pui8DATA(data, pDescr->offset);
1868 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001869 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001870
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001871 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001872 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001873
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001874 while (Bits > 0)
1875 {
1876 index <<= 1;
1877
1878 if (CSN_UNION_LH == pDescr->type)
1879 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001880 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001881 }
1882 else
1883 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001884 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001885 }
1886
1887 remaining_bits_len--;
1888 bit_offset++;
1889 Bits--;
1890 }
1891
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001892 *writeIndex -= Bits;
1893 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001894
1895
1896 /* script index to continue on, limited in case we do not have a power of 2 */
1897 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001898 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001899
1900 switch (pDescr->type)
1901 { /* get the right element of the union based on computed index */
1902
1903 case CSN_BIT:
1904 {
1905 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001906 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001907 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001908 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001909 bit_offset++;
1910 pDescr++;
1911 break;
1912 }
1913
1914 case CSN_NULL:
1915 { /* Empty member! */
1916 pDescr++;
1917 break;
1918 }
1919
1920 case CSN_UINT:
1921 {
1922 guint8 no_of_bits = (guint8) pDescr->i;
1923 if (remaining_bits_len >= no_of_bits)
1924 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001925 if (no_of_bits <= 8)
1926 {
1927 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001928 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001929 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001930 }
1931 else if (no_of_bits <= 16)
1932 {
1933 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001934 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001935 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001936 }
1937 else if (no_of_bits <= 32)
1938 {
1939 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001940 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001941 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001942 }
1943 else
1944 {
1945 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1946 }
1947 }
1948 else
1949 {
1950 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1951 }
1952
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001953 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001954 bit_offset += no_of_bits;
1955 pDescr++;
1956 break;
1957 }
1958
1959 case CSN_UINT_OFFSET:
1960 {
1961 guint8 no_of_bits = (guint8) pDescr->i;
1962
1963 if (remaining_bits_len >= no_of_bits)
1964 {
1965 if (no_of_bits <= 8)
1966 {
1967 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001968 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001969 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001970 }
1971 else if (no_of_bits <= 16)
1972 {
1973 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001974 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001975 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001976 }
1977 else if (no_of_bits <= 32)
1978 {
1979 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001980 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001981 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001982 }
1983 else
1984 {
1985 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1986 }
1987 }
1988 else
1989 {
1990 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1991 }
1992
1993 remaining_bits_len -= no_of_bits;
1994 bit_offset += no_of_bits;
1995 pDescr++;
1996 break;
1997 }
1998
1999 case CSN_UINT_LH:
2000 {
2001 guint8 no_of_bits = (guint8) pDescr->i;
2002
2003 if (remaining_bits_len >= no_of_bits)
2004 {
2005 remaining_bits_len -= no_of_bits;
2006 if (no_of_bits <= 8)
2007 {
2008 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002009 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002010 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002011 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002012 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002013 *writeIndex -= no_of_bits;
2014 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002015 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002016
2017 }
2018 else
2019 {/* Maybe we should support more than 8 bits ? */
2020 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2021 }
2022 }
2023 else
2024 {
2025 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2026 }
2027
2028 remaining_bits_len -= no_of_bits;
2029 bit_offset += no_of_bits;
2030 pDescr++;
2031 break;
2032 }
2033
2034 case CSN_UINT_ARRAY:
2035 {
2036 guint8 no_of_bits = (guint8) pDescr->i;
2037 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2038
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002039 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002040 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2041 nCount = *pui16DATA(data, nCount);
2042 }
2043
2044 if (remaining_bits_len >= no_of_bits)
2045 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002046 if (no_of_bits <= 8)
2047 {
2048 pui8 = pui8DATA(data, pDescr->offset);
2049 do
2050 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002051 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002052 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002053 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002054 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002055 bit_offset += no_of_bits;
2056 } while (--nCount > 0);
2057 }
2058 else if (no_of_bits <= 16)
2059 {
2060 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2061 }
2062 else if (no_of_bits <= 32)
2063 {
2064 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2065 }
2066 else
2067 {
2068 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2069 }
2070 }
2071 else
2072 {
2073 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2074 }
2075 pDescr++;
2076 break;
2077 }
2078
2079 case CSN_VARIABLE_TARRAY_OFFSET:
2080 case CSN_VARIABLE_TARRAY:
2081 case CSN_TYPE_ARRAY:
2082 {
2083 gint16 Status;
2084 csnStream_t arT = *ar;
2085 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002086 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002087
2088 pui8 = pui8DATA(data, pDescr->offset);
2089 if (pDescr->type == CSN_VARIABLE_TARRAY)
2090 { /* Count specified in field */
2091 nCount = *pui8DATA(data, pDescr->i);
2092 }
2093 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2094 { /* Count specified in field */
2095 nCount = *pui8DATA(data, pDescr->i);
2096 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2097 }
2098
2099 while (nCount > 0)
2100 { /* resulting array of length 0 is possible
2101 * but no bits shall be read from bitstream
2102 */
2103
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002104 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002105 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2106 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2107 if (Status >= 0)
2108 {
2109 pui8 += nSize;
2110 remaining_bits_len = arT.remaining_bits_len;
2111 bit_offset = arT.bit_offset;
2112 }
2113 else
2114 {
2115 return Status;
2116 }
2117 nCount--;
2118 }
2119
2120 pDescr++;
2121 break;
2122 }
2123
2124 case CSN_BITMAP:
2125 { /* bitmap with given length. The result is left aligned! */
2126 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2127
2128 if (no_of_bits > 0)
2129 {
2130
2131 if (no_of_bits <= 32)
2132 {
2133 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002134 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002135 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002136 }
2137 else if (no_of_bits <= 64)
2138 {
2139 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002140 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002141 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002142 }
2143 else
2144 {
2145 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2146 }
2147
2148 remaining_bits_len -= no_of_bits;
2149 assert(remaining_bits_len >= 0);
2150 bit_offset += no_of_bits;
2151 }
2152 /* bitmap was successfully extracted or it was empty */
2153
2154 pDescr++;
2155 break;
2156 }
2157
2158 case CSN_TYPE:
2159 {
2160 gint16 Status;
2161 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002162 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002163 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2164 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002165 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002166 if (Status >= 0)
2167 {
2168 remaining_bits_len = arT.remaining_bits_len;
2169 bit_offset = arT.bit_offset;
2170 pDescr++;
2171 }
2172 else
2173 {
2174 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2175 return Status;
2176 }
2177
2178 break;
2179 }
2180
2181 default:
2182 { /* descriptions of union elements other than above are illegal */
2183 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2184 }
2185 }
2186
2187 pDescr = pDescrNext;
2188 break;
2189 }
2190
2191 case CSN_EXIST:
2192 case CSN_EXIST_LH:
2193 {
2194 guint8 fExist;
2195 unsigned exist = 0;
2196 pui8 = pui8DATA(data, pDescr->offset);
2197 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002198 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002199 writeIndex--;
2200 if (CSN_EXIST_LH == pDescr->type)
2201 {
2202 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2203 }
2204 else
2205 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002206 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002207 }
2208 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002209 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002210 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002211 remaining_bits_len--;
2212 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002213 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002214
2215 if (!exist)
2216 {
2217 ar->remaining_bits_len = remaining_bits_len;
2218 ar->bit_offset = bit_offset;
2219 return remaining_bits_len;
2220 }
2221 break;
2222 }
2223
2224 case CSN_NEXT_EXIST:
2225 {
2226 guint8 fExist;
2227
2228 pui8 = pui8DATA(data, pDescr->offset);
2229
2230 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002231 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002232 { /* no more bits to decode is fine here - end of message detected and allowed */
2233
2234 /* Skip i entries + this entry */
2235 pDescr += pDescr->i + 1;
2236
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002237 break;
2238 }
2239
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002240 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002241 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002242 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002243
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002244 remaining_bits_len--;
2245 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002246
2247 if (fExist == 0)
2248 { /* Skip 'i' entries */
2249 pDescr += pDescr->i;
2250 }
2251
2252 pDescr++;
2253 break;
2254 }
2255
2256 case CSN_NEXT_EXIST_LH:
2257 {
2258 guint8 fExist;
2259 pui8 = pui8DATA(data, pDescr->offset);
2260
2261 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2262 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2263 { /* no more bits to decode is fine here - end of message detected and allowed */
2264
2265 /* skip 'i' entries + this entry */
2266 pDescr += pDescr->i + 1;
2267
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002268 /* set the data member to "not exist" */
2269 //*pui8 = 0;
2270 break;
2271 }
2272
2273 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002274 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002275 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002276 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002277 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002278 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002279 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002280
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002281 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002282 bit_offset++;
2283
2284 if (fExist == 0)
2285 { /* Skip 'i' entries */
2286 pDescr += pDescr->i;
2287 }
2288 pDescr++;
2289
2290 break;
2291 }
2292
2293 case CSN_VARIABLE_BITMAP_1:
2294 { /* Bitmap from here and to the end of message */
2295
2296 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2297
2298 /*no break -
2299 * with a length set we have a regular variable length bitmap so we continue */
2300 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002301 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002302 case CSN_VARIABLE_BITMAP:
2303 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2304 * <N: bit (5)> <bitmap: bit(N + offset)>
2305 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2306 * The result is right aligned!
2307 */
2308 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2309
2310 no_of_bits += pDescr->i; /* adjusted by offset */
2311
2312 if (no_of_bits > 0)
2313 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002314
2315 if (remaining_bits_len < 0)
2316 {
2317 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2318 }
2319
2320 { /* extract bits */
2321 guint8* pui8 = pui8DATA(data, pDescr->offset);
2322 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2323
2324 if (nB1 > 0)
2325 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002326 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002327 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002328 pui8++;
2329 no_of_bits -= nB1;
2330 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002331 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002332 }
2333
2334 /* remaining no_of_bits is a multiple of 8 or 0 */
2335 while (no_of_bits > 0)
2336 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002337 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002338 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002339 pui8++;
2340 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002341 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002342 }
2343 }
2344 }
2345 pDescr++;
2346 break;
2347 }
2348
2349 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2350 { /* Bitmap from here and to the end of message */
2351
2352 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2353
2354 /* no break -
2355 * with a length set we have a regular left aligned variable length bitmap so we continue
2356 */
2357 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002358 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002359 case CSN_LEFT_ALIGNED_VAR_BMP:
2360 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2361 * <N: bit (5)> <bitmap: bit(N + offset)>
2362 * bit array with length (in bits) specified in parameter (pDescr->descr)
2363 */
2364
2365 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2366
2367 no_of_bits += pDescr->i;/* size adjusted by offset */
2368
2369 if (no_of_bits > 0)
2370 {
2371 remaining_bits_len -= no_of_bits;
2372
2373 if (remaining_bits_len < 0)
2374 {
2375 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2376 }
2377
2378 { /* extract bits */
2379 guint8* pui8 = pui8DATA(data, pDescr->offset);
2380 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2381
2382 while (no_of_bits > 0)
2383 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002384 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002385 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002386 pui8++;
2387 no_of_bits -= 8;
2388 }
2389 if (nB1 > 0)
2390 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002391 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002392 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002393 pui8++;
2394 no_of_bits -= nB1;
2395 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2396 }
2397 }
2398
2399 }
2400
2401 /* bitmap was successfully extracted or it was empty */
2402 pDescr++;
2403 break;
2404 }
2405
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002406 case CSN_PADDING_BITS:
2407 { /* Padding from here and to the end of message */
2408 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2409 guint8 filler = 0x2b;
2410 if (remaining_bits_len > 0)
2411 {
2412 while (remaining_bits_len > 0)
2413 {
2414 guint8 bits_to_handle = remaining_bits_len%8;
2415 if (bits_to_handle > 0)
2416 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302417 /* section 11 of 44.060
2418 * The padding bits may be the 'null' string. Otherwise, the
2419 * padding bits starts with bit '0', followed by 'spare padding'
2420 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2421 */
2422 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002423 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002424 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2425 remaining_bits_len -= bits_to_handle;
2426 bit_offset += bits_to_handle;
2427 }
2428 else if (bits_to_handle == 0)
2429 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002430 bitvec_write_field(vector, writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002431 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2432 remaining_bits_len -= 8;
2433 bit_offset += 8;
2434 }
2435 }
2436 }
2437 if (remaining_bits_len < 0)
2438 {
2439 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2440 }
2441
2442 /* Padding was successfully extracted or it was empty */
2443 pDescr++;
2444 break;
2445 }
2446
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002447 case CSN_VARIABLE_ARRAY:
2448 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2449 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2450 * Array with length specified in parameter:
2451 * <count: bit (x)>
2452 * <list: octet(count + offset)>
2453 */
2454 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2455
2456 count += pDescr->i; /* Adjusted by offset */
2457
2458 if (count > 0)
2459 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002460 if (remaining_bits_len < 0)
2461 {
2462 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2463 }
2464
2465 pui8 = pui8DATA(data, pDescr->offset);
2466
2467 while (count > 0)
2468 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002469 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002470 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002471 pui8++;
2472 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002473 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002474 count--;
2475 }
2476 }
2477
2478 pDescr++;
2479 break;
2480 }
2481
2482 case CSN_RECURSIVE_ARRAY:
2483 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2484 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2485 * where <element> ::= bit(value)
2486 * <tag> ::= 0 | 1
2487 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2488 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2489 * REMARK: recursive way to specify an array but an iterative implementation!
2490 */
2491 gint16 no_of_bits = pDescr->i;
2492 guint8 ElementCount = 0;
2493 pui8 = pui8DATA(data, pDescr->offset);
2494 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2495 while (ElementCount > 0)
2496 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002497 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002498 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002499 bit_offset++;
2500 remaining_bits_len--;
2501
2502 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002503 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002504 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002505 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002506 ElementCount--;
2507
2508 if (remaining_bits_len < 0)
2509 {
2510 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2511 }
2512
2513 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002514 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002515 }
2516
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002517 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002518 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002519 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302520 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002521
2522 pDescr++;
2523 break;
2524 }
2525
2526 case CSN_RECURSIVE_TARRAY:
2527 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2528 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2529 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2530 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002531 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002532 guint8 ElementCount = 0;
2533 pui8 = pui8DATA(data, pDescr->offset);
2534 /* Store the counted number of elements of the array */
2535 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2536
2537 while (ElementCount > 0)
2538 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002539 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002540 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002541 bit_offset++;
2542
2543 remaining_bits_len--;
2544 ElementCount--;
2545
2546 { /* unpack the following data structure */
2547 csnStream_t arT = *ar;
2548 gint16 Status;
2549 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002550 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002551
2552 if (Status >= 0)
2553 { /* successful completion */
2554 pui8 += nSizeElement; /* -> to next data element */
2555 remaining_bits_len = arT.remaining_bits_len;
2556 bit_offset = arT.bit_offset;
2557 }
2558 else
2559 { /* something went awry */
2560 return Status;
2561 }
2562 }
2563
2564 if (remaining_bits_len < 0)
2565 {
2566 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2567 }
2568 }
2569
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002570 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002571 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002572 bit_offset++;
2573
2574 pDescr++;
2575 break;
2576 }
2577
2578 case CSN_RECURSIVE_TARRAY_2:
2579 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2580
2581 Tag = REVERSED_TAG;
2582
2583 /* NO break -
2584 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2585 */
2586 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002587 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002588 case CSN_RECURSIVE_TARRAY_1:
2589 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2590 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2591 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2592 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002593 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002594 guint8 ElementCount = 0;
2595 guint8 ElementNum = 0;
2596 csnStream_t arT = *ar;
2597 gint16 Status;
2598
2599 pui8 = pui8DATA(data, pDescr->offset);
2600 /* Store the count of the array */
2601 ElementCount = *pui8DATA(data, pDescr->i);
2602 ElementNum = ElementCount;
2603
2604 while (ElementCount > 0)
2605 { /* get data element */
2606 if (ElementCount != ElementNum)
2607 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002608 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002609 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002610 bit_offset++;
2611 remaining_bits_len--;
2612 }
2613 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002614 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002615 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002616 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002617 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002618 if (Status >= 0)
2619 { /* successful completion */
2620 pui8 += nSizeElement; /* -> to next */
2621 remaining_bits_len = arT.remaining_bits_len;
2622 bit_offset = arT.bit_offset;
2623 }
2624 else
2625 { /* something went awry */
2626 return Status;
2627 }
2628
2629 if (remaining_bits_len < 0)
2630 {
2631 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2632 }
2633
2634 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002635 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002636 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002637 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002638 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2639 pDescr++;
2640 break;
2641 }
2642
2643 case CSN_FIXED:
2644 { /* Verify the fixed bits */
2645 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002646 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002647 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002648 remaining_bits_len -= no_of_bits;
2649 bit_offset += no_of_bits;
2650 pDescr++;
2651 break;
2652 }
2653
2654 case CSN_CALLBACK:
2655 {
2656 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2657 break;
2658 }
2659
2660 case CSN_TRAP_ERROR:
2661 {
2662 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2663 }
2664
2665 case CSN_END:
2666 {
2667 ar->remaining_bits_len = remaining_bits_len;
2668 ar->bit_offset = bit_offset;
2669 return remaining_bits_len;
2670 }
2671
2672 default:
2673 {
2674 assert(0);
2675 }
2676
2677 }
2678
2679 } while (remaining_bits_len >= 0);
2680
2681 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2682}