blob: 700c342a1f8c464a2883bb86839b139767597b3d [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040031#include <assert.h>
32#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020033#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
Pau Espin Pedrold636f742020-02-03 15:37:08 +010038#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030040
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030050static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
51
52
53/* Returns no_of_bits (up to 8) masked with 0x2B */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030054static guint8
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070055get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030056{
57 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
58 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
59 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
60 guint8 result;
61 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070062 *readIndex -= relative_bit_offset;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030063 if (bit_shift >= 0)
64 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070065 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
66 *readIndex-= bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030067 result &= maskBits[no_of_bits];
68 }
69 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010070 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070071 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030072 hight_part = (guint8) (hight_part << (-bit_shift));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070073 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
74 *readIndex = *readIndex - (8 - (-bit_shift));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030075 result |= hight_part;
76 }
77 return result;
78}
79
80/**
81 * ================================================================================================
82 * set initial/start values in help data structure used for packing/unpacking operation
83 * ================================================================================================
84 */
85void
86csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
87{
88 ar->remaining_bits_len = remaining_bits_len;
89 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040090 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030091}
92
Pau Espin Pedrold636f742020-02-03 15:37:08 +010093static const struct value_string csn1_error_names[] = {
94 { CSN_OK, "General 0" },
95 { CSN_ERROR_GENERAL, "General -1" },
96 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
97 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
98 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
99 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
Vadim Yanitskiyfee767f2020-02-11 05:28:02 +0700100 { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" },
101 { CSN_ERROR_INTERNAL, "INTERNAL" },
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100102 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
103 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
104 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300105};
106
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100107
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700108static gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100109 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300110{
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100111 /* Don't add trailing newline, top caller is responsible for appending it */
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100112 if (err != CSN_OK)
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700113 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %u)",
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100114 sz, get_value_string(csn1_error_names, err), err,
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700115 pDescr ? pDescr->sz : "-", *readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116 return err;
117}
118
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100119#define ProcessError(readIndex, sz, err, pDescr) \
120 ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
121
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300122
123/**
124 * ================================================================================================
125 * Return TRUE if tag in bit stream indicates existence of next list element,
126 * otherwise return FALSE.
127 * Will work for tag values equal to both 0 and 1.
128 * ================================================================================================
129 */
130
131static gboolean
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700132existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300133{
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700134 int res = bitvec_get_bit_pos(vector, (*readIndex)++);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300135 if (Tag == STANDARD_TAG)
136 {
137 return (res > 0);
138 }
139 return (res == 0);
140}
141
142
143gint16
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700144csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300145{
146 gint remaining_bits_len = ar->remaining_bits_len;
147 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100148 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300149 guint16* pui16;
150 guint32* pui32;
151 guint64* pui64;
152 guint8 Tag = STANDARD_TAG;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700153 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300154
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700155 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300156 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700157 return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300158 }
159
160 do
161 {
162 switch (pDescr->type)
163 {
164 case CSN_BIT:
165 {
166 if (remaining_bits_len > 0)
167 {
168 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700169 *pui8 = bitvec_read_field(vector, readIndex, 1);
Harald Welte570f9132020-03-19 15:03:01 +0100170 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300171 /* end add the bit value to protocol tree */
172 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400173 else if(pDescr->may_be_null)
174 {
175 pui8 = pui8DATA(data, pDescr->offset);
176 *pui8 = 0;
Harald Welte570f9132020-03-19 15:03:01 +0100177 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400178 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300179 else
180 {
181 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
182 }
183
184 pDescr++;
185 remaining_bits_len--;
186 bit_offset++;
187 break;
188 }
189
190 case CSN_NULL:
191 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100192 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300193 pDescr++;
194 break;
195 }
196
197 case CSN_UINT:
198 {
199 guint8 no_of_bits = (guint8) pDescr->i;
200
201 if (remaining_bits_len >= no_of_bits)
202 {
203 if (no_of_bits <= 8)
204 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700205 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300206 pui8 = pui8DATA(data, pDescr->offset);
207 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100208 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300209 }
210 else if (no_of_bits <= 16)
211 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700212 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300213 pui16 = pui16DATA(data, pDescr->offset);
214 *pui16 = ui16;
Harald Welte570f9132020-03-19 15:03:01 +0100215 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300216 }
217 else if (no_of_bits <= 32)
218 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700219 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300220 pui32 = pui32DATA(data, pDescr->offset);
221 *pui32 = ui32;
Harald Welte570f9132020-03-19 15:03:01 +0100222 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300223 }
224 else
225 {
226 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
227 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400228 remaining_bits_len -= no_of_bits;
229 bit_offset += no_of_bits;
230 }
231 else if(pDescr->may_be_null)
232 {
233 if (no_of_bits <= 8)
234 {
235 pui8 = pui8DATA(data, pDescr->offset);
236 *pui8 = 0;
237 }
238 else if (no_of_bits <= 16)
239 {
240 pui16 = pui16DATA(data, pDescr->offset);
241 *pui16 = 0;
242 }
243 else if (no_of_bits <= 32)
244 {
245 pui32 = pui32DATA(data, pDescr->offset);
246 *pui32 = 0;
247 }
Harald Welte570f9132020-03-19 15:03:01 +0100248 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300249 }
250 else
251 {
252 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
253 }
254
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300255 pDescr++;
256 break;
257 }
258
259 case CSN_UINT_OFFSET:
260 {
261 guint8 no_of_bits = (guint8) pDescr->i;
262
263 if (remaining_bits_len >= no_of_bits)
264 {
265 if (no_of_bits <= 8)
266 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700267 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300268 pui8 = pui8DATA(data, pDescr->offset);
269 *pui8 = ui8 + (guint8)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100270 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300271 }
272 else if (no_of_bits <= 16)
273 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700274 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300275 pui16 = pui16DATA(data, pDescr->offset);
276 *pui16 = ui16 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100277 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300278 }
279 else if (no_of_bits <= 32)
280 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700281 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300282 pui32 = pui32DATA(data, pDescr->offset);
283 *pui32 = ui32 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100284 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300285 }
286 else
287 {
288 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
289 }
290 }
291 else
292 {
293 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
294 }
295
296 remaining_bits_len -= no_of_bits;
297 bit_offset += no_of_bits;
298 pDescr++;
299 break;
300 }
301
302 case CSN_UINT_LH:
303 {
304 guint8 no_of_bits = (guint8) pDescr->i;
305
306 if (remaining_bits_len >= no_of_bits)
307 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300308 if (no_of_bits <= 8)
309 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100310 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300311 pui8 = pui8DATA(data, pDescr->offset);
312 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100313 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300314 }
315 else
316 {/* Maybe we should support more than 8 bits ? */
317 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
318 }
319 }
320 else
321 {
322 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
323 }
324
325 remaining_bits_len -= no_of_bits;
326 bit_offset += no_of_bits;
327 pDescr++;
328 break;
329 }
330
331 case CSN_UINT_ARRAY:
332 {
333 guint8 no_of_bits = (guint8) pDescr->i;
334 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
335
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100336 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300337 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
338 nCount = *pui16DATA(data, nCount);
339 }
340
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +0100341 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300342 {
343 remaining_bits_len -= (no_of_bits*nCount);
344 if (no_of_bits <= 8)
345 {
346 pui8 = pui8DATA(data, pDescr->offset);
347 do
348 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700349 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100350 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300351 pui8++;
352 bit_offset += no_of_bits;
353 } while (--nCount > 0);
354 }
355 else if (no_of_bits <= 16)
356 {
357 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
358 }
359 else if (no_of_bits <= 32)
360 {
361 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
362 }
363 else
364 {
365 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
366 }
367 }
368 else
369 {
370 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
371 }
372 pDescr++;
373 break;
374 }
375
376 case CSN_VARIABLE_TARRAY_OFFSET:
377 case CSN_VARIABLE_TARRAY:
378 case CSN_TYPE_ARRAY:
379 {
380 gint16 Status;
381 csnStream_t arT = *ar;
382 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100383 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300384
385 pui8 = pui8DATA(data, pDescr->offset);
386 if (pDescr->type == CSN_VARIABLE_TARRAY)
387 { /* Count specified in field */
388 nCount = *pui8DATA(data, pDescr->i);
389 }
390 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
391 { /* Count specified in field */
392 nCount = *pui8DATA(data, pDescr->i);
393 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
394 }
395
396 while (nCount > 0)
397 { /* resulting array of length 0 is possible
398 * but no bits shall be read from bitstream
399 */
400
Harald Welte570f9132020-03-19 15:03:01 +0100401 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300402 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100403 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300404 if (Status >= 0)
405 {
406 pui8 += nSize;
407 remaining_bits_len = arT.remaining_bits_len;
408 bit_offset = arT.bit_offset;
409 }
410 else
411 {
412 return Status;
413 }
414 nCount--;
415 }
416
417 pDescr++;
418 break;
419 }
420
421 case CSN_BITMAP:
422 { /* bitmap with given length. The result is left aligned! */
423 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
424
425 if (no_of_bits > 0)
426 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +0100427 if (no_of_bits > remaining_bits_len)
428 {
429 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
430 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300431
432 if (no_of_bits <= 32)
433 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700434 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400435 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700436 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 pui8 = pui8DATA(data, pDescr->offset+ib);
438 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100439 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400440 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300441 }
442 else if (no_of_bits <= 64)
443 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700444 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400445 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700446 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 pui8 = pui8DATA(data, pDescr->offset+ib);
448 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100449 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400450 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300451 }
452 else
453 {
454 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
455 }
456
457 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300458 bit_offset += no_of_bits;
459 }
460 /* bitmap was successfully extracted or it was empty */
461
462 pDescr++;
463 break;
464 }
465
466 case CSN_TYPE:
467 {
468 gint16 Status;
469 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +0100470 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300471 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100472 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +0100473 LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300474 if (Status >= 0)
475 {
476 remaining_bits_len = arT.remaining_bits_len;
477 bit_offset = arT.bit_offset;
478 pDescr++;
479 }
480 else
481 {
482 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
483 return Status;
484 }
485
486 break;
487 }
488
489 case CSN_CHOICE:
490 {
491 gint16 count = pDescr->i;
492 guint8 i = 0;
493 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
494
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700495 /* Make sure that the list of choice items is not empty */
496 if (!count)
497 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
Vadim Yanitskiyc9915662020-05-23 17:24:37 +0700498 else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
499 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700500
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300501 while (count > 0)
502 {
503 guint8 no_of_bits = pChoice->bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700504 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300505 if (value == pChoice->value)
506 {
507 CSN_DESCR descr[2];
508 gint16 Status;
509 csnStream_t arT = *ar;
510
511 descr[0] = pChoice->descr;
512 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
513 descr[1].type = CSN_END;
514 pui8 = pui8DATA(data, pDescr->offset);
515 *pui8 = i;
Harald Welte570f9132020-03-19 15:03:01 +0100516 LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100517 if (!pChoice->keep_bits) {
518 bit_offset += no_of_bits;
519 remaining_bits_len -= no_of_bits;
520 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300521
522 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100523 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300524
525 if (Status >= 0)
526 {
527 remaining_bits_len = arT.remaining_bits_len;
528 bit_offset = arT.bit_offset;
529 }
530 else
531 {
532 return Status;
533 }
534 break;
535 }
536
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700537 *readIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300538 count--;
539 pChoice++;
540 i++;
541 }
542
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700543 /* Neither of the choice items matched => unknown value */
544 if (!count)
545 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
546
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300547 pDescr++;
548 break;
549 }
550
551 case CSN_SERIALIZE:
552 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100553 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300554 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400555 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300556 gint16 Status = -1;
557
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700558 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300559
Harald Welte570f9132020-03-19 15:03:01 +0100560 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400561 bit_offset += length_len;
562 remaining_bits_len -= length_len;
563
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100564 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100565 arT.direction = 1;
Harald Welte570f9132020-03-19 15:03:01 +0100566 LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100567 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300568
569 if (Status >= 0)
570 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100571 if (length > 0) {
572 remaining_bits_len -= length;
573 bit_offset += length;
574 } else {
575 remaining_bits_len = arT.remaining_bits_len;
576 bit_offset = arT.bit_offset;
577 }
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700578
579 /* Skip bits not handled by serialize(), if any */
580 if (Status > 0) {
Harald Welte570f9132020-03-19 15:03:01 +0100581 LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700582 *readIndex += Status;
583 }
584
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300585 pDescr++;
586 }
587 else
588 {
589 /* Has already been processed: */
590 return Status;
591 }
592
593 break;
594 }
595
596 case CSN_UNION_LH:
597 case CSN_UNION:
598 {
599 gint16 Bits;
600 guint8 index;
601 gint16 count = pDescr->i;
602 const CSN_DESCR* pDescrNext = pDescr;
603
604 pDescrNext += count + 1; /* now this is next after the union */
605 if ((count <= 0) || (count > 16))
606 {
607 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
608 }
609
610 /* Now get the bits to extract the index */
611 Bits = ixBitsTab[count];
612 index = 0;
613
614 while (Bits > 0)
615 {
616 index <<= 1;
617
618 if (CSN_UNION_LH == pDescr->type)
619 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700620 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621 }
622 else
623 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700624 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300625 }
626 remaining_bits_len--;
627 bit_offset++;
628 Bits--;
629 }
630
631 /* Assign UnionType */
632 pui8 = pui8DATA(data, pDescr->offset);
633 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100634
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300635
636 /* script index to continue on, limited in case we do not have a power of 2 */
637 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +0100638 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300639
640 switch (pDescr->type)
641 { /* get the right element of the union based on computed index */
642
643 case CSN_BIT:
644 {
645 pui8 = pui8DATA(data, pDescr->offset);
646 *pui8 = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700647 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300648 {
649 *pui8 = 0x01;
650 }
Harald Welte570f9132020-03-19 15:03:01 +0100651 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300652 remaining_bits_len -= 1;
653 bit_offset++;
654 pDescr++;
655 break;
656 }
657
658 case CSN_NULL:
659 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100660 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300661 pDescr++;
662 break;
663 }
664
665 case CSN_UINT:
666 {
667 guint8 no_of_bits = (guint8) pDescr->i;
668 if (remaining_bits_len >= no_of_bits)
669 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300670 if (no_of_bits <= 8)
671 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700672 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300673 pui8 = pui8DATA(data, pDescr->offset);
674 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100675 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300676 }
677 else if (no_of_bits <= 16)
678 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700679 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300680 pui16 = pui16DATA(data, pDescr->offset);
681 *pui16 = ui16;
Harald Welte570f9132020-03-19 15:03:01 +0100682 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300683 }
684 else if (no_of_bits <= 32)
685 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700686 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300687 pui32 = pui32DATA(data, pDescr->offset);
688 *pui32 = ui32;
Harald Welte570f9132020-03-19 15:03:01 +0100689 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300690 }
691 else
692 {
693 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
694 }
695 }
696 else
697 {
698 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
699 }
700
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700701 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300702 bit_offset += no_of_bits;
703 pDescr++;
704 break;
705 }
706
707 case CSN_UINT_OFFSET:
708 {
709 guint8 no_of_bits = (guint8) pDescr->i;
710
711 if (remaining_bits_len >= no_of_bits)
712 {
713 if (no_of_bits <= 8)
714 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700715 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300716 pui8 = pui8DATA(data, pDescr->offset);
717 *pui8 = ui8 + (guint8)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100718 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300719 }
720 else if (no_of_bits <= 16)
721 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700722 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300723 pui16 = pui16DATA(data, pDescr->offset);
724 *pui16 = ui16 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100725 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300726 }
727 else if (no_of_bits <= 32)
728 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700729 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300730 pui32 = pui32DATA(data, pDescr->offset);
731 *pui32 = ui32 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100732 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300733 }
734 else
735 {
736 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
737 }
738 }
739 else
740 {
741 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
742 }
743
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700744 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300745 bit_offset += no_of_bits;
746 pDescr++;
747 break;
748 }
749
750 case CSN_UINT_LH:
751 {
752 guint8 no_of_bits = (guint8) pDescr->i;
753
754 if (remaining_bits_len >= no_of_bits)
755 {
756 if (no_of_bits <= 8)
757 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100758 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300759 pui8 = pui8DATA(data, pDescr->offset);
760 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100761 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300762 }
763 else
764 { /* Maybe we should support more than 8 bits ? */
765 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
766 }
767 }
768 else
769 {
770 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
771 }
772
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700773 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300774 bit_offset += no_of_bits;
775 pDescr++;
776 break;
777 }
778
779 case CSN_UINT_ARRAY:
780 {
781 guint8 no_of_bits = (guint8) pDescr->i;
782 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
783
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100784 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300785 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
786 nCount = *pui16DATA(data, nCount);
787 }
788
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +0100789 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300790 {
791 remaining_bits_len -= (no_of_bits * nCount);
792 if (no_of_bits <= 8)
793 {
794 pui8 = pui8DATA(data, pDescr->offset);
795
796 while (nCount > 0)
797 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700798 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100799 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300800 pui8++;
801 bit_offset += no_of_bits;
802 nCount--;
803 }
804 }
805 else if (no_of_bits <= 16)
806 {
807 pui16 = pui16DATA(data, pDescr->offset);
808
809 while (nCount > 0)
810 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700811 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100812 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300813 pui16++;
814 bit_offset += no_of_bits;
815 nCount--;
816 }
817 }
818 else if (no_of_bits <= 32)
819 { /* not supported */
820 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
821 }
822 else
823 {
824 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
825 }
826 }
827 else
828 {
829 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
830 }
831
832 pDescr++;
833 break;
834 }
835
836 case CSN_VARIABLE_TARRAY_OFFSET:
837 case CSN_VARIABLE_TARRAY:
838 case CSN_TYPE_ARRAY:
839 {
840 gint16 Status;
841 csnStream_t arT = *ar;
842 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100843 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300844
845 pui8 = pui8DATA(data, pDescr->offset);
846
847 if (CSN_VARIABLE_TARRAY == pDescr->type)
848 { /* Count specified in field */
849 nCount = *pui8DATA(data, pDescr->i);
850 }
851 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
852 { /* Count specified in field */
853 nCount = *pui8DATA(data, pDescr->i);
854 nCount--; /* Offset 1 */
855 }
856
857 while (nCount--) /* Changed to handle length = 0. */
858 {
Harald Welte570f9132020-03-19 15:03:01 +0100859 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300860 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100861 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300862 if (Status >= 0)
863 {
864 pui8 += nSize;
865 remaining_bits_len = arT.remaining_bits_len;
866 bit_offset = arT.bit_offset;
867 }
868 else
869 {
870 return Status;
871 }
872 }
873
874 pDescr++;
875 break;
876 }
877
878 case CSN_BITMAP:
879 { /* bitmap with given length. The result is left aligned! */
880 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
881
882 if (no_of_bits > 0)
883 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +0100884 if (no_of_bits > remaining_bits_len)
885 {
886 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
887 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300888
889 if (no_of_bits <= 32)
890 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700891 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300892 pui32 = pui32DATA(data, pDescr->offset);
893 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300894 }
895 else if (no_of_bits <= 64)
896 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700897 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300898 pui64 = pui64DATA(data, pDescr->offset);
899 *pui64 = ui64;
Harald Welte570f9132020-03-19 15:03:01 +0100900 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300901 }
902 else
903 {
904 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
905 }
906
907 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300908 bit_offset += no_of_bits;
909 }
910 /* bitmap was successfully extracted or it was empty */
911
912 pDescr++;
913 break;
914 }
915
916 case CSN_TYPE:
917 {
918 gint16 Status;
919 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +0100920 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300921 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100922 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +0100923 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300924 if (Status >= 0)
925 {
926 remaining_bits_len = arT.remaining_bits_len;
927 bit_offset = arT.bit_offset;
928 pDescr++;
929 }
930 else
931 { /* return error code Has already been processed: */
932 return Status;
933 }
934
935 break;
936 }
937
938 default:
939 { /* descriptions of union elements other than above are illegal */
940 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
941 }
942 }
943
944 pDescr = pDescrNext;
945 break;
946 }
947
948 case CSN_EXIST:
949 case CSN_EXIST_LH:
950 {
951 guint8 fExist;
952
953 pui8 = pui8DATA(data, pDescr->offset);
954
955 if (CSN_EXIST_LH == pDescr->type)
956 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100957 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300958 }
959 else
960 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700961 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300962 }
963
964 *pui8 = fExist;
Harald Welte570f9132020-03-19 15:03:01 +0100965 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300966 pDescr++;
Vadim Yanitskiyd8e5e8b2020-02-17 18:16:20 +0700967 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300968 remaining_bits_len -= 1;
969
970 if (!fExist)
971 {
972 ar->remaining_bits_len = remaining_bits_len;
973 ar->bit_offset = bit_offset;
974 return remaining_bits_len;
975 }
976
977 break;
978 }
979
980 case CSN_NEXT_EXIST:
981 {
982 guint8 fExist;
983
984 pui8 = pui8DATA(data, pDescr->offset);
985
986 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400987 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300988 { /* no more bits to decode is fine here - end of message detected and allowed */
989
990 /* Skip i entries + this entry */
991 pDescr += pDescr->i + 1;
992
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300993 /* Set the data member to "not exist" */
994 *pui8 = 0;
995 break;
996 }
997
998 /* the "regular" M_NEXT_EXIST description element */
999
1000 fExist = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001001 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001002 {
1003 fExist = 0x01;
1004 }
1005
1006 *pui8 = fExist;
1007 remaining_bits_len -= 1;
Harald Welte570f9132020-03-19 15:03:01 +01001008 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001009 ++bit_offset;
1010
1011 if (fExist == 0)
1012 { /* Skip 'i' entries */
1013 pDescr += pDescr->i;
1014 }
1015
1016 pDescr++;
1017 break;
1018 }
1019
1020 case CSN_NEXT_EXIST_LH:
1021 {
1022 guint8 fExist;
1023 pui8 = pui8DATA(data, pDescr->offset);
1024
1025 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1026 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1027 { /* no more bits to decode is fine here - end of message detected and allowed */
1028
1029 /* skip 'i' entries + this entry */
1030 pDescr += pDescr->i + 1;
1031
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001032 /* set the data member to "not exist" */
1033 *pui8 = 0;
1034 break;
1035 }
1036
1037 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001038 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001039 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001040 *pui8++ = fExist;
1041 remaining_bits_len -= 1;
1042
1043 bit_offset++;
1044
1045 if (fExist == 0)
1046 { /* Skip 'i' entries */
1047 pDescr += pDescr->i;
1048 }
1049 pDescr++;
1050
1051 break;
1052 }
1053
1054 case CSN_VARIABLE_BITMAP_1:
1055 { /* Bitmap from here and to the end of message */
1056
1057 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1058
1059 /*no break -
1060 * with a length set we have a regular variable length bitmap so we continue */
1061 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001062 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001063 case CSN_VARIABLE_BITMAP:
1064 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1065 * <N: bit (5)> <bitmap: bit(N + offset)>
1066 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1067 * The result is right aligned!
1068 */
1069 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1070
1071 no_of_bits += pDescr->i; /* adjusted by offset */
1072
1073 if (no_of_bits > 0)
1074 {
1075 remaining_bits_len -= no_of_bits;
1076
1077 if (remaining_bits_len < 0)
1078 {
1079 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1080 }
1081
1082 { /* extract bits */
1083 guint8* pui8 = pui8DATA(data, pDescr->offset);
1084 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1085
1086 if (nB1 > 0)
1087 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001088 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01001089 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001090 pui8++;
1091 no_of_bits -= nB1;
1092 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1093 }
1094
1095 /* remaining no_of_bits is a multiple of 8 or 0 */
1096 while (no_of_bits > 0)
1097 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001098 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001099 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001100 pui8++;
1101 no_of_bits -= 8;
1102 }
1103 }
1104 }
1105 pDescr++;
1106 break;
1107 }
1108
1109 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1110 { /* Bitmap from here and to the end of message */
1111
1112 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1113
1114 /* no break -
1115 * with a length set we have a regular left aligned variable length bitmap so we continue
1116 */
1117 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001118 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001119 case CSN_LEFT_ALIGNED_VAR_BMP:
1120 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1121 * <N: bit (5)> <bitmap: bit(N + offset)>
1122 * bit array with length (in bits) specified in parameter (pDescr->descr)
1123 */
1124 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1125
1126 no_of_bits += pDescr->i;/* size adjusted by offset */
1127
1128 if (no_of_bits > 0)
1129 {
1130 remaining_bits_len -= no_of_bits;
1131
1132 if (remaining_bits_len < 0)
1133 {
1134 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1135 }
1136
1137 { /* extract bits */
1138 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001139
Neels Hofmeyr02415262016-09-02 02:15:26 +02001140 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001141 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001142 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001143 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001144 pui8++;
1145 no_of_bits -= 8;
1146 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001147 if (no_of_bits > 0)
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01001148 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001149 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001150 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001151 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001152 bit_offset += no_of_bits;
1153 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001154 }
1155 }
1156 }
1157
1158 /* bitmap was successfully extracted or it was empty */
1159 pDescr++;
1160 break;
1161 }
1162
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001163 case CSN_PADDING_BITS:
1164 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01001165 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001166 if (remaining_bits_len > 0)
1167 {
1168 while (remaining_bits_len > 0)
1169 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001170 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001171 if (bits_to_handle > 0)
1172 {
Harald Welte570f9132020-03-19 15:03:01 +01001173 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001174 remaining_bits_len -= bits_to_handle;
1175 bit_offset += bits_to_handle;
1176 }
1177 else if (bits_to_handle == 0)
1178 {
Harald Welte570f9132020-03-19 15:03:01 +01001179 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001180 remaining_bits_len -= 8;
1181 bit_offset += 8;
1182 }
1183 }
1184 }
1185 if (remaining_bits_len < 0)
1186 {
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01001187 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001188 }
1189
1190 /* Padding was successfully extracted or it was empty */
1191 pDescr++;
1192 break;
1193 }
1194
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001195 case CSN_VARIABLE_ARRAY:
1196 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1197 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1198 * Array with length specified in parameter:
1199 * <count: bit (x)>
1200 * <list: octet(count + offset)>
1201 */
1202 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1203
1204 count += pDescr->i; /* Adjusted by offset */
1205
1206 if (count > 0)
1207 {
1208 remaining_bits_len -= count * 8;
1209
1210 if (remaining_bits_len < 0)
1211 {
1212 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1213 }
1214
1215 pui8 = pui8DATA(data, pDescr->offset);
1216
1217 while (count > 0)
1218 {
1219 readIndex -= 8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001220 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001221 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001222 pui8++;
1223 bit_offset += 8;
1224 count--;
1225 }
1226 }
1227
1228 pDescr++;
1229 break;
1230 }
1231
1232 case CSN_RECURSIVE_ARRAY:
1233 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1234 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1235 * where <element> ::= bit(value)
1236 * <tag> ::= 0 | 1
1237 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1238 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1239 * REMARK: recursive way to specify an array but an iterative implementation!
1240 */
1241 gint16 no_of_bits = pDescr->i;
1242 guint8 ElementCount = 0;
1243
1244 pui8 = pui8DATA(data, pDescr->offset);
1245
Alexander Couzensccde5c92017-02-04 03:10:08 +01001246 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001247 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001248 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001249 bit_offset++;
1250 remaining_bits_len--;
1251
1252 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001253 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001254 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001255 pui8++;
1256 remaining_bits_len -= no_of_bits;
1257 ElementCount++;
1258
1259 if (remaining_bits_len < 0)
1260 {
1261 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1262 }
1263
1264 bit_offset += no_of_bits;
1265 }
1266
Harald Welte570f9132020-03-19 15:03:01 +01001267 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001268 /* existNextElement() returned FALSE, 1 bit consumed */
1269 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001270 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001271
1272 /* Store the counted number of elements of the array */
1273 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1274
1275 pDescr++;
1276 break;
1277 }
1278
1279 case CSN_RECURSIVE_TARRAY:
1280 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1281 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001282 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001283 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001284 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001285 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001286 guint8 ElementCount = 0;
1287 pui8 = pui8DATA(data, pDescr->offset);
1288
Alexander Couzensccde5c92017-02-04 03:10:08 +01001289 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001290 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001291 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001292 /* existNextElement() returned TRUE, 1 bit consumed */
1293 bit_offset++;
1294 remaining_bits_len--;
1295 ElementCount++;
1296
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001297 if (ElementCount > nSizeArray)
1298 {
1299 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1300 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1301 }
1302
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001303 { /* unpack the following data structure */
1304 csnStream_t arT = *ar;
1305 gint16 Status;
1306 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001307 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001308
1309 if (Status >= 0)
1310 { /* successful completion */
1311 pui8 += nSizeElement; /* -> to next data element */
1312 remaining_bits_len = arT.remaining_bits_len;
1313 bit_offset = arT.bit_offset;
1314 }
1315 else
1316 { /* something went awry */
1317 return Status;
1318 }
1319 }
1320
1321 if (remaining_bits_len < 0)
1322 {
1323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1324 }
1325 }
1326
Harald Welte570f9132020-03-19 15:03:01 +01001327 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001328
1329 /* existNextElement() returned FALSE, 1 bit consumed */
Vadim Yanitskiye87066d2020-02-17 18:02:32 +07001330 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001331 bit_offset++;
1332
1333 /* Store the counted number of elements of the array */
1334 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1335
1336 pDescr++;
1337 break;
1338 }
1339
1340 case CSN_RECURSIVE_TARRAY_2:
1341 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1342
1343 Tag = REVERSED_TAG;
1344
1345 /* NO break -
1346 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1347 */
1348 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001349 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001350 case CSN_RECURSIVE_TARRAY_1:
1351 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1352 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001353 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001354 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001355 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001356 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001357 guint8 ElementCount = 0;
1358 csnStream_t arT = *ar;
1359 gboolean EndOfList = FALSE;
1360 gint16 Status;
1361 pui8 = pui8DATA(data, pDescr->offset);
1362
1363 do
1364 { /* get data element */
1365 ElementCount++;
1366
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001367 if (ElementCount > nSizeArray)
1368 {
1369 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1370 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1371 }
1372
Harald Welte570f9132020-03-19 15:03:01 +01001373 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001374
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001375 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001376 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001377
1378 if (Status >= 0)
1379 { /* successful completion */
1380 pui8 += nSizeElement; /* -> to next */
1381 remaining_bits_len = arT.remaining_bits_len;
1382 bit_offset = arT.bit_offset;
1383 }
1384 else
1385 { /* something went awry */
1386 return Status;
1387 }
1388
1389 if (remaining_bits_len < 0)
1390 {
1391 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1392 }
1393
1394 /* control of next element's tag */
Harald Welte570f9132020-03-19 15:03:01 +01001395 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001396 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001397
1398 bit_offset++;
1399 remaining_bits_len--; /* 1 bit consumed (tag) */
1400 } while (!EndOfList);
1401
1402
1403 /* Store the count of the array */
1404 *pui8DATA(data, pDescr->i) = ElementCount;
1405 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1406 pDescr++;
1407 break;
1408 }
1409
1410 case CSN_FIXED:
1411 { /* Verify the fixed bits */
1412 guint8 no_of_bits = (guint8) pDescr->i;
1413 guint32 ui32;
1414
1415 if (no_of_bits <= 32)
1416 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001417 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001418 }
1419 else
1420 {
1421 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1422 }
1423 if (ui32 != (unsigned)(gint32)pDescr->offset)
1424 {
1425 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1426 }
1427
Harald Welte570f9132020-03-19 15:03:01 +01001428 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001429 remaining_bits_len -= no_of_bits;
1430 bit_offset += no_of_bits;
1431 pDescr++;
1432 break;
1433 }
1434
1435 case CSN_CALLBACK:
1436 {
Pau Espin Pedrolf3ac06b2020-03-26 18:13:19 +01001437 guint16 no_of_bits;
1438 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1439 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
1440 no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
1441 remaining_bits_len -= no_of_bits;
1442 bit_offset += no_of_bits;
1443 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001444 break;
1445 }
1446
1447 case CSN_TRAP_ERROR:
1448 {
1449 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1450 }
1451
1452 case CSN_END:
1453 {
1454 ar->remaining_bits_len = remaining_bits_len;
1455 ar->bit_offset = bit_offset;
1456 return remaining_bits_len;
1457 }
1458
1459 default:
1460 {
1461 assert(0);
1462 }
1463
1464
1465 }
1466
1467 } while (remaining_bits_len >= 0);
1468
1469 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1470}
1471
1472
1473
1474
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001475gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001476{
1477 gint remaining_bits_len = ar->remaining_bits_len;
1478 gint bit_offset = ar->bit_offset;
1479 guint8* pui8;
1480 guint16* pui16;
1481 guint32* pui32;
1482 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001483 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001484
1485 guint8 Tag = STANDARD_TAG;
1486
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001487 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001488 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001489 return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001490 }
1491
1492 do
1493 {
1494 switch (pDescr->type)
1495 {
1496 case CSN_BIT:
1497 {
1498 if (remaining_bits_len > 0)
1499 {
1500 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001501 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001502 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001503 /* end add the bit value to protocol tree */
1504 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001505 else if(pDescr->may_be_null)
1506 {
Harald Welte570f9132020-03-19 15:03:01 +01001507 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001508 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001509 else
1510 {
1511 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1512 }
1513
1514 pDescr++;
1515 remaining_bits_len--;
1516 bit_offset++;
1517 break;
1518 }
1519
1520 case CSN_NULL:
1521 { /* Empty member! */
1522 pDescr++;
1523 break;
1524 }
1525
1526 case CSN_UINT:
1527 {
1528 guint8 no_of_bits = (guint8) pDescr->i;
1529
1530 if (remaining_bits_len >= no_of_bits)
1531 {
1532 if (no_of_bits <= 8)
1533 {
1534 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001535 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001536 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001537 }
1538 else if (no_of_bits <= 16)
1539 {
1540 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001541 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001542 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001543 }
1544 else if (no_of_bits <= 32)
1545 {
1546 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001547 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001548 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001549 }
1550 else
1551 {
1552 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1553 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001554
1555 remaining_bits_len -= no_of_bits;
1556 bit_offset += no_of_bits;
1557 }
1558 else if(pDescr->may_be_null)
1559 {
Harald Welte570f9132020-03-19 15:03:01 +01001560 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001561 }
1562 else
1563 {
1564 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1565 }
1566
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001567 pDescr++;
1568 break;
1569 }
1570
1571 case CSN_UINT_OFFSET:
1572 {
1573 guint8 no_of_bits = (guint8) pDescr->i;
1574
1575 if (remaining_bits_len >= no_of_bits)
1576 {
1577 if (no_of_bits <= 8)
1578 {
1579 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001580 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001581 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001582 }
1583 else if (no_of_bits <= 16)
1584 {
1585 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001586 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001587 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001588 }
1589 else if (no_of_bits <= 32)
1590 {
1591 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001592 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001593 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001594 }
1595 else
1596 {
1597 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1598 }
1599 }
1600 else
1601 {
1602 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1603 }
1604
1605 remaining_bits_len -= no_of_bits;
1606 bit_offset += no_of_bits;
1607 pDescr++;
1608 break;
1609 }
1610
1611 case CSN_UINT_LH:
1612 {
1613 guint8 no_of_bits = (guint8) pDescr->i;
1614
1615 if (remaining_bits_len >= no_of_bits)
1616 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001617 if (no_of_bits <= 8)
1618 {
1619 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001620 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001621 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001622 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001623 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001624 *writeIndex -= no_of_bits;
1625 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001626 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001627
1628 }
1629 else
1630 {/* Maybe we should support more than 8 bits ? */
1631 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1632 }
1633 }
1634 else
1635 {
1636 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1637 }
1638
1639 remaining_bits_len -= no_of_bits;
1640 bit_offset += no_of_bits;
1641 pDescr++;
1642 break;
1643 }
1644
1645 case CSN_UINT_ARRAY:
1646 {
1647 guint8 no_of_bits = (guint8) pDescr->i;
1648 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1649
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001650 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001651 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1652 nCount = *pui16DATA(data, nCount);
1653 }
1654
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +01001655 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001656 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001657 if (no_of_bits <= 8)
1658 {
1659 pui8 = pui8DATA(data, pDescr->offset);
1660 do
1661 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001662 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001663 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001664 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001665 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001666 bit_offset += no_of_bits;
1667 } while (--nCount > 0);
1668 }
1669 else if (no_of_bits <= 16)
1670 {
1671 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1672 }
1673 else if (no_of_bits <= 32)
1674 {
1675 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1676 }
1677 else
1678 {
1679 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1680 }
1681 }
1682 else
1683 {
1684 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1685 }
1686 pDescr++;
1687 break;
1688 }
1689
1690 case CSN_VARIABLE_TARRAY_OFFSET:
1691 case CSN_VARIABLE_TARRAY:
1692 case CSN_TYPE_ARRAY:
1693 {
1694 gint16 Status;
1695 csnStream_t arT = *ar;
1696 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001697 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001698
1699 pui8 = pui8DATA(data, pDescr->offset);
1700 if (pDescr->type == CSN_VARIABLE_TARRAY)
1701 { /* Count specified in field */
1702 nCount = *pui8DATA(data, pDescr->i);
1703 }
1704 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1705 { /* Count specified in field */
1706 nCount = *pui8DATA(data, pDescr->i);
1707 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1708 }
1709
1710 while (nCount > 0)
1711 { /* resulting array of length 0 is possible
1712 * but no bits shall be read from bitstream
1713 */
1714
Harald Welte570f9132020-03-19 15:03:01 +01001715 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001716 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1717 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1718 if (Status >= 0)
1719 {
1720 pui8 += nSize;
1721 remaining_bits_len = arT.remaining_bits_len;
1722 bit_offset = arT.bit_offset;
1723
1724 }
1725 else
1726 {
1727 return Status;
1728 }
1729 nCount--;
1730 }
1731
1732 pDescr++;
1733 break;
1734 }
1735
1736 case CSN_BITMAP:
1737 { /* bitmap with given length. The result is left aligned! */
1738 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1739
1740 if (no_of_bits > 0)
1741 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +01001742 if (no_of_bits > remaining_bits_len)
1743 {
1744 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1745 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001746
1747 if (no_of_bits <= 32)
1748 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001749 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001750 {
1751 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001752 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001753 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001754 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001755 }
1756 else if (no_of_bits <= 64)
1757 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001758 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001759 {
1760 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001761 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001762 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001763 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001764 }
1765 else
1766 {
1767 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1768 }
1769
1770 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001771 bit_offset += no_of_bits;
1772 }
1773 /* bitmap was successfully extracted or it was empty */
1774
1775 pDescr++;
1776 break;
1777 }
1778
1779 case CSN_TYPE:
1780 {
1781 gint16 Status;
1782 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01001783 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001784 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1785 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01001786 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001787 if (Status >= 0)
1788 {
1789
1790 remaining_bits_len = arT.remaining_bits_len;
1791 bit_offset = arT.bit_offset;
1792 pDescr++;
1793 }
1794 else
1795 {
1796 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1797 return Status;
1798 }
1799
1800 break;
1801 }
1802
1803 case CSN_CHOICE:
1804 {
Vadim Yanitskiyfac83322020-05-23 17:33:07 +07001805 gint16 count = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001806 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001807 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001808
Vadim Yanitskiyfac83322020-05-23 17:33:07 +07001809 /* Make sure that the list of choice items is not empty */
1810 if (!count)
1811 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
1812 else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
1813 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
1814
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001815 pui8 = pui8DATA(data, pDescr->offset);
1816 i = *pui8;
1817 pChoice += i;
1818 guint8 no_of_bits = pChoice->bits;
1819 guint8 value = pChoice->value;
Harald Welte570f9132020-03-19 15:03:01 +01001820 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001821 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001822
1823 CSN_DESCR descr[2];
1824 gint16 Status;
1825 csnStream_t arT = *ar;
1826
1827 descr[0] = pChoice->descr;
1828 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1829 descr[1].type = CSN_END;
1830 bit_offset += no_of_bits;
1831 remaining_bits_len -= no_of_bits;
1832
1833 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1834 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1835
1836 if (Status >= 0)
1837 {
1838 remaining_bits_len = arT.remaining_bits_len;
1839 bit_offset = arT.bit_offset;
1840 }
1841 else
1842 {
1843 return Status;
1844 }
1845
1846 pDescr++;
1847 break;
1848 }
1849
1850 case CSN_SERIALIZE:
1851 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001852 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001853 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001854 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001855 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001856 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001857
1858 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001859 lengthIndex = *writeIndex;
1860 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001861 bit_offset += length_len;
1862 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001863 arT.direction = 0;
1864 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1865 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001866
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001867 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
Harald Welte570f9132020-03-19 15:03:01 +01001868 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001869
1870 if (Status >= 0)
1871 {
1872 remaining_bits_len = arT.remaining_bits_len;
1873 bit_offset = arT.bit_offset;
1874 pDescr++;
1875 }
1876 else
1877 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001878 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001879 return Status;
1880 }
1881
1882 break;
1883 }
1884
1885 case CSN_UNION_LH:
1886 case CSN_UNION:
1887 {
1888 gint16 Bits;
1889 guint8 index;
1890 gint16 count = pDescr->i;
1891 const CSN_DESCR* pDescrNext = pDescr;
1892
1893 pDescrNext += count + 1; /* now this is next after the union */
1894 if ((count <= 0) || (count > 16))
1895 {
1896 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1897 }
1898
1899 /* Now get the bits to extract the index */
1900 Bits = ixBitsTab[count];
1901 index = 0;
1902
1903 /* Assign UnionType */
1904 pui8 = pui8DATA(data, pDescr->offset);
1905 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001906 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001907
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001908 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001909 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001910
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001911 while (Bits > 0)
1912 {
1913 index <<= 1;
1914
1915 if (CSN_UNION_LH == pDescr->type)
1916 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001917 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001918 }
1919 else
1920 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001921 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001922 }
1923
1924 remaining_bits_len--;
1925 bit_offset++;
1926 Bits--;
1927 }
1928
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001929 *writeIndex -= Bits;
1930 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001931
1932
1933 /* script index to continue on, limited in case we do not have a power of 2 */
1934 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +01001935 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001936
1937 switch (pDescr->type)
1938 { /* get the right element of the union based on computed index */
1939
1940 case CSN_BIT:
1941 {
1942 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001943 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001944 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001945 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001946 bit_offset++;
1947 pDescr++;
1948 break;
1949 }
1950
1951 case CSN_NULL:
1952 { /* Empty member! */
1953 pDescr++;
1954 break;
1955 }
1956
1957 case CSN_UINT:
1958 {
1959 guint8 no_of_bits = (guint8) pDescr->i;
1960 if (remaining_bits_len >= no_of_bits)
1961 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001962 if (no_of_bits <= 8)
1963 {
1964 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001965 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001966 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001967 }
1968 else if (no_of_bits <= 16)
1969 {
1970 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001971 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001972 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001973 }
1974 else if (no_of_bits <= 32)
1975 {
1976 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001977 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001978 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001979 }
1980 else
1981 {
1982 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1983 }
1984 }
1985 else
1986 {
1987 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1988 }
1989
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001990 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001991 bit_offset += no_of_bits;
1992 pDescr++;
1993 break;
1994 }
1995
1996 case CSN_UINT_OFFSET:
1997 {
1998 guint8 no_of_bits = (guint8) pDescr->i;
1999
2000 if (remaining_bits_len >= no_of_bits)
2001 {
2002 if (no_of_bits <= 8)
2003 {
2004 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002005 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002006 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002007 }
2008 else if (no_of_bits <= 16)
2009 {
2010 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002011 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002012 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002013 }
2014 else if (no_of_bits <= 32)
2015 {
2016 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002017 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002018 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002019 }
2020 else
2021 {
2022 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2023 }
2024 }
2025 else
2026 {
2027 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2028 }
2029
2030 remaining_bits_len -= no_of_bits;
2031 bit_offset += no_of_bits;
2032 pDescr++;
2033 break;
2034 }
2035
2036 case CSN_UINT_LH:
2037 {
2038 guint8 no_of_bits = (guint8) pDescr->i;
2039
2040 if (remaining_bits_len >= no_of_bits)
2041 {
2042 remaining_bits_len -= no_of_bits;
2043 if (no_of_bits <= 8)
2044 {
2045 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002046 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002047 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002048 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002049 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002050 *writeIndex -= no_of_bits;
2051 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002052 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002053
2054 }
2055 else
2056 {/* Maybe we should support more than 8 bits ? */
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
2065 remaining_bits_len -= no_of_bits;
2066 bit_offset += no_of_bits;
2067 pDescr++;
2068 break;
2069 }
2070
2071 case CSN_UINT_ARRAY:
2072 {
2073 guint8 no_of_bits = (guint8) pDescr->i;
2074 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2075
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002076 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002077 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2078 nCount = *pui16DATA(data, nCount);
2079 }
2080
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +01002081 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002082 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002083 if (no_of_bits <= 8)
2084 {
2085 pui8 = pui8DATA(data, pDescr->offset);
2086 do
2087 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002088 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002089 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002090 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002091 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002092 bit_offset += no_of_bits;
2093 } while (--nCount > 0);
2094 }
2095 else if (no_of_bits <= 16)
2096 {
2097 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2098 }
2099 else if (no_of_bits <= 32)
2100 {
2101 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2102 }
2103 else
2104 {
2105 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2106 }
2107 }
2108 else
2109 {
2110 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2111 }
2112 pDescr++;
2113 break;
2114 }
2115
2116 case CSN_VARIABLE_TARRAY_OFFSET:
2117 case CSN_VARIABLE_TARRAY:
2118 case CSN_TYPE_ARRAY:
2119 {
2120 gint16 Status;
2121 csnStream_t arT = *ar;
2122 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002123 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002124
2125 pui8 = pui8DATA(data, pDescr->offset);
2126 if (pDescr->type == CSN_VARIABLE_TARRAY)
2127 { /* Count specified in field */
2128 nCount = *pui8DATA(data, pDescr->i);
2129 }
2130 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2131 { /* Count specified in field */
2132 nCount = *pui8DATA(data, pDescr->i);
2133 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2134 }
2135
2136 while (nCount > 0)
2137 { /* resulting array of length 0 is possible
2138 * but no bits shall be read from bitstream
2139 */
2140
Harald Welte570f9132020-03-19 15:03:01 +01002141 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002142 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2143 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2144 if (Status >= 0)
2145 {
2146 pui8 += nSize;
2147 remaining_bits_len = arT.remaining_bits_len;
2148 bit_offset = arT.bit_offset;
2149 }
2150 else
2151 {
2152 return Status;
2153 }
2154 nCount--;
2155 }
2156
2157 pDescr++;
2158 break;
2159 }
2160
2161 case CSN_BITMAP:
2162 { /* bitmap with given length. The result is left aligned! */
2163 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2164
2165 if (no_of_bits > 0)
2166 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +01002167 if (no_of_bits > remaining_bits_len)
2168 {
2169 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2170 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002171
2172 if (no_of_bits <= 32)
2173 {
2174 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002175 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002176 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002177 }
2178 else if (no_of_bits <= 64)
2179 {
2180 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002181 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002182 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002183 }
2184 else
2185 {
2186 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2187 }
2188
2189 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002190 bit_offset += no_of_bits;
2191 }
2192 /* bitmap was successfully extracted or it was empty */
2193
2194 pDescr++;
2195 break;
2196 }
2197
2198 case CSN_TYPE:
2199 {
2200 gint16 Status;
2201 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01002202 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002203 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2204 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01002205 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002206 if (Status >= 0)
2207 {
2208 remaining_bits_len = arT.remaining_bits_len;
2209 bit_offset = arT.bit_offset;
2210 pDescr++;
2211 }
2212 else
2213 {
2214 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2215 return Status;
2216 }
2217
2218 break;
2219 }
2220
2221 default:
2222 { /* descriptions of union elements other than above are illegal */
2223 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2224 }
2225 }
2226
2227 pDescr = pDescrNext;
2228 break;
2229 }
2230
2231 case CSN_EXIST:
2232 case CSN_EXIST_LH:
2233 {
2234 guint8 fExist;
2235 unsigned exist = 0;
2236 pui8 = pui8DATA(data, pDescr->offset);
2237 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002238 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002239 writeIndex--;
2240 if (CSN_EXIST_LH == pDescr->type)
2241 {
2242 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2243 }
2244 else
2245 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002246 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002247 }
2248 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002249 bitvec_write_field(vector, writeIndex, fExist, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002250 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002251 remaining_bits_len--;
2252 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002253 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002254
2255 if (!exist)
2256 {
2257 ar->remaining_bits_len = remaining_bits_len;
2258 ar->bit_offset = bit_offset;
2259 return remaining_bits_len;
2260 }
2261 break;
2262 }
2263
2264 case CSN_NEXT_EXIST:
2265 {
2266 guint8 fExist;
2267
2268 pui8 = pui8DATA(data, pDescr->offset);
2269
2270 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002271 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002272 { /* no more bits to decode is fine here - end of message detected and allowed */
2273
2274 /* Skip i entries + this entry */
2275 pDescr += pDescr->i + 1;
2276
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002277 break;
2278 }
2279
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002280 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002281 fExist = *pui8;
Harald Welte570f9132020-03-19 15:03:01 +01002282 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002283
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002284 remaining_bits_len--;
2285 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002286
2287 if (fExist == 0)
2288 { /* Skip 'i' entries */
2289 pDescr += pDescr->i;
2290 }
2291
2292 pDescr++;
2293 break;
2294 }
2295
2296 case CSN_NEXT_EXIST_LH:
2297 {
2298 guint8 fExist;
2299 pui8 = pui8DATA(data, pDescr->offset);
2300
2301 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2302 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2303 { /* no more bits to decode is fine here - end of message detected and allowed */
2304
2305 /* skip 'i' entries + this entry */
2306 pDescr += pDescr->i + 1;
2307
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002308 /* set the data member to "not exist" */
2309 //*pui8 = 0;
2310 break;
2311 }
2312
2313 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002314 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002315 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002316 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002317 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002318 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002319 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002320
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002321 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002322 bit_offset++;
2323
2324 if (fExist == 0)
2325 { /* Skip 'i' entries */
2326 pDescr += pDescr->i;
2327 }
2328 pDescr++;
2329
2330 break;
2331 }
2332
2333 case CSN_VARIABLE_BITMAP_1:
2334 { /* Bitmap from here and to the end of message */
2335
2336 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2337
2338 /*no break -
2339 * with a length set we have a regular variable length bitmap so we continue */
2340 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002341 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002342 case CSN_VARIABLE_BITMAP:
2343 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2344 * <N: bit (5)> <bitmap: bit(N + offset)>
2345 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2346 * The result is right aligned!
2347 */
2348 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2349
2350 no_of_bits += pDescr->i; /* adjusted by offset */
2351
2352 if (no_of_bits > 0)
2353 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002354
2355 if (remaining_bits_len < 0)
2356 {
2357 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2358 }
2359
2360 { /* extract bits */
2361 guint8* pui8 = pui8DATA(data, pDescr->offset);
2362 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2363
2364 if (nB1 > 0)
2365 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002366 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002367 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002368 pui8++;
2369 no_of_bits -= nB1;
2370 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002371 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002372 }
2373
2374 /* remaining no_of_bits is a multiple of 8 or 0 */
2375 while (no_of_bits > 0)
2376 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002377 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002378 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002379 pui8++;
2380 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002381 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002382 }
2383 }
2384 }
2385 pDescr++;
2386 break;
2387 }
2388
2389 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2390 { /* Bitmap from here and to the end of message */
2391
2392 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2393
2394 /* no break -
2395 * with a length set we have a regular left aligned variable length bitmap so we continue
2396 */
2397 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002398 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002399 case CSN_LEFT_ALIGNED_VAR_BMP:
2400 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2401 * <N: bit (5)> <bitmap: bit(N + offset)>
2402 * bit array with length (in bits) specified in parameter (pDescr->descr)
2403 */
2404
2405 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2406
2407 no_of_bits += pDescr->i;/* size adjusted by offset */
2408
2409 if (no_of_bits > 0)
2410 {
2411 remaining_bits_len -= no_of_bits;
2412
2413 if (remaining_bits_len < 0)
2414 {
2415 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2416 }
2417
2418 { /* extract bits */
2419 guint8* pui8 = pui8DATA(data, pDescr->offset);
2420 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2421
2422 while (no_of_bits > 0)
2423 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002424 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002425 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002426 pui8++;
2427 no_of_bits -= 8;
2428 }
2429 if (nB1 > 0)
2430 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002431 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002432 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002433 pui8++;
2434 no_of_bits -= nB1;
2435 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2436 }
2437 }
2438
2439 }
2440
2441 /* bitmap was successfully extracted or it was empty */
2442 pDescr++;
2443 break;
2444 }
2445
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002446 case CSN_PADDING_BITS:
2447 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01002448 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002449 guint8 filler = 0x2b;
2450 if (remaining_bits_len > 0)
2451 {
2452 while (remaining_bits_len > 0)
2453 {
2454 guint8 bits_to_handle = remaining_bits_len%8;
2455 if (bits_to_handle > 0)
2456 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302457 /* section 11 of 44.060
2458 * The padding bits may be the 'null' string. Otherwise, the
2459 * padding bits starts with bit '0', followed by 'spare padding'
2460 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2461 */
2462 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002463 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Harald Welte570f9132020-03-19 15:03:01 +01002464 LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002465 remaining_bits_len -= bits_to_handle;
2466 bit_offset += bits_to_handle;
2467 }
2468 else if (bits_to_handle == 0)
2469 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002470 bitvec_write_field(vector, writeIndex, filler, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002471 LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002472 remaining_bits_len -= 8;
2473 bit_offset += 8;
2474 }
2475 }
2476 }
2477 if (remaining_bits_len < 0)
2478 {
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01002479 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002480 }
2481
2482 /* Padding was successfully extracted or it was empty */
2483 pDescr++;
2484 break;
2485 }
2486
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002487 case CSN_VARIABLE_ARRAY:
2488 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2489 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2490 * Array with length specified in parameter:
2491 * <count: bit (x)>
2492 * <list: octet(count + offset)>
2493 */
2494 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2495
2496 count += pDescr->i; /* Adjusted by offset */
2497
2498 if (count > 0)
2499 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002500 if (remaining_bits_len < 0)
2501 {
2502 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2503 }
2504
2505 pui8 = pui8DATA(data, pDescr->offset);
2506
2507 while (count > 0)
2508 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002509 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002510 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002511 pui8++;
2512 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002513 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002514 count--;
2515 }
2516 }
2517
2518 pDescr++;
2519 break;
2520 }
2521
2522 case CSN_RECURSIVE_ARRAY:
2523 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2524 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2525 * where <element> ::= bit(value)
2526 * <tag> ::= 0 | 1
2527 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2528 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2529 * REMARK: recursive way to specify an array but an iterative implementation!
2530 */
2531 gint16 no_of_bits = pDescr->i;
2532 guint8 ElementCount = 0;
2533 pui8 = pui8DATA(data, pDescr->offset);
2534 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2535 while (ElementCount > 0)
2536 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002537 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002538 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002539 bit_offset++;
2540 remaining_bits_len--;
2541
2542 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002543 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002544 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002545 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002546 ElementCount--;
2547
2548 if (remaining_bits_len < 0)
2549 {
2550 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2551 }
2552
2553 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002554 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002555 }
2556
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002557 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002558 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002559 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302560 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002561
2562 pDescr++;
2563 break;
2564 }
2565
2566 case CSN_RECURSIVE_TARRAY:
2567 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2568 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2569 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2570 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002571 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002572 guint8 ElementCount = 0;
2573 pui8 = pui8DATA(data, pDescr->offset);
2574 /* Store the counted number of elements of the array */
2575 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2576
2577 while (ElementCount > 0)
2578 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002579 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002580 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002581 bit_offset++;
2582
2583 remaining_bits_len--;
2584 ElementCount--;
2585
2586 { /* unpack the following data structure */
2587 csnStream_t arT = *ar;
2588 gint16 Status;
2589 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002590 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002591
2592 if (Status >= 0)
2593 { /* successful completion */
2594 pui8 += nSizeElement; /* -> to next data element */
2595 remaining_bits_len = arT.remaining_bits_len;
2596 bit_offset = arT.bit_offset;
2597 }
2598 else
2599 { /* something went awry */
2600 return Status;
2601 }
2602 }
2603
2604 if (remaining_bits_len < 0)
2605 {
2606 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2607 }
2608 }
2609
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002610 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002611 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002612 bit_offset++;
2613
2614 pDescr++;
2615 break;
2616 }
2617
2618 case CSN_RECURSIVE_TARRAY_2:
2619 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2620
2621 Tag = REVERSED_TAG;
2622
2623 /* NO break -
2624 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2625 */
2626 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002627 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002628 case CSN_RECURSIVE_TARRAY_1:
2629 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2630 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2631 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2632 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002633 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002634 guint8 ElementCount = 0;
2635 guint8 ElementNum = 0;
2636 csnStream_t arT = *ar;
2637 gint16 Status;
2638
2639 pui8 = pui8DATA(data, pDescr->offset);
2640 /* Store the count of the array */
2641 ElementCount = *pui8DATA(data, pDescr->i);
2642 ElementNum = ElementCount;
2643
2644 while (ElementCount > 0)
2645 { /* get data element */
2646 if (ElementCount != ElementNum)
2647 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002648 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002649 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002650 bit_offset++;
2651 remaining_bits_len--;
2652 }
2653 ElementCount--;
Harald Welte570f9132020-03-19 15:03:01 +01002654 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002655 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002656 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Harald Welte570f9132020-03-19 15:03:01 +01002657 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002658 if (Status >= 0)
2659 { /* successful completion */
2660 pui8 += nSizeElement; /* -> to next */
2661 remaining_bits_len = arT.remaining_bits_len;
2662 bit_offset = arT.bit_offset;
2663 }
2664 else
2665 { /* something went awry */
2666 return Status;
2667 }
2668
2669 if (remaining_bits_len < 0)
2670 {
2671 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2672 }
2673
2674 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002675 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002676 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002677 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002678 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2679 pDescr++;
2680 break;
2681 }
2682
2683 case CSN_FIXED:
2684 { /* Verify the fixed bits */
2685 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002686 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002687 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002688 remaining_bits_len -= no_of_bits;
2689 bit_offset += no_of_bits;
2690 pDescr++;
2691 break;
2692 }
2693
2694 case CSN_CALLBACK:
2695 {
2696 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2697 break;
2698 }
2699
2700 case CSN_TRAP_ERROR:
2701 {
2702 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2703 }
2704
2705 case CSN_END:
2706 {
2707 ar->remaining_bits_len = remaining_bits_len;
2708 ar->bit_offset = bit_offset;
2709 return remaining_bits_len;
2710 }
2711
2712 default:
2713 {
2714 assert(0);
2715 }
2716
2717 }
2718
2719 } while (remaining_bits_len >= 0);
2720
2721 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2722}