blob: f248b95835a829f0240ce5d8340027807c580935 [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31#include <iostream>
32#include <cstdlib>
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040033#include <assert.h>
34#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020035#define __STDC_FORMAT_MACROS
36#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040038#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030039
40
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
50using namespace std;
51static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
52
53
54/* Returns no_of_bits (up to 8) masked with 0x2B */
55
56static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040057get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030058{
59 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
60 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
61 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
62 guint8 result;
63 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
64 readIndex -= relative_bit_offset;
65 if (bit_shift >= 0)
66 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010067 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030068 readIndex-= bit_shift;
69 result &= maskBits[no_of_bits];
70 }
71 else
72 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010073 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030074 hight_part = (guint8) (hight_part << (-bit_shift));
Alexander Couzensccde5c92017-02-04 03:10:08 +010075 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030076 readIndex = readIndex - (8 - (-bit_shift));
77 result |= hight_part;
78 }
79 return result;
80}
81
82/**
83 * ================================================================================================
84 * set initial/start values in help data structure used for packing/unpacking operation
85 * ================================================================================================
86 */
87void
88csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
89{
90 ar->remaining_bits_len = remaining_bits_len;
91 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040092 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030093}
94
95static const char* ErrCodes[] =
96{
97 "General 0",
98 "General -1",
99 "DATA_NOT VALID",
100 "IN SCRIPT",
101 "INVALID UNION INDEX",
102 "NEED_MORE BITS TO UNPACK",
103 "ILLEGAL BIT VALUE",
104 "Internal",
105 "STREAM_NOT_SUPPORTED",
106 "MESSAGE_TOO_LONG"
107};
108
109static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400110ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111{
112 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
113 if (i >= 0)
114 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400115 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116 }
117 else
118 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400119 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300120 }
121 return err;
122}
123
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300124
125/**
126 * ================================================================================================
127 * Return TRUE if tag in bit stream indicates existence of next list element,
128 * otherwise return FALSE.
129 * Will work for tag values equal to both 0 and 1.
130 * ================================================================================================
131 */
132
133static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400134existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300135{
Alexander Couzensccde5c92017-02-04 03:10:08 +0100136 guint8 res = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300137 if (Tag == STANDARD_TAG)
138 {
139 return (res > 0);
140 }
141 return (res == 0);
142}
143
144
145gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400146csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300147{
148 gint remaining_bits_len = ar->remaining_bits_len;
149 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100150 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300151 guint16* pui16;
152 guint32* pui32;
153 guint64* pui64;
154 guint8 Tag = STANDARD_TAG;
155
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);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100170 *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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100206 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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100213 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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100220 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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100268 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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100275 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 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100282 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300283 pui32 = pui32DATA(data, pDescr->offset);
284 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400285 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300286 }
287 else
288 {
289 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
290 }
291 }
292 else
293 {
294 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
295 }
296
297 remaining_bits_len -= no_of_bits;
298 bit_offset += no_of_bits;
299 pDescr++;
300 break;
301 }
302
303 case CSN_UINT_LH:
304 {
305 guint8 no_of_bits = (guint8) pDescr->i;
306
307 if (remaining_bits_len >= no_of_bits)
308 {
309 remaining_bits_len -= no_of_bits;
310 if (no_of_bits <= 8)
311 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100312 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300313 pui8 = pui8DATA(data, pDescr->offset);
314 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400315 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300316 }
317 else
318 {/* Maybe we should support more than 8 bits ? */
319 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
320 }
321 }
322 else
323 {
324 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
325 }
326
327 remaining_bits_len -= no_of_bits;
328 bit_offset += no_of_bits;
329 pDescr++;
330 break;
331 }
332
333 case CSN_UINT_ARRAY:
334 {
335 guint8 no_of_bits = (guint8) pDescr->i;
336 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
337
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100338 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300339 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
340 nCount = *pui16DATA(data, nCount);
341 }
342
343 if (remaining_bits_len >= no_of_bits)
344 {
345 remaining_bits_len -= (no_of_bits*nCount);
346 if (no_of_bits <= 8)
347 {
348 pui8 = pui8DATA(data, pDescr->offset);
349 do
350 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100351 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400352 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300353 pui8++;
354 bit_offset += no_of_bits;
355 } while (--nCount > 0);
356 }
357 else if (no_of_bits <= 16)
358 {
359 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
360 }
361 else if (no_of_bits <= 32)
362 {
363 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
364 }
365 else
366 {
367 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
368 }
369 }
370 else
371 {
372 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
373 }
374 pDescr++;
375 break;
376 }
377
378 case CSN_VARIABLE_TARRAY_OFFSET:
379 case CSN_VARIABLE_TARRAY:
380 case CSN_TYPE_ARRAY:
381 {
382 gint16 Status;
383 csnStream_t arT = *ar;
384 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100385 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300386
387 pui8 = pui8DATA(data, pDescr->offset);
388 if (pDescr->type == CSN_VARIABLE_TARRAY)
389 { /* Count specified in field */
390 nCount = *pui8DATA(data, pDescr->i);
391 }
392 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
393 { /* Count specified in field */
394 nCount = *pui8DATA(data, pDescr->i);
395 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
396 }
397
398 while (nCount > 0)
399 { /* resulting array of length 0 is possible
400 * but no bits shall be read from bitstream
401 */
402
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400403 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300404 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100405 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300406 if (Status >= 0)
407 {
408 pui8 += nSize;
409 remaining_bits_len = arT.remaining_bits_len;
410 bit_offset = arT.bit_offset;
411 }
412 else
413 {
414 return Status;
415 }
416 nCount--;
417 }
418
419 pDescr++;
420 break;
421 }
422
423 case CSN_BITMAP:
424 { /* bitmap with given length. The result is left aligned! */
425 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
426
427 if (no_of_bits > 0)
428 {
429
430 if (no_of_bits <= 32)
431 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400432 for(unsigned ib = 0; ib < 4; ib++)
433 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100434 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400435 pui8 = pui8DATA(data, pDescr->offset+ib);
436 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400437 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400438 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300439 }
440 else if (no_of_bits <= 64)
441 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400442 for(unsigned ib = 0; ib < 8; ib++)
443 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100444 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400445 pui8 = pui8DATA(data, pDescr->offset+ib);
446 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400447 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400448 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300449 }
450 else
451 {
452 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
453 }
454
455 remaining_bits_len -= no_of_bits;
456 assert(remaining_bits_len >= 0);
457 bit_offset += no_of_bits;
458 }
459 /* bitmap was successfully extracted or it was empty */
460
461 pDescr++;
462 break;
463 }
464
465 case CSN_TYPE:
466 {
467 gint16 Status;
468 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400469 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300470 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100471 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400472 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300473 if (Status >= 0)
474 {
475 remaining_bits_len = arT.remaining_bits_len;
476 bit_offset = arT.bit_offset;
477 pDescr++;
478 }
479 else
480 {
481 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
482 return Status;
483 }
484
485 break;
486 }
487
488 case CSN_CHOICE:
489 {
490 gint16 count = pDescr->i;
491 guint8 i = 0;
492 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
493
494 while (count > 0)
495 {
496 guint8 no_of_bits = pChoice->bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100497 guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300498 if (value == pChoice->value)
499 {
500 CSN_DESCR descr[2];
501 gint16 Status;
502 csnStream_t arT = *ar;
503
504 descr[0] = pChoice->descr;
505 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
506 descr[1].type = CSN_END;
507 pui8 = pui8DATA(data, pDescr->offset);
508 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400509 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100510 if (!pChoice->keep_bits) {
511 bit_offset += no_of_bits;
512 remaining_bits_len -= no_of_bits;
513 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300514
515 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100516 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300517
518 if (Status >= 0)
519 {
520 remaining_bits_len = arT.remaining_bits_len;
521 bit_offset = arT.bit_offset;
522 }
523 else
524 {
525 return Status;
526 }
527 break;
528 }
529
530 readIndex -= no_of_bits;
531 count--;
532 pChoice++;
533 i++;
534 }
535
536 pDescr++;
537 break;
538 }
539
540 case CSN_SERIALIZE:
541 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100542 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300543 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400544 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300545 gint16 Status = -1;
546
Alexander Couzensccde5c92017-02-04 03:10:08 +0100547 guint8 length = bitvec_read_field(vector, &readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300548
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400549 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400550 bit_offset += length_len;
551 remaining_bits_len -= length_len;
552
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100553 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100554 arT.direction = 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100555 LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100556 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300557
558 if (Status >= 0)
559 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100560 if (length > 0) {
561 remaining_bits_len -= length;
562 bit_offset += length;
563 } else {
564 remaining_bits_len = arT.remaining_bits_len;
565 bit_offset = arT.bit_offset;
566 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300567 pDescr++;
568 }
569 else
570 {
571 /* Has already been processed: */
572 return Status;
573 }
574
575 break;
576 }
577
578 case CSN_UNION_LH:
579 case CSN_UNION:
580 {
581 gint16 Bits;
582 guint8 index;
583 gint16 count = pDescr->i;
584 const CSN_DESCR* pDescrNext = pDescr;
585
586 pDescrNext += count + 1; /* now this is next after the union */
587 if ((count <= 0) || (count > 16))
588 {
589 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
590 }
591
592 /* Now get the bits to extract the index */
593 Bits = ixBitsTab[count];
594 index = 0;
595
596 while (Bits > 0)
597 {
598 index <<= 1;
599
600 if (CSN_UNION_LH == pDescr->type)
601 {
602 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
603 }
604 else
605 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100606 index |= bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300607 }
608 remaining_bits_len--;
609 bit_offset++;
610 Bits--;
611 }
612
613 /* Assign UnionType */
614 pui8 = pui8DATA(data, pDescr->offset);
615 *pui8 = index;
616
617
618 /* script index to continue on, limited in case we do not have a power of 2 */
619 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400620 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621
622 switch (pDescr->type)
623 { /* get the right element of the union based on computed index */
624
625 case CSN_BIT:
626 {
627 pui8 = pui8DATA(data, pDescr->offset);
628 *pui8 = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100629 if (bitvec_read_field(vector, &readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300630 {
631 *pui8 = 0x01;
632 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400633 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300634 remaining_bits_len -= 1;
635 bit_offset++;
636 pDescr++;
637 break;
638 }
639
640 case CSN_NULL:
641 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100642 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300643 pDescr++;
644 break;
645 }
646
647 case CSN_UINT:
648 {
649 guint8 no_of_bits = (guint8) pDescr->i;
650 if (remaining_bits_len >= no_of_bits)
651 {
652 remaining_bits_len -= no_of_bits;
653
654 if (no_of_bits <= 8)
655 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100656 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300657 pui8 = pui8DATA(data, pDescr->offset);
658 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400659 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300660 }
661 else if (no_of_bits <= 16)
662 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100663 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300664 pui16 = pui16DATA(data, pDescr->offset);
665 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400666 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300667 }
668 else if (no_of_bits <= 32)
669 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100670 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300671 pui32 = pui32DATA(data, pDescr->offset);
672 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400673 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300674 }
675 else
676 {
677 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
678 }
679 }
680 else
681 {
682 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
683 }
684
685 bit_offset += no_of_bits;
686 pDescr++;
687 break;
688 }
689
690 case CSN_UINT_OFFSET:
691 {
692 guint8 no_of_bits = (guint8) pDescr->i;
693
694 if (remaining_bits_len >= no_of_bits)
695 {
696 if (no_of_bits <= 8)
697 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100698 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300699 pui8 = pui8DATA(data, pDescr->offset);
700 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400701 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300702 }
703 else if (no_of_bits <= 16)
704 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100705 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300706 pui16 = pui16DATA(data, pDescr->offset);
707 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400708 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300709 }
710 else if (no_of_bits <= 32)
711 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100712 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300713 pui32 = pui32DATA(data, pDescr->offset);
714 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400715 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300716 }
717 else
718 {
719 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
720 }
721 }
722 else
723 {
724 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
725 }
726
727 bit_offset += no_of_bits;
728 pDescr++;
729 break;
730 }
731
732 case CSN_UINT_LH:
733 {
734 guint8 no_of_bits = (guint8) pDescr->i;
735
736 if (remaining_bits_len >= no_of_bits)
737 {
738 if (no_of_bits <= 8)
739 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100740 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300741 pui8 = pui8DATA(data, pDescr->offset);
742 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400743 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300744 }
745 else
746 { /* Maybe we should support more than 8 bits ? */
747 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
748 }
749 }
750 else
751 {
752 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
753 }
754
755 bit_offset += no_of_bits;
756 pDescr++;
757 break;
758 }
759
760 case CSN_UINT_ARRAY:
761 {
762 guint8 no_of_bits = (guint8) pDescr->i;
763 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
764
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100765 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300766 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
767 nCount = *pui16DATA(data, nCount);
768 }
769
770 if (remaining_bits_len >= no_of_bits)
771 {
772 remaining_bits_len -= (no_of_bits * nCount);
773 if (no_of_bits <= 8)
774 {
775 pui8 = pui8DATA(data, pDescr->offset);
776
777 while (nCount > 0)
778 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100779 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400780 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300781 pui8++;
782 bit_offset += no_of_bits;
783 nCount--;
784 }
785 }
786 else if (no_of_bits <= 16)
787 {
788 pui16 = pui16DATA(data, pDescr->offset);
789
790 while (nCount > 0)
791 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100792 *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400793 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300794 pui16++;
795 bit_offset += no_of_bits;
796 nCount--;
797 }
798 }
799 else if (no_of_bits <= 32)
800 { /* not supported */
801 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
802 }
803 else
804 {
805 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
806 }
807 }
808 else
809 {
810 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
811 }
812
813 pDescr++;
814 break;
815 }
816
817 case CSN_VARIABLE_TARRAY_OFFSET:
818 case CSN_VARIABLE_TARRAY:
819 case CSN_TYPE_ARRAY:
820 {
821 gint16 Status;
822 csnStream_t arT = *ar;
823 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100824 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300825
826 pui8 = pui8DATA(data, pDescr->offset);
827
828 if (CSN_VARIABLE_TARRAY == pDescr->type)
829 { /* Count specified in field */
830 nCount = *pui8DATA(data, pDescr->i);
831 }
832 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
833 { /* Count specified in field */
834 nCount = *pui8DATA(data, pDescr->i);
835 nCount--; /* Offset 1 */
836 }
837
838 while (nCount--) /* Changed to handle length = 0. */
839 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400840 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300841 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100842 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300843 if (Status >= 0)
844 {
845 pui8 += nSize;
846 remaining_bits_len = arT.remaining_bits_len;
847 bit_offset = arT.bit_offset;
848 }
849 else
850 {
851 return Status;
852 }
853 }
854
855 pDescr++;
856 break;
857 }
858
859 case CSN_BITMAP:
860 { /* bitmap with given length. The result is left aligned! */
861 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
862
863 if (no_of_bits > 0)
864 {
865
866 if (no_of_bits <= 32)
867 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100868 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300869 pui32 = pui32DATA(data, pDescr->offset);
870 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300871 }
872 else if (no_of_bits <= 64)
873 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100874 guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300875 pui64 = pui64DATA(data, pDescr->offset);
876 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200877 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300878 }
879 else
880 {
881 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
882 }
883
884 remaining_bits_len -= no_of_bits;
885 assert(remaining_bits_len >= 0);
886 bit_offset += no_of_bits;
887 }
888 /* bitmap was successfully extracted or it was empty */
889
890 pDescr++;
891 break;
892 }
893
894 case CSN_TYPE:
895 {
896 gint16 Status;
897 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400898 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300899 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100900 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400901 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300902 if (Status >= 0)
903 {
904 remaining_bits_len = arT.remaining_bits_len;
905 bit_offset = arT.bit_offset;
906 pDescr++;
907 }
908 else
909 { /* return error code Has already been processed: */
910 return Status;
911 }
912
913 break;
914 }
915
916 default:
917 { /* descriptions of union elements other than above are illegal */
918 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
919 }
920 }
921
922 pDescr = pDescrNext;
923 break;
924 }
925
926 case CSN_EXIST:
927 case CSN_EXIST_LH:
928 {
929 guint8 fExist;
930
931 pui8 = pui8DATA(data, pDescr->offset);
932
933 if (CSN_EXIST_LH == pDescr->type)
934 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100935 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300936 }
937 else
938 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100939 fExist = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300940 }
941
942 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400943 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300944 pDescr++;
945 remaining_bits_len -= 1;
946
947 if (!fExist)
948 {
949 ar->remaining_bits_len = remaining_bits_len;
950 ar->bit_offset = bit_offset;
951 return remaining_bits_len;
952 }
953
954 break;
955 }
956
957 case CSN_NEXT_EXIST:
958 {
959 guint8 fExist;
960
961 pui8 = pui8DATA(data, pDescr->offset);
962
963 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400964 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300965 { /* no more bits to decode is fine here - end of message detected and allowed */
966
967 /* Skip i entries + this entry */
968 pDescr += pDescr->i + 1;
969
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300970 /* Set the data member to "not exist" */
971 *pui8 = 0;
972 break;
973 }
974
975 /* the "regular" M_NEXT_EXIST description element */
976
977 fExist = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100978 if (bitvec_read_field(vector, &readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300979 {
980 fExist = 0x01;
981 }
982
983 *pui8 = fExist;
984 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400985 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300986 ++bit_offset;
987
988 if (fExist == 0)
989 { /* Skip 'i' entries */
990 pDescr += pDescr->i;
991 }
992
993 pDescr++;
994 break;
995 }
996
997 case CSN_NEXT_EXIST_LH:
998 {
999 guint8 fExist;
1000 pui8 = pui8DATA(data, pDescr->offset);
1001
1002 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1003 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1004 { /* no more bits to decode is fine here - end of message detected and allowed */
1005
1006 /* skip 'i' entries + this entry */
1007 pDescr += pDescr->i + 1;
1008
1009 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1010 if ( pDescr->type != CSN_END )
1011 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1012 remaining_bits_len--;
1013 }
1014
1015 /* set the data member to "not exist" */
1016 *pui8 = 0;
1017 break;
1018 }
1019
1020 /* the "regular" M_NEXT_EXIST_LH description element */
1021 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001022 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001023 *pui8++ = fExist;
1024 remaining_bits_len -= 1;
1025
1026 bit_offset++;
1027
1028 if (fExist == 0)
1029 { /* Skip 'i' entries */
1030 pDescr += pDescr->i;
1031 }
1032 pDescr++;
1033
1034 break;
1035 }
1036
1037 case CSN_VARIABLE_BITMAP_1:
1038 { /* Bitmap from here and to the end of message */
1039
1040 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1041
1042 /*no break -
1043 * with a length set we have a regular variable length bitmap so we continue */
1044 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001045 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001046 case CSN_VARIABLE_BITMAP:
1047 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1048 * <N: bit (5)> <bitmap: bit(N + offset)>
1049 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1050 * The result is right aligned!
1051 */
1052 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1053
1054 no_of_bits += pDescr->i; /* adjusted by offset */
1055
1056 if (no_of_bits > 0)
1057 {
1058 remaining_bits_len -= no_of_bits;
1059
1060 if (remaining_bits_len < 0)
1061 {
1062 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1063 }
1064
1065 { /* extract bits */
1066 guint8* pui8 = pui8DATA(data, pDescr->offset);
1067 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1068
1069 if (nB1 > 0)
1070 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001071 *pui8 = bitvec_read_field(vector, &readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001072 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001073 pui8++;
1074 no_of_bits -= nB1;
1075 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1076 }
1077
1078 /* remaining no_of_bits is a multiple of 8 or 0 */
1079 while (no_of_bits > 0)
1080 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001081 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001082 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001083 pui8++;
1084 no_of_bits -= 8;
1085 }
1086 }
1087 }
1088 pDescr++;
1089 break;
1090 }
1091
1092 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1093 { /* Bitmap from here and to the end of message */
1094
1095 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1096
1097 /* no break -
1098 * with a length set we have a regular left aligned variable length bitmap so we continue
1099 */
1100 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001101 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001102 case CSN_LEFT_ALIGNED_VAR_BMP:
1103 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1104 * <N: bit (5)> <bitmap: bit(N + offset)>
1105 * bit array with length (in bits) specified in parameter (pDescr->descr)
1106 */
1107 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1108
1109 no_of_bits += pDescr->i;/* size adjusted by offset */
1110
1111 if (no_of_bits > 0)
1112 {
1113 remaining_bits_len -= no_of_bits;
1114
1115 if (remaining_bits_len < 0)
1116 {
1117 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1118 }
1119
1120 { /* extract bits */
1121 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001122
Neels Hofmeyr02415262016-09-02 02:15:26 +02001123 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001124 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001125 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001126 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001127 pui8++;
1128 no_of_bits -= 8;
1129 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001130 if (no_of_bits > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001131 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001132 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001133 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001134 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001135 bit_offset += no_of_bits;
1136 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001137 }
1138 }
1139 }
1140
1141 /* bitmap was successfully extracted or it was empty */
1142 pDescr++;
1143 break;
1144 }
1145
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001146 case CSN_PADDING_BITS:
1147 { /* Padding from here and to the end of message */
1148 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1149 if (remaining_bits_len > 0)
1150 {
1151 while (remaining_bits_len > 0)
1152 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001153 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001154 if (bits_to_handle > 0)
1155 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001156 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001157 remaining_bits_len -= bits_to_handle;
1158 bit_offset += bits_to_handle;
1159 }
1160 else if (bits_to_handle == 0)
1161 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001162 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001163 remaining_bits_len -= 8;
1164 bit_offset += 8;
1165 }
1166 }
1167 }
1168 if (remaining_bits_len < 0)
1169 {
1170 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1171 }
1172
1173 /* Padding was successfully extracted or it was empty */
1174 pDescr++;
1175 break;
1176 }
1177
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001178 case CSN_VARIABLE_ARRAY:
1179 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1180 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1181 * Array with length specified in parameter:
1182 * <count: bit (x)>
1183 * <list: octet(count + offset)>
1184 */
1185 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1186
1187 count += pDescr->i; /* Adjusted by offset */
1188
1189 if (count > 0)
1190 {
1191 remaining_bits_len -= count * 8;
1192
1193 if (remaining_bits_len < 0)
1194 {
1195 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1196 }
1197
1198 pui8 = pui8DATA(data, pDescr->offset);
1199
1200 while (count > 0)
1201 {
1202 readIndex -= 8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001203 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001204 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001205 pui8++;
1206 bit_offset += 8;
1207 count--;
1208 }
1209 }
1210
1211 pDescr++;
1212 break;
1213 }
1214
1215 case CSN_RECURSIVE_ARRAY:
1216 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1217 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1218 * where <element> ::= bit(value)
1219 * <tag> ::= 0 | 1
1220 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1221 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1222 * REMARK: recursive way to specify an array but an iterative implementation!
1223 */
1224 gint16 no_of_bits = pDescr->i;
1225 guint8 ElementCount = 0;
1226
1227 pui8 = pui8DATA(data, pDescr->offset);
1228
Alexander Couzensccde5c92017-02-04 03:10:08 +01001229 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001230 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001231 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001232 bit_offset++;
1233 remaining_bits_len--;
1234
1235 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001236 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001237 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001238 pui8++;
1239 remaining_bits_len -= no_of_bits;
1240 ElementCount++;
1241
1242 if (remaining_bits_len < 0)
1243 {
1244 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1245 }
1246
1247 bit_offset += no_of_bits;
1248 }
1249
Alexander Couzensccde5c92017-02-04 03:10:08 +01001250 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001251 /* existNextElement() returned FALSE, 1 bit consumed */
1252 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001253 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001254
1255 /* Store the counted number of elements of the array */
1256 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1257
1258 pDescr++;
1259 break;
1260 }
1261
1262 case CSN_RECURSIVE_TARRAY:
1263 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1264 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1265 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1266 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001267 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001268 guint8 ElementCount = 0;
1269 pui8 = pui8DATA(data, pDescr->offset);
1270
Alexander Couzensccde5c92017-02-04 03:10:08 +01001271 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001272 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001273 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001274 /* existNextElement() returned TRUE, 1 bit consumed */
1275 bit_offset++;
1276 remaining_bits_len--;
1277 ElementCount++;
1278
1279 { /* unpack the following data structure */
1280 csnStream_t arT = *ar;
1281 gint16 Status;
1282 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001283 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001284
1285 if (Status >= 0)
1286 { /* successful completion */
1287 pui8 += nSizeElement; /* -> to next data element */
1288 remaining_bits_len = arT.remaining_bits_len;
1289 bit_offset = arT.bit_offset;
1290 }
1291 else
1292 { /* something went awry */
1293 return Status;
1294 }
1295 }
1296
1297 if (remaining_bits_len < 0)
1298 {
1299 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1300 }
1301 }
1302
Alexander Couzensccde5c92017-02-04 03:10:08 +01001303 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001304
1305 /* existNextElement() returned FALSE, 1 bit consumed */
1306 bit_offset++;
1307
1308 /* Store the counted number of elements of the array */
1309 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1310
1311 pDescr++;
1312 break;
1313 }
1314
1315 case CSN_RECURSIVE_TARRAY_2:
1316 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1317
1318 Tag = REVERSED_TAG;
1319
1320 /* NO break -
1321 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1322 */
1323 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001324 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001325 case CSN_RECURSIVE_TARRAY_1:
1326 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1327 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1328 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1329 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001330 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001331 guint8 ElementCount = 0;
1332 csnStream_t arT = *ar;
1333 gboolean EndOfList = FALSE;
1334 gint16 Status;
1335 pui8 = pui8DATA(data, pDescr->offset);
1336
1337 do
1338 { /* get data element */
1339 ElementCount++;
1340
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001341 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1342
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001343 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001344 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001345
1346 if (Status >= 0)
1347 { /* successful completion */
1348 pui8 += nSizeElement; /* -> to next */
1349 remaining_bits_len = arT.remaining_bits_len;
1350 bit_offset = arT.bit_offset;
1351 }
1352 else
1353 { /* something went awry */
1354 return Status;
1355 }
1356
1357 if (remaining_bits_len < 0)
1358 {
1359 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1360 }
1361
1362 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001363 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001364 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001365
1366 bit_offset++;
1367 remaining_bits_len--; /* 1 bit consumed (tag) */
1368 } while (!EndOfList);
1369
1370
1371 /* Store the count of the array */
1372 *pui8DATA(data, pDescr->i) = ElementCount;
1373 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1374 pDescr++;
1375 break;
1376 }
1377
1378 case CSN_FIXED:
1379 { /* Verify the fixed bits */
1380 guint8 no_of_bits = (guint8) pDescr->i;
1381 guint32 ui32;
1382
1383 if (no_of_bits <= 32)
1384 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001385 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001386 }
1387 else
1388 {
1389 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1390 }
1391 if (ui32 != (unsigned)(gint32)pDescr->offset)
1392 {
1393 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1394 }
1395
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001396 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001397 remaining_bits_len -= no_of_bits;
1398 bit_offset += no_of_bits;
1399 pDescr++;
1400 break;
1401 }
1402
1403 case CSN_CALLBACK:
1404 {
1405 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1406 break;
1407 }
1408
1409 case CSN_TRAP_ERROR:
1410 {
1411 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1412 }
1413
1414 case CSN_END:
1415 {
1416 ar->remaining_bits_len = remaining_bits_len;
1417 ar->bit_offset = bit_offset;
1418 return remaining_bits_len;
1419 }
1420
1421 default:
1422 {
1423 assert(0);
1424 }
1425
1426
1427 }
1428
1429 } while (remaining_bits_len >= 0);
1430
1431 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1432}
1433
1434
1435
1436
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001437gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001438{
1439 gint remaining_bits_len = ar->remaining_bits_len;
1440 gint bit_offset = ar->bit_offset;
1441 guint8* pui8;
1442 guint16* pui16;
1443 guint32* pui32;
1444 guint64* pui64;
1445
1446 guint8 Tag = STANDARD_TAG;
1447
1448 if (remaining_bits_len <= 0)
1449 {
1450 return 0;
1451 }
1452
1453 do
1454 {
1455 switch (pDescr->type)
1456 {
1457 case CSN_BIT:
1458 {
1459 if (remaining_bits_len > 0)
1460 {
1461 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001462 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001463 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001464 /* end add the bit value to protocol tree */
1465 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001466 else if(pDescr->may_be_null)
1467 {
1468 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1469 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001470 else
1471 {
1472 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1473 }
1474
1475 pDescr++;
1476 remaining_bits_len--;
1477 bit_offset++;
1478 break;
1479 }
1480
1481 case CSN_NULL:
1482 { /* Empty member! */
1483 pDescr++;
1484 break;
1485 }
1486
1487 case CSN_UINT:
1488 {
1489 guint8 no_of_bits = (guint8) pDescr->i;
1490
1491 if (remaining_bits_len >= no_of_bits)
1492 {
1493 if (no_of_bits <= 8)
1494 {
1495 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001496 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001497 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001498 }
1499 else if (no_of_bits <= 16)
1500 {
1501 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001502 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001503 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001504 }
1505 else if (no_of_bits <= 32)
1506 {
1507 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001508 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001509 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001510 }
1511 else
1512 {
1513 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1514 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001515
1516 remaining_bits_len -= no_of_bits;
1517 bit_offset += no_of_bits;
1518 }
1519 else if(pDescr->may_be_null)
1520 {
1521 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001522 }
1523 else
1524 {
1525 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1526 }
1527
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001528 pDescr++;
1529 break;
1530 }
1531
1532 case CSN_UINT_OFFSET:
1533 {
1534 guint8 no_of_bits = (guint8) pDescr->i;
1535
1536 if (remaining_bits_len >= no_of_bits)
1537 {
1538 if (no_of_bits <= 8)
1539 {
1540 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001541 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001542 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001543 }
1544 else if (no_of_bits <= 16)
1545 {
1546 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001547 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001548 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001549 }
1550 else if (no_of_bits <= 32)
1551 {
1552 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001553 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001554 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001555 }
1556 else
1557 {
1558 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1559 }
1560 }
1561 else
1562 {
1563 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1564 }
1565
1566 remaining_bits_len -= no_of_bits;
1567 bit_offset += no_of_bits;
1568 pDescr++;
1569 break;
1570 }
1571
1572 case CSN_UINT_LH:
1573 {
1574 guint8 no_of_bits = (guint8) pDescr->i;
1575
1576 if (remaining_bits_len >= no_of_bits)
1577 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001578 if (no_of_bits <= 8)
1579 {
1580 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001581 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001582 // TODO : Change get_masked_bits8()
1583 writeIndex -= no_of_bits;
1584 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1585 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001586 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001587 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001588
1589 }
1590 else
1591 {/* Maybe we should support more than 8 bits ? */
1592 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1593 }
1594 }
1595 else
1596 {
1597 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1598 }
1599
1600 remaining_bits_len -= no_of_bits;
1601 bit_offset += no_of_bits;
1602 pDescr++;
1603 break;
1604 }
1605
1606 case CSN_UINT_ARRAY:
1607 {
1608 guint8 no_of_bits = (guint8) pDescr->i;
1609 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1610
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001611 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001612 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1613 nCount = *pui16DATA(data, nCount);
1614 }
1615
1616 if (remaining_bits_len >= no_of_bits)
1617 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001618 if (no_of_bits <= 8)
1619 {
1620 pui8 = pui8DATA(data, pDescr->offset);
1621 do
1622 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001623 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001624 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001625 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001626 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001627 bit_offset += no_of_bits;
1628 } while (--nCount > 0);
1629 }
1630 else if (no_of_bits <= 16)
1631 {
1632 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1633 }
1634 else if (no_of_bits <= 32)
1635 {
1636 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1637 }
1638 else
1639 {
1640 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1641 }
1642 }
1643 else
1644 {
1645 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1646 }
1647 pDescr++;
1648 break;
1649 }
1650
1651 case CSN_VARIABLE_TARRAY_OFFSET:
1652 case CSN_VARIABLE_TARRAY:
1653 case CSN_TYPE_ARRAY:
1654 {
1655 gint16 Status;
1656 csnStream_t arT = *ar;
1657 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001658 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001659
1660 pui8 = pui8DATA(data, pDescr->offset);
1661 if (pDescr->type == CSN_VARIABLE_TARRAY)
1662 { /* Count specified in field */
1663 nCount = *pui8DATA(data, pDescr->i);
1664 }
1665 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1666 { /* Count specified in field */
1667 nCount = *pui8DATA(data, pDescr->i);
1668 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1669 }
1670
1671 while (nCount > 0)
1672 { /* resulting array of length 0 is possible
1673 * but no bits shall be read from bitstream
1674 */
1675
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001676 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001677 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1678 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1679 if (Status >= 0)
1680 {
1681 pui8 += nSize;
1682 remaining_bits_len = arT.remaining_bits_len;
1683 bit_offset = arT.bit_offset;
1684
1685 }
1686 else
1687 {
1688 return Status;
1689 }
1690 nCount--;
1691 }
1692
1693 pDescr++;
1694 break;
1695 }
1696
1697 case CSN_BITMAP:
1698 { /* bitmap with given length. The result is left aligned! */
1699 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1700
1701 if (no_of_bits > 0)
1702 {
1703
1704 if (no_of_bits <= 32)
1705 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001706 for(unsigned ib = 0; ib < 4; ib++)
1707 {
1708 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001709 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001710 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001711 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001712 }
1713 else if (no_of_bits <= 64)
1714 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001715 for(unsigned ib = 0; ib < 8; ib++)
1716 {
1717 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001718 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001719 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001720 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001721 }
1722 else
1723 {
1724 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1725 }
1726
1727 remaining_bits_len -= no_of_bits;
1728 assert(remaining_bits_len >= 0);
1729 bit_offset += no_of_bits;
1730 }
1731 /* bitmap was successfully extracted or it was empty */
1732
1733 pDescr++;
1734 break;
1735 }
1736
1737 case CSN_TYPE:
1738 {
1739 gint16 Status;
1740 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001741 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001742 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1743 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001744 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001745 if (Status >= 0)
1746 {
1747
1748 remaining_bits_len = arT.remaining_bits_len;
1749 bit_offset = arT.bit_offset;
1750 pDescr++;
1751 }
1752 else
1753 {
1754 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1755 return Status;
1756 }
1757
1758 break;
1759 }
1760
1761 case CSN_CHOICE:
1762 {
1763 //gint16 count = pDescr->i;
1764 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001765 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001766
1767 pui8 = pui8DATA(data, pDescr->offset);
1768 i = *pui8;
1769 pChoice += i;
1770 guint8 no_of_bits = pChoice->bits;
1771 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001772 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001773 bitvec_write_field(vector, &writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001774
1775 CSN_DESCR descr[2];
1776 gint16 Status;
1777 csnStream_t arT = *ar;
1778
1779 descr[0] = pChoice->descr;
1780 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1781 descr[1].type = CSN_END;
1782 bit_offset += no_of_bits;
1783 remaining_bits_len -= no_of_bits;
1784
1785 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1786 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1787
1788 if (Status >= 0)
1789 {
1790 remaining_bits_len = arT.remaining_bits_len;
1791 bit_offset = arT.bit_offset;
1792 }
1793 else
1794 {
1795 return Status;
1796 }
1797
1798 pDescr++;
1799 break;
1800 }
1801
1802 case CSN_SERIALIZE:
1803 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001804 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001805 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001806 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001807 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001808 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001809
1810 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001811 lengthIndex = writeIndex;
1812 writeIndex += length_len;
1813 bit_offset += length_len;
1814 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001815 arT.direction = 0;
1816 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1817 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001818
Alexander Couzensccde5c92017-02-04 03:10:08 +01001819 bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001820 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001821
1822 if (Status >= 0)
1823 {
1824 remaining_bits_len = arT.remaining_bits_len;
1825 bit_offset = arT.bit_offset;
1826 pDescr++;
1827 }
1828 else
1829 {
1830 // Has already been processed:
1831 return Status;
1832 }
1833
1834 break;
1835 }
1836
1837 case CSN_UNION_LH:
1838 case CSN_UNION:
1839 {
1840 gint16 Bits;
1841 guint8 index;
1842 gint16 count = pDescr->i;
1843 const CSN_DESCR* pDescrNext = pDescr;
1844
1845 pDescrNext += count + 1; /* now this is next after the union */
1846 if ((count <= 0) || (count > 16))
1847 {
1848 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1849 }
1850
1851 /* Now get the bits to extract the index */
1852 Bits = ixBitsTab[count];
1853 index = 0;
1854
1855 /* Assign UnionType */
1856 pui8 = pui8DATA(data, pDescr->offset);
1857 //read index from data and write to vector
Alexander Couzensccde5c92017-02-04 03:10:08 +01001858 bitvec_write_field(vector, &writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001859
1860 //decode index
1861 writeIndex -= Bits;
1862
1863 while (Bits > 0)
1864 {
1865 index <<= 1;
1866
1867 if (CSN_UNION_LH == pDescr->type)
1868 {
1869 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1870 }
1871 else
1872 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001873 index |= bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001874 }
1875
1876 remaining_bits_len--;
1877 bit_offset++;
1878 Bits--;
1879 }
1880
1881 writeIndex -= Bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001882 bitvec_write_field(vector, &writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001883
1884
1885 /* script index to continue on, limited in case we do not have a power of 2 */
1886 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001887 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001888
1889 switch (pDescr->type)
1890 { /* get the right element of the union based on computed index */
1891
1892 case CSN_BIT:
1893 {
1894 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001895 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001896 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001897 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001898 bit_offset++;
1899 pDescr++;
1900 break;
1901 }
1902
1903 case CSN_NULL:
1904 { /* Empty member! */
1905 pDescr++;
1906 break;
1907 }
1908
1909 case CSN_UINT:
1910 {
1911 guint8 no_of_bits = (guint8) pDescr->i;
1912 if (remaining_bits_len >= no_of_bits)
1913 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001914 if (no_of_bits <= 8)
1915 {
1916 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001917 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001918 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001919 }
1920 else if (no_of_bits <= 16)
1921 {
1922 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001923 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001924 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001925 }
1926 else if (no_of_bits <= 32)
1927 {
1928 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001929 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001930 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001931 }
1932 else
1933 {
1934 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1935 }
1936 }
1937 else
1938 {
1939 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1940 }
1941
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001942 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001943 bit_offset += no_of_bits;
1944 pDescr++;
1945 break;
1946 }
1947
1948 case CSN_UINT_OFFSET:
1949 {
1950 guint8 no_of_bits = (guint8) pDescr->i;
1951
1952 if (remaining_bits_len >= no_of_bits)
1953 {
1954 if (no_of_bits <= 8)
1955 {
1956 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001957 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001958 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001959 }
1960 else if (no_of_bits <= 16)
1961 {
1962 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001963 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001964 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001965 }
1966 else if (no_of_bits <= 32)
1967 {
1968 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001969 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001970 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001971 }
1972 else
1973 {
1974 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1975 }
1976 }
1977 else
1978 {
1979 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1980 }
1981
1982 remaining_bits_len -= no_of_bits;
1983 bit_offset += no_of_bits;
1984 pDescr++;
1985 break;
1986 }
1987
1988 case CSN_UINT_LH:
1989 {
1990 guint8 no_of_bits = (guint8) pDescr->i;
1991
1992 if (remaining_bits_len >= no_of_bits)
1993 {
1994 remaining_bits_len -= no_of_bits;
1995 if (no_of_bits <= 8)
1996 {
1997 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001998 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001999 // TODO : Change get_masked_bits8()
2000 writeIndex -= no_of_bits;
2001 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
2002 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002003 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002004 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002005
2006 }
2007 else
2008 {/* Maybe we should support more than 8 bits ? */
2009 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2010 }
2011 }
2012 else
2013 {
2014 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2015 }
2016
2017 remaining_bits_len -= no_of_bits;
2018 bit_offset += no_of_bits;
2019 pDescr++;
2020 break;
2021 }
2022
2023 case CSN_UINT_ARRAY:
2024 {
2025 guint8 no_of_bits = (guint8) pDescr->i;
2026 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2027
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002028 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002029 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2030 nCount = *pui16DATA(data, nCount);
2031 }
2032
2033 if (remaining_bits_len >= no_of_bits)
2034 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002035 if (no_of_bits <= 8)
2036 {
2037 pui8 = pui8DATA(data, pDescr->offset);
2038 do
2039 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002040 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002041 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002042 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002043 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002044 bit_offset += no_of_bits;
2045 } while (--nCount > 0);
2046 }
2047 else if (no_of_bits <= 16)
2048 {
2049 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2050 }
2051 else if (no_of_bits <= 32)
2052 {
2053 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2054 }
2055 else
2056 {
2057 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2058 }
2059 }
2060 else
2061 {
2062 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2063 }
2064 pDescr++;
2065 break;
2066 }
2067
2068 case CSN_VARIABLE_TARRAY_OFFSET:
2069 case CSN_VARIABLE_TARRAY:
2070 case CSN_TYPE_ARRAY:
2071 {
2072 gint16 Status;
2073 csnStream_t arT = *ar;
2074 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002075 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002076
2077 pui8 = pui8DATA(data, pDescr->offset);
2078 if (pDescr->type == CSN_VARIABLE_TARRAY)
2079 { /* Count specified in field */
2080 nCount = *pui8DATA(data, pDescr->i);
2081 }
2082 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2083 { /* Count specified in field */
2084 nCount = *pui8DATA(data, pDescr->i);
2085 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2086 }
2087
2088 while (nCount > 0)
2089 { /* resulting array of length 0 is possible
2090 * but no bits shall be read from bitstream
2091 */
2092
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002093 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002094 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2095 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2096 if (Status >= 0)
2097 {
2098 pui8 += nSize;
2099 remaining_bits_len = arT.remaining_bits_len;
2100 bit_offset = arT.bit_offset;
2101 }
2102 else
2103 {
2104 return Status;
2105 }
2106 nCount--;
2107 }
2108
2109 pDescr++;
2110 break;
2111 }
2112
2113 case CSN_BITMAP:
2114 { /* bitmap with given length. The result is left aligned! */
2115 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2116
2117 if (no_of_bits > 0)
2118 {
2119
2120 if (no_of_bits <= 32)
2121 {
2122 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002123 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002124 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002125 }
2126 else if (no_of_bits <= 64)
2127 {
2128 pui64 = pui64DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002129 bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002130 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002131 }
2132 else
2133 {
2134 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2135 }
2136
2137 remaining_bits_len -= no_of_bits;
2138 assert(remaining_bits_len >= 0);
2139 bit_offset += no_of_bits;
2140 }
2141 /* bitmap was successfully extracted or it was empty */
2142
2143 pDescr++;
2144 break;
2145 }
2146
2147 case CSN_TYPE:
2148 {
2149 gint16 Status;
2150 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002151 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002152 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2153 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002154 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002155 if (Status >= 0)
2156 {
2157 remaining_bits_len = arT.remaining_bits_len;
2158 bit_offset = arT.bit_offset;
2159 pDescr++;
2160 }
2161 else
2162 {
2163 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2164 return Status;
2165 }
2166
2167 break;
2168 }
2169
2170 default:
2171 { /* descriptions of union elements other than above are illegal */
2172 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2173 }
2174 }
2175
2176 pDescr = pDescrNext;
2177 break;
2178 }
2179
2180 case CSN_EXIST:
2181 case CSN_EXIST_LH:
2182 {
2183 guint8 fExist;
2184 unsigned exist = 0;
2185 pui8 = pui8DATA(data, pDescr->offset);
2186 exist = *pui8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002187 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002188 writeIndex--;
2189 if (CSN_EXIST_LH == pDescr->type)
2190 {
2191 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2192 }
2193 else
2194 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002195 fExist = bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002196 }
2197 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002198 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002199 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002200 remaining_bits_len--;
2201 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002202 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002203
2204 if (!exist)
2205 {
2206 ar->remaining_bits_len = remaining_bits_len;
2207 ar->bit_offset = bit_offset;
2208 return remaining_bits_len;
2209 }
2210 break;
2211 }
2212
2213 case CSN_NEXT_EXIST:
2214 {
2215 guint8 fExist;
2216
2217 pui8 = pui8DATA(data, pDescr->offset);
2218
2219 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002220 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002221 { /* no more bits to decode is fine here - end of message detected and allowed */
2222
2223 /* Skip i entries + this entry */
2224 pDescr += pDescr->i + 1;
2225
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002226 break;
2227 }
2228
Alexander Couzensccde5c92017-02-04 03:10:08 +01002229 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002230 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002231 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002232
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002233 remaining_bits_len--;
2234 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002235
2236 if (fExist == 0)
2237 { /* Skip 'i' entries */
2238 pDescr += pDescr->i;
2239 }
2240
2241 pDescr++;
2242 break;
2243 }
2244
2245 case CSN_NEXT_EXIST_LH:
2246 {
2247 guint8 fExist;
2248 pui8 = pui8DATA(data, pDescr->offset);
2249
2250 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2251 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2252 { /* no more bits to decode is fine here - end of message detected and allowed */
2253
2254 /* skip 'i' entries + this entry */
2255 pDescr += pDescr->i + 1;
2256
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002257 /* set the data member to "not exist" */
2258 //*pui8 = 0;
2259 break;
2260 }
2261
2262 /* the "regular" M_NEXT_EXIST_LH description element */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002263 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002264 writeIndex--;
2265 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2266 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002267 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002268 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002269
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002270 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002271 bit_offset++;
2272
2273 if (fExist == 0)
2274 { /* Skip 'i' entries */
2275 pDescr += pDescr->i;
2276 }
2277 pDescr++;
2278
2279 break;
2280 }
2281
2282 case CSN_VARIABLE_BITMAP_1:
2283 { /* Bitmap from here and to the end of message */
2284
2285 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2286
2287 /*no break -
2288 * with a length set we have a regular variable length bitmap so we continue */
2289 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002290 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002291 case CSN_VARIABLE_BITMAP:
2292 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2293 * <N: bit (5)> <bitmap: bit(N + offset)>
2294 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2295 * The result is right aligned!
2296 */
2297 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2298
2299 no_of_bits += pDescr->i; /* adjusted by offset */
2300
2301 if (no_of_bits > 0)
2302 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002303
2304 if (remaining_bits_len < 0)
2305 {
2306 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2307 }
2308
2309 { /* extract bits */
2310 guint8* pui8 = pui8DATA(data, pDescr->offset);
2311 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2312
2313 if (nB1 > 0)
2314 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002315 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002316 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002317 pui8++;
2318 no_of_bits -= nB1;
2319 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002320 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002321 }
2322
2323 /* remaining no_of_bits is a multiple of 8 or 0 */
2324 while (no_of_bits > 0)
2325 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002326 bitvec_write_field(vector, &writeIndex, *pui8, 8);
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 -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002330 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002331 }
2332 }
2333 }
2334 pDescr++;
2335 break;
2336 }
2337
2338 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2339 { /* Bitmap from here and to the end of message */
2340
2341 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2342
2343 /* no break -
2344 * with a length set we have a regular left aligned variable length bitmap so we continue
2345 */
2346 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002347 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002348 case CSN_LEFT_ALIGNED_VAR_BMP:
2349 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2350 * <N: bit (5)> <bitmap: bit(N + offset)>
2351 * bit array with length (in bits) specified in parameter (pDescr->descr)
2352 */
2353
2354 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2355
2356 no_of_bits += pDescr->i;/* size adjusted by offset */
2357
2358 if (no_of_bits > 0)
2359 {
2360 remaining_bits_len -= no_of_bits;
2361
2362 if (remaining_bits_len < 0)
2363 {
2364 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2365 }
2366
2367 { /* extract bits */
2368 guint8* pui8 = pui8DATA(data, pDescr->offset);
2369 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2370
2371 while (no_of_bits > 0)
2372 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002373 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002374 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002375 pui8++;
2376 no_of_bits -= 8;
2377 }
2378 if (nB1 > 0)
2379 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002380 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002381 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002382 pui8++;
2383 no_of_bits -= nB1;
2384 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2385 }
2386 }
2387
2388 }
2389
2390 /* bitmap was successfully extracted or it was empty */
2391 pDescr++;
2392 break;
2393 }
2394
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002395 case CSN_PADDING_BITS:
2396 { /* Padding from here and to the end of message */
2397 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2398 guint8 filler = 0x2b;
2399 if (remaining_bits_len > 0)
2400 {
2401 while (remaining_bits_len > 0)
2402 {
2403 guint8 bits_to_handle = remaining_bits_len%8;
2404 if (bits_to_handle > 0)
2405 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302406 /* section 11 of 44.060
2407 * The padding bits may be the 'null' string. Otherwise, the
2408 * padding bits starts with bit '0', followed by 'spare padding'
2409 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2410 */
2411 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Alexander Couzensccde5c92017-02-04 03:10:08 +01002412 bitvec_write_field(vector, &writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002413 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2414 remaining_bits_len -= bits_to_handle;
2415 bit_offset += bits_to_handle;
2416 }
2417 else if (bits_to_handle == 0)
2418 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002419 bitvec_write_field(vector, &writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002420 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2421 remaining_bits_len -= 8;
2422 bit_offset += 8;
2423 }
2424 }
2425 }
2426 if (remaining_bits_len < 0)
2427 {
2428 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2429 }
2430
2431 /* Padding was successfully extracted or it was empty */
2432 pDescr++;
2433 break;
2434 }
2435
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002436 case CSN_VARIABLE_ARRAY:
2437 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2438 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2439 * Array with length specified in parameter:
2440 * <count: bit (x)>
2441 * <list: octet(count + offset)>
2442 */
2443 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2444
2445 count += pDescr->i; /* Adjusted by offset */
2446
2447 if (count > 0)
2448 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002449 if (remaining_bits_len < 0)
2450 {
2451 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2452 }
2453
2454 pui8 = pui8DATA(data, pDescr->offset);
2455
2456 while (count > 0)
2457 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002458 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002459 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002460 pui8++;
2461 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002462 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002463 count--;
2464 }
2465 }
2466
2467 pDescr++;
2468 break;
2469 }
2470
2471 case CSN_RECURSIVE_ARRAY:
2472 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2473 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2474 * where <element> ::= bit(value)
2475 * <tag> ::= 0 | 1
2476 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2477 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2478 * REMARK: recursive way to specify an array but an iterative implementation!
2479 */
2480 gint16 no_of_bits = pDescr->i;
2481 guint8 ElementCount = 0;
2482 pui8 = pui8DATA(data, pDescr->offset);
2483 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2484 while (ElementCount > 0)
2485 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002486 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002487 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002488 bit_offset++;
2489 remaining_bits_len--;
2490
2491 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002492 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002493 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002494 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002495 ElementCount--;
2496
2497 if (remaining_bits_len < 0)
2498 {
2499 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2500 }
2501
2502 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002503 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002504 }
2505
Alexander Couzensccde5c92017-02-04 03:10:08 +01002506 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002507 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002508 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302509 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002510
2511 pDescr++;
2512 break;
2513 }
2514
2515 case CSN_RECURSIVE_TARRAY:
2516 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2517 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2518 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2519 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002520 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002521 guint8 ElementCount = 0;
2522 pui8 = pui8DATA(data, pDescr->offset);
2523 /* Store the counted number of elements of the array */
2524 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2525
2526 while (ElementCount > 0)
2527 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002528 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002529 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002530 bit_offset++;
2531
2532 remaining_bits_len--;
2533 ElementCount--;
2534
2535 { /* unpack the following data structure */
2536 csnStream_t arT = *ar;
2537 gint16 Status;
2538 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002539 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002540
2541 if (Status >= 0)
2542 { /* successful completion */
2543 pui8 += nSizeElement; /* -> to next data element */
2544 remaining_bits_len = arT.remaining_bits_len;
2545 bit_offset = arT.bit_offset;
2546 }
2547 else
2548 { /* something went awry */
2549 return Status;
2550 }
2551 }
2552
2553 if (remaining_bits_len < 0)
2554 {
2555 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2556 }
2557 }
2558
Alexander Couzensccde5c92017-02-04 03:10:08 +01002559 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002560 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002561 bit_offset++;
2562
2563 pDescr++;
2564 break;
2565 }
2566
2567 case CSN_RECURSIVE_TARRAY_2:
2568 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2569
2570 Tag = REVERSED_TAG;
2571
2572 /* NO break -
2573 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2574 */
2575 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002576 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002577 case CSN_RECURSIVE_TARRAY_1:
2578 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2579 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2580 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2581 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002582 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002583 guint8 ElementCount = 0;
2584 guint8 ElementNum = 0;
2585 csnStream_t arT = *ar;
2586 gint16 Status;
2587
2588 pui8 = pui8DATA(data, pDescr->offset);
2589 /* Store the count of the array */
2590 ElementCount = *pui8DATA(data, pDescr->i);
2591 ElementNum = ElementCount;
2592
2593 while (ElementCount > 0)
2594 { /* get data element */
2595 if (ElementCount != ElementNum)
2596 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002597 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002598 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002599 bit_offset++;
2600 remaining_bits_len--;
2601 }
2602 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002603 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002604 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002605 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002606 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002607 if (Status >= 0)
2608 { /* successful completion */
2609 pui8 += nSizeElement; /* -> to next */
2610 remaining_bits_len = arT.remaining_bits_len;
2611 bit_offset = arT.bit_offset;
2612 }
2613 else
2614 { /* something went awry */
2615 return Status;
2616 }
2617
2618 if (remaining_bits_len < 0)
2619 {
2620 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2621 }
2622
2623 }
Alexander Couzensccde5c92017-02-04 03:10:08 +01002624 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002625 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002626 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002627 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2628 pDescr++;
2629 break;
2630 }
2631
2632 case CSN_FIXED:
2633 { /* Verify the fixed bits */
2634 guint8 no_of_bits = (guint8) pDescr->i;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002635 bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002636 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002637 remaining_bits_len -= no_of_bits;
2638 bit_offset += no_of_bits;
2639 pDescr++;
2640 break;
2641 }
2642
2643 case CSN_CALLBACK:
2644 {
2645 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2646 break;
2647 }
2648
2649 case CSN_TRAP_ERROR:
2650 {
2651 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2652 }
2653
2654 case CSN_END:
2655 {
2656 ar->remaining_bits_len = remaining_bits_len;
2657 ar->bit_offset = bit_offset;
2658 return remaining_bits_len;
2659 }
2660
2661 default:
2662 {
2663 assert(0);
2664 }
2665
2666 }
2667
2668 } while (remaining_bits_len >= 0);
2669
2670 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2671}
2672