blob: 2be039238452adf8cd29afbd28369c729d1f42a9 [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 }
Pau Espin Pedrol16705a42020-10-27 10:24:57 +0100173 else if (pDescr->may_be_null)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400174 {
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 }
Pau Espin Pedrol16705a42020-10-27 10:24:57 +0100231 else if (pDescr->may_be_null)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400232 {
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 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001219 *pui8 = bitvec_read_field(vector, readIndex, 8);
Pau Espin Pedrol74aa3522020-11-24 11:10:52 +01001220 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001221 pui8++;
1222 bit_offset += 8;
1223 count--;
1224 }
1225 }
1226
1227 pDescr++;
1228 break;
1229 }
1230
1231 case CSN_RECURSIVE_ARRAY:
1232 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1233 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1234 * where <element> ::= bit(value)
1235 * <tag> ::= 0 | 1
1236 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1237 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1238 * REMARK: recursive way to specify an array but an iterative implementation!
1239 */
1240 gint16 no_of_bits = pDescr->i;
1241 guint8 ElementCount = 0;
1242
1243 pui8 = pui8DATA(data, pDescr->offset);
1244
Alexander Couzensccde5c92017-02-04 03:10:08 +01001245 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001246 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001247 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001248 bit_offset++;
1249 remaining_bits_len--;
1250
1251 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001252 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001253 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001254 pui8++;
1255 remaining_bits_len -= no_of_bits;
1256 ElementCount++;
1257
1258 if (remaining_bits_len < 0)
1259 {
1260 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1261 }
1262
1263 bit_offset += no_of_bits;
1264 }
1265
Harald Welte570f9132020-03-19 15:03:01 +01001266 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001267 /* existNextElement() returned FALSE, 1 bit consumed */
1268 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001269 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001270
1271 /* Store the counted number of elements of the array */
1272 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1273
1274 pDescr++;
1275 break;
1276 }
1277
1278 case CSN_RECURSIVE_TARRAY:
1279 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1280 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001281 * {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 +03001282 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001283 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001284 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001285 guint8 ElementCount = 0;
1286 pui8 = pui8DATA(data, pDescr->offset);
1287
Alexander Couzensccde5c92017-02-04 03:10:08 +01001288 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001289 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001290 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001291 /* existNextElement() returned TRUE, 1 bit consumed */
1292 bit_offset++;
1293 remaining_bits_len--;
1294 ElementCount++;
1295
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001296 if (ElementCount > nSizeArray)
1297 {
1298 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1299 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1300 }
1301
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001302 { /* unpack the following data structure */
1303 csnStream_t arT = *ar;
1304 gint16 Status;
1305 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001306 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001307
1308 if (Status >= 0)
1309 { /* successful completion */
1310 pui8 += nSizeElement; /* -> to next data element */
1311 remaining_bits_len = arT.remaining_bits_len;
1312 bit_offset = arT.bit_offset;
1313 }
1314 else
1315 { /* something went awry */
1316 return Status;
1317 }
1318 }
1319
1320 if (remaining_bits_len < 0)
1321 {
1322 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1323 }
1324 }
1325
Harald Welte570f9132020-03-19 15:03:01 +01001326 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001327
1328 /* existNextElement() returned FALSE, 1 bit consumed */
Vadim Yanitskiye87066d2020-02-17 18:02:32 +07001329 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001330 bit_offset++;
1331
1332 /* Store the counted number of elements of the array */
1333 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1334
1335 pDescr++;
1336 break;
1337 }
1338
1339 case CSN_RECURSIVE_TARRAY_2:
1340 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1341
1342 Tag = REVERSED_TAG;
1343
1344 /* NO break -
1345 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1346 */
1347 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001348 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001349 case CSN_RECURSIVE_TARRAY_1:
1350 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1351 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001352 * {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 +03001353 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001354 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001355 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001356 guint8 ElementCount = 0;
1357 csnStream_t arT = *ar;
1358 gboolean EndOfList = FALSE;
1359 gint16 Status;
1360 pui8 = pui8DATA(data, pDescr->offset);
1361
1362 do
1363 { /* get data element */
1364 ElementCount++;
1365
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001366 if (ElementCount > nSizeArray)
1367 {
1368 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1369 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1370 }
1371
Harald Welte570f9132020-03-19 15:03:01 +01001372 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001373
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001374 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001375 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001376
1377 if (Status >= 0)
1378 { /* successful completion */
1379 pui8 += nSizeElement; /* -> to next */
1380 remaining_bits_len = arT.remaining_bits_len;
1381 bit_offset = arT.bit_offset;
1382 }
1383 else
1384 { /* something went awry */
1385 return Status;
1386 }
1387
1388 if (remaining_bits_len < 0)
1389 {
1390 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1391 }
1392
1393 /* control of next element's tag */
Harald Welte570f9132020-03-19 15:03:01 +01001394 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001395 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001396
1397 bit_offset++;
1398 remaining_bits_len--; /* 1 bit consumed (tag) */
1399 } while (!EndOfList);
1400
1401
1402 /* Store the count of the array */
1403 *pui8DATA(data, pDescr->i) = ElementCount;
1404 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1405 pDescr++;
1406 break;
1407 }
1408
1409 case CSN_FIXED:
1410 { /* Verify the fixed bits */
1411 guint8 no_of_bits = (guint8) pDescr->i;
1412 guint32 ui32;
1413
1414 if (no_of_bits <= 32)
1415 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001416 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001417 }
1418 else
1419 {
1420 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1421 }
1422 if (ui32 != (unsigned)(gint32)pDescr->offset)
1423 {
1424 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1425 }
1426
Harald Welte570f9132020-03-19 15:03:01 +01001427 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001428 remaining_bits_len -= no_of_bits;
1429 bit_offset += no_of_bits;
1430 pDescr++;
1431 break;
1432 }
1433
1434 case CSN_CALLBACK:
1435 {
Pau Espin Pedrolf3ac06b2020-03-26 18:13:19 +01001436 guint16 no_of_bits;
1437 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1438 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
1439 no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
1440 remaining_bits_len -= no_of_bits;
1441 bit_offset += no_of_bits;
1442 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001443 break;
1444 }
1445
1446 case CSN_TRAP_ERROR:
1447 {
1448 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1449 }
1450
1451 case CSN_END:
1452 {
1453 ar->remaining_bits_len = remaining_bits_len;
1454 ar->bit_offset = bit_offset;
1455 return remaining_bits_len;
1456 }
1457
1458 default:
1459 {
1460 assert(0);
1461 }
1462
1463
1464 }
1465
1466 } while (remaining_bits_len >= 0);
1467
1468 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1469}
1470
1471
1472
1473
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001474gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001475{
1476 gint remaining_bits_len = ar->remaining_bits_len;
1477 gint bit_offset = ar->bit_offset;
1478 guint8* pui8;
1479 guint16* pui16;
1480 guint32* pui32;
1481 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001482 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001483
1484 guint8 Tag = STANDARD_TAG;
1485
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001486 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001487 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001488 return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001489 }
1490
1491 do
1492 {
1493 switch (pDescr->type)
1494 {
1495 case CSN_BIT:
1496 {
1497 if (remaining_bits_len > 0)
1498 {
1499 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001500 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001501 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001502 /* end add the bit value to protocol tree */
1503 }
Pau Espin Pedrol16705a42020-10-27 10:24:57 +01001504 else if (pDescr->may_be_null)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001505 {
Harald Welte570f9132020-03-19 15:03:01 +01001506 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001507 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001508 else
1509 {
1510 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1511 }
1512
1513 pDescr++;
1514 remaining_bits_len--;
1515 bit_offset++;
1516 break;
1517 }
1518
1519 case CSN_NULL:
1520 { /* Empty member! */
1521 pDescr++;
1522 break;
1523 }
1524
1525 case CSN_UINT:
1526 {
1527 guint8 no_of_bits = (guint8) pDescr->i;
1528
1529 if (remaining_bits_len >= no_of_bits)
1530 {
1531 if (no_of_bits <= 8)
1532 {
1533 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001534 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001535 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001536 }
1537 else if (no_of_bits <= 16)
1538 {
1539 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001540 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001541 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001542 }
1543 else if (no_of_bits <= 32)
1544 {
1545 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001546 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001547 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001548 }
1549 else
1550 {
1551 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1552 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001553
1554 remaining_bits_len -= no_of_bits;
1555 bit_offset += no_of_bits;
1556 }
Pau Espin Pedrol16705a42020-10-27 10:24:57 +01001557 else if (pDescr->may_be_null)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001558 {
Harald Welte570f9132020-03-19 15:03:01 +01001559 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001560 }
1561 else
1562 {
1563 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1564 }
1565
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001566 pDescr++;
1567 break;
1568 }
1569
1570 case CSN_UINT_OFFSET:
1571 {
1572 guint8 no_of_bits = (guint8) pDescr->i;
1573
1574 if (remaining_bits_len >= no_of_bits)
1575 {
1576 if (no_of_bits <= 8)
1577 {
1578 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001579 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001580 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001581 }
1582 else if (no_of_bits <= 16)
1583 {
1584 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001585 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001586 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001587 }
1588 else if (no_of_bits <= 32)
1589 {
1590 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001591 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001592 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001593 }
1594 else
1595 {
1596 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1597 }
1598 }
1599 else
1600 {
1601 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1602 }
1603
1604 remaining_bits_len -= no_of_bits;
1605 bit_offset += no_of_bits;
1606 pDescr++;
1607 break;
1608 }
1609
1610 case CSN_UINT_LH:
1611 {
1612 guint8 no_of_bits = (guint8) pDescr->i;
1613
1614 if (remaining_bits_len >= no_of_bits)
1615 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001616 if (no_of_bits <= 8)
1617 {
1618 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001619 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001620 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001621 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001622 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001623 *writeIndex -= no_of_bits;
1624 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001625 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001626
1627 }
1628 else
1629 {/* Maybe we should support more than 8 bits ? */
1630 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1631 }
1632 }
1633 else
1634 {
1635 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1636 }
1637
1638 remaining_bits_len -= no_of_bits;
1639 bit_offset += no_of_bits;
1640 pDescr++;
1641 break;
1642 }
1643
1644 case CSN_UINT_ARRAY:
1645 {
1646 guint8 no_of_bits = (guint8) pDescr->i;
1647 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1648
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001649 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001650 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1651 nCount = *pui16DATA(data, nCount);
1652 }
1653
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +01001654 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001655 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001656 if (no_of_bits <= 8)
1657 {
1658 pui8 = pui8DATA(data, pDescr->offset);
1659 do
1660 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001661 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001662 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001663 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001664 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001665 bit_offset += no_of_bits;
1666 } while (--nCount > 0);
1667 }
1668 else if (no_of_bits <= 16)
1669 {
1670 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1671 }
1672 else if (no_of_bits <= 32)
1673 {
1674 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1675 }
1676 else
1677 {
1678 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1679 }
1680 }
1681 else
1682 {
1683 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1684 }
1685 pDescr++;
1686 break;
1687 }
1688
1689 case CSN_VARIABLE_TARRAY_OFFSET:
1690 case CSN_VARIABLE_TARRAY:
1691 case CSN_TYPE_ARRAY:
1692 {
1693 gint16 Status;
1694 csnStream_t arT = *ar;
1695 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001696 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001697
1698 pui8 = pui8DATA(data, pDescr->offset);
1699 if (pDescr->type == CSN_VARIABLE_TARRAY)
1700 { /* Count specified in field */
1701 nCount = *pui8DATA(data, pDescr->i);
1702 }
1703 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1704 { /* Count specified in field */
1705 nCount = *pui8DATA(data, pDescr->i);
1706 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1707 }
1708
1709 while (nCount > 0)
1710 { /* resulting array of length 0 is possible
1711 * but no bits shall be read from bitstream
1712 */
1713
Harald Welte570f9132020-03-19 15:03:01 +01001714 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001715 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1716 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1717 if (Status >= 0)
1718 {
1719 pui8 += nSize;
1720 remaining_bits_len = arT.remaining_bits_len;
1721 bit_offset = arT.bit_offset;
1722
1723 }
1724 else
1725 {
1726 return Status;
1727 }
1728 nCount--;
1729 }
1730
1731 pDescr++;
1732 break;
1733 }
1734
1735 case CSN_BITMAP:
1736 { /* bitmap with given length. The result is left aligned! */
1737 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1738
1739 if (no_of_bits > 0)
1740 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +01001741 if (no_of_bits > remaining_bits_len)
1742 {
1743 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1744 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001745
1746 if (no_of_bits <= 32)
1747 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001748 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001749 {
1750 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001751 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001752 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001753 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001754 }
1755 else if (no_of_bits <= 64)
1756 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001757 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001758 {
1759 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001760 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001761 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001762 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001763 }
1764 else
1765 {
1766 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1767 }
1768
1769 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001770 bit_offset += no_of_bits;
1771 }
1772 /* bitmap was successfully extracted or it was empty */
1773
1774 pDescr++;
1775 break;
1776 }
1777
1778 case CSN_TYPE:
1779 {
1780 gint16 Status;
1781 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01001782 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001783 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1784 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01001785 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001786 if (Status >= 0)
1787 {
1788
1789 remaining_bits_len = arT.remaining_bits_len;
1790 bit_offset = arT.bit_offset;
1791 pDescr++;
1792 }
1793 else
1794 {
1795 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1796 return Status;
1797 }
1798
1799 break;
1800 }
1801
1802 case CSN_CHOICE:
1803 {
Vadim Yanitskiyfac83322020-05-23 17:33:07 +07001804 gint16 count = pDescr->i;
Anders Broman60bf8452020-01-24 17:35:48 +01001805 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001806
Vadim Yanitskiyfac83322020-05-23 17:33:07 +07001807 /* Make sure that the list of choice items is not empty */
1808 if (!count)
1809 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
1810 else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
1811 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
1812
Vadim Yanitskiy0614e932020-05-23 17:43:45 +07001813 /* Make sure that choice index is not out of range */
1814 pui8 = pui8DATA(data, pDescr->offset);
1815 if (*pui8 >= count)
1816 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1817
1818 pChoice += *pui8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001819 guint8 no_of_bits = pChoice->bits;
1820 guint8 value = pChoice->value;
Harald Welte570f9132020-03-19 15:03:01 +01001821 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001822 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001823
1824 CSN_DESCR descr[2];
1825 gint16 Status;
1826 csnStream_t arT = *ar;
1827
1828 descr[0] = pChoice->descr;
1829 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1830 descr[1].type = CSN_END;
1831 bit_offset += no_of_bits;
1832 remaining_bits_len -= no_of_bits;
1833
1834 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1835 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1836
1837 if (Status >= 0)
1838 {
1839 remaining_bits_len = arT.remaining_bits_len;
1840 bit_offset = arT.bit_offset;
1841 }
1842 else
1843 {
1844 return Status;
1845 }
1846
1847 pDescr++;
1848 break;
1849 }
1850
1851 case CSN_SERIALIZE:
1852 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001853 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001854 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001855 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001856 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001857 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001858
1859 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001860 lengthIndex = *writeIndex;
1861 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001862 bit_offset += length_len;
1863 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001864 arT.direction = 0;
1865 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1866 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001867
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001868 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
Harald Welte570f9132020-03-19 15:03:01 +01001869 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001870
1871 if (Status >= 0)
1872 {
1873 remaining_bits_len = arT.remaining_bits_len;
1874 bit_offset = arT.bit_offset;
1875 pDescr++;
1876 }
1877 else
1878 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001879 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001880 return Status;
1881 }
1882
1883 break;
1884 }
1885
1886 case CSN_UNION_LH:
1887 case CSN_UNION:
1888 {
1889 gint16 Bits;
1890 guint8 index;
1891 gint16 count = pDescr->i;
1892 const CSN_DESCR* pDescrNext = pDescr;
1893
1894 pDescrNext += count + 1; /* now this is next after the union */
1895 if ((count <= 0) || (count > 16))
1896 {
1897 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1898 }
1899
1900 /* Now get the bits to extract the index */
1901 Bits = ixBitsTab[count];
1902 index = 0;
1903
1904 /* Assign UnionType */
1905 pui8 = pui8DATA(data, pDescr->offset);
1906 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001907 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001908
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001909 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001910 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001911
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001912 while (Bits > 0)
1913 {
1914 index <<= 1;
1915
1916 if (CSN_UNION_LH == pDescr->type)
1917 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001918 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001919 }
1920 else
1921 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001922 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001923 }
1924
1925 remaining_bits_len--;
1926 bit_offset++;
1927 Bits--;
1928 }
1929
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001930 *writeIndex -= Bits;
1931 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001932
1933
1934 /* script index to continue on, limited in case we do not have a power of 2 */
1935 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +01001936 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001937
1938 switch (pDescr->type)
1939 { /* get the right element of the union based on computed index */
1940
1941 case CSN_BIT:
1942 {
1943 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001944 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001945 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001946 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001947 bit_offset++;
1948 pDescr++;
1949 break;
1950 }
1951
1952 case CSN_NULL:
1953 { /* Empty member! */
1954 pDescr++;
1955 break;
1956 }
1957
1958 case CSN_UINT:
1959 {
1960 guint8 no_of_bits = (guint8) pDescr->i;
1961 if (remaining_bits_len >= no_of_bits)
1962 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001963 if (no_of_bits <= 8)
1964 {
1965 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001966 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001967 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001968 }
1969 else if (no_of_bits <= 16)
1970 {
1971 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001972 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001973 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001974 }
1975 else if (no_of_bits <= 32)
1976 {
1977 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001978 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001979 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001980 }
1981 else
1982 {
1983 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1984 }
1985 }
1986 else
1987 {
1988 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1989 }
1990
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001991 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001992 bit_offset += no_of_bits;
1993 pDescr++;
1994 break;
1995 }
1996
1997 case CSN_UINT_OFFSET:
1998 {
1999 guint8 no_of_bits = (guint8) pDescr->i;
2000
2001 if (remaining_bits_len >= no_of_bits)
2002 {
2003 if (no_of_bits <= 8)
2004 {
2005 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002006 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002007 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002008 }
2009 else if (no_of_bits <= 16)
2010 {
2011 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002012 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002013 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002014 }
2015 else if (no_of_bits <= 32)
2016 {
2017 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002018 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002019 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002020 }
2021 else
2022 {
2023 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2024 }
2025 }
2026 else
2027 {
2028 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2029 }
2030
2031 remaining_bits_len -= no_of_bits;
2032 bit_offset += no_of_bits;
2033 pDescr++;
2034 break;
2035 }
2036
2037 case CSN_UINT_LH:
2038 {
2039 guint8 no_of_bits = (guint8) pDescr->i;
2040
2041 if (remaining_bits_len >= no_of_bits)
2042 {
2043 remaining_bits_len -= no_of_bits;
2044 if (no_of_bits <= 8)
2045 {
2046 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002047 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002048 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002049 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002050 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002051 *writeIndex -= no_of_bits;
2052 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002053 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002054
2055 }
2056 else
2057 {/* Maybe we should support more than 8 bits ? */
2058 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2059 }
2060 }
2061 else
2062 {
2063 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2064 }
2065
2066 remaining_bits_len -= no_of_bits;
2067 bit_offset += no_of_bits;
2068 pDescr++;
2069 break;
2070 }
2071
2072 case CSN_UINT_ARRAY:
2073 {
2074 guint8 no_of_bits = (guint8) pDescr->i;
2075 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2076
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002077 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002078 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2079 nCount = *pui16DATA(data, nCount);
2080 }
2081
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +01002082 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002083 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002084 if (no_of_bits <= 8)
2085 {
2086 pui8 = pui8DATA(data, pDescr->offset);
2087 do
2088 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002089 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002090 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002091 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002092 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002093 bit_offset += no_of_bits;
2094 } while (--nCount > 0);
2095 }
2096 else if (no_of_bits <= 16)
2097 {
2098 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2099 }
2100 else if (no_of_bits <= 32)
2101 {
2102 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2103 }
2104 else
2105 {
2106 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2107 }
2108 }
2109 else
2110 {
2111 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2112 }
2113 pDescr++;
2114 break;
2115 }
2116
2117 case CSN_VARIABLE_TARRAY_OFFSET:
2118 case CSN_VARIABLE_TARRAY:
2119 case CSN_TYPE_ARRAY:
2120 {
2121 gint16 Status;
2122 csnStream_t arT = *ar;
2123 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002124 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002125
2126 pui8 = pui8DATA(data, pDescr->offset);
2127 if (pDescr->type == CSN_VARIABLE_TARRAY)
2128 { /* Count specified in field */
2129 nCount = *pui8DATA(data, pDescr->i);
2130 }
2131 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2132 { /* Count specified in field */
2133 nCount = *pui8DATA(data, pDescr->i);
2134 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2135 }
2136
2137 while (nCount > 0)
2138 { /* resulting array of length 0 is possible
2139 * but no bits shall be read from bitstream
2140 */
2141
Harald Welte570f9132020-03-19 15:03:01 +01002142 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002143 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2144 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2145 if (Status >= 0)
2146 {
2147 pui8 += nSize;
2148 remaining_bits_len = arT.remaining_bits_len;
2149 bit_offset = arT.bit_offset;
2150 }
2151 else
2152 {
2153 return Status;
2154 }
2155 nCount--;
2156 }
2157
2158 pDescr++;
2159 break;
2160 }
2161
2162 case CSN_BITMAP:
2163 { /* bitmap with given length. The result is left aligned! */
2164 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2165
2166 if (no_of_bits > 0)
2167 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +01002168 if (no_of_bits > remaining_bits_len)
2169 {
2170 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2171 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002172
2173 if (no_of_bits <= 32)
2174 {
2175 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002176 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002177 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002178 }
2179 else if (no_of_bits <= 64)
2180 {
2181 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002182 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002183 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002184 }
2185 else
2186 {
2187 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2188 }
2189
2190 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002191 bit_offset += no_of_bits;
2192 }
2193 /* bitmap was successfully extracted or it was empty */
2194
2195 pDescr++;
2196 break;
2197 }
2198
2199 case CSN_TYPE:
2200 {
2201 gint16 Status;
2202 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01002203 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002204 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2205 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01002206 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002207 if (Status >= 0)
2208 {
2209 remaining_bits_len = arT.remaining_bits_len;
2210 bit_offset = arT.bit_offset;
2211 pDescr++;
2212 }
2213 else
2214 {
2215 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2216 return Status;
2217 }
2218
2219 break;
2220 }
2221
2222 default:
2223 { /* descriptions of union elements other than above are illegal */
2224 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2225 }
2226 }
2227
2228 pDescr = pDescrNext;
2229 break;
2230 }
2231
2232 case CSN_EXIST:
2233 case CSN_EXIST_LH:
2234 {
2235 guint8 fExist;
2236 unsigned exist = 0;
2237 pui8 = pui8DATA(data, pDescr->offset);
2238 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002239 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002240 writeIndex--;
2241 if (CSN_EXIST_LH == pDescr->type)
2242 {
2243 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2244 }
2245 else
2246 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002247 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002248 }
2249 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002250 bitvec_write_field(vector, writeIndex, fExist, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002251 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002252 remaining_bits_len--;
2253 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002254 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002255
2256 if (!exist)
2257 {
2258 ar->remaining_bits_len = remaining_bits_len;
2259 ar->bit_offset = bit_offset;
2260 return remaining_bits_len;
2261 }
2262 break;
2263 }
2264
2265 case CSN_NEXT_EXIST:
2266 {
2267 guint8 fExist;
2268
2269 pui8 = pui8DATA(data, pDescr->offset);
2270
2271 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002272 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002273 { /* no more bits to decode is fine here - end of message detected and allowed */
2274
2275 /* Skip i entries + this entry */
2276 pDescr += pDescr->i + 1;
2277
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002278 break;
2279 }
2280
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002281 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002282 fExist = *pui8;
Harald Welte570f9132020-03-19 15:03:01 +01002283 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002284
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002285 remaining_bits_len--;
2286 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002287
2288 if (fExist == 0)
2289 { /* Skip 'i' entries */
2290 pDescr += pDescr->i;
2291 }
2292
2293 pDescr++;
2294 break;
2295 }
2296
2297 case CSN_NEXT_EXIST_LH:
2298 {
2299 guint8 fExist;
2300 pui8 = pui8DATA(data, pDescr->offset);
2301
2302 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2303 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2304 { /* no more bits to decode is fine here - end of message detected and allowed */
2305
2306 /* skip 'i' entries + this entry */
2307 pDescr += pDescr->i + 1;
2308
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002309 /* set the data member to "not exist" */
2310 //*pui8 = 0;
2311 break;
2312 }
2313
2314 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002315 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002316 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002317 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002318 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002319 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002320 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002321
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002322 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002323 bit_offset++;
2324
2325 if (fExist == 0)
2326 { /* Skip 'i' entries */
2327 pDescr += pDescr->i;
2328 }
2329 pDescr++;
2330
2331 break;
2332 }
2333
2334 case CSN_VARIABLE_BITMAP_1:
2335 { /* Bitmap from here and to the end of message */
2336
2337 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2338
2339 /*no break -
2340 * with a length set we have a regular variable length bitmap so we continue */
2341 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002342 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002343 case CSN_VARIABLE_BITMAP:
2344 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2345 * <N: bit (5)> <bitmap: bit(N + offset)>
2346 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2347 * The result is right aligned!
2348 */
2349 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2350
2351 no_of_bits += pDescr->i; /* adjusted by offset */
2352
2353 if (no_of_bits > 0)
2354 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002355
2356 if (remaining_bits_len < 0)
2357 {
2358 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2359 }
2360
2361 { /* extract bits */
2362 guint8* pui8 = pui8DATA(data, pDescr->offset);
2363 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2364
2365 if (nB1 > 0)
2366 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002367 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002368 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002369 pui8++;
2370 no_of_bits -= nB1;
2371 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002372 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002373 }
2374
2375 /* remaining no_of_bits is a multiple of 8 or 0 */
2376 while (no_of_bits > 0)
2377 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002378 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002379 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002380 pui8++;
2381 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002382 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002383 }
2384 }
2385 }
2386 pDescr++;
2387 break;
2388 }
2389
2390 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2391 { /* Bitmap from here and to the end of message */
2392
2393 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2394
2395 /* no break -
2396 * with a length set we have a regular left aligned variable length bitmap so we continue
2397 */
2398 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002399 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002400 case CSN_LEFT_ALIGNED_VAR_BMP:
2401 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2402 * <N: bit (5)> <bitmap: bit(N + offset)>
2403 * bit array with length (in bits) specified in parameter (pDescr->descr)
2404 */
2405
2406 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2407
2408 no_of_bits += pDescr->i;/* size adjusted by offset */
2409
2410 if (no_of_bits > 0)
2411 {
2412 remaining_bits_len -= no_of_bits;
2413
2414 if (remaining_bits_len < 0)
2415 {
2416 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2417 }
2418
2419 { /* extract bits */
2420 guint8* pui8 = pui8DATA(data, pDescr->offset);
2421 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2422
2423 while (no_of_bits > 0)
2424 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002425 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002426 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002427 pui8++;
2428 no_of_bits -= 8;
2429 }
2430 if (nB1 > 0)
2431 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002432 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002433 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002434 pui8++;
2435 no_of_bits -= nB1;
2436 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2437 }
2438 }
2439
2440 }
2441
2442 /* bitmap was successfully extracted or it was empty */
2443 pDescr++;
2444 break;
2445 }
2446
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002447 case CSN_PADDING_BITS:
2448 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01002449 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002450 guint8 filler = 0x2b;
2451 if (remaining_bits_len > 0)
2452 {
2453 while (remaining_bits_len > 0)
2454 {
2455 guint8 bits_to_handle = remaining_bits_len%8;
2456 if (bits_to_handle > 0)
2457 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302458 /* section 11 of 44.060
2459 * The padding bits may be the 'null' string. Otherwise, the
2460 * padding bits starts with bit '0', followed by 'spare padding'
2461 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2462 */
2463 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002464 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Harald Welte570f9132020-03-19 15:03:01 +01002465 LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002466 remaining_bits_len -= bits_to_handle;
2467 bit_offset += bits_to_handle;
2468 }
2469 else if (bits_to_handle == 0)
2470 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002471 bitvec_write_field(vector, writeIndex, filler, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002472 LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002473 remaining_bits_len -= 8;
2474 bit_offset += 8;
2475 }
2476 }
2477 }
2478 if (remaining_bits_len < 0)
2479 {
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01002480 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002481 }
2482
2483 /* Padding was successfully extracted or it was empty */
2484 pDescr++;
2485 break;
2486 }
2487
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002488 case CSN_VARIABLE_ARRAY:
2489 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2490 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2491 * Array with length specified in parameter:
2492 * <count: bit (x)>
2493 * <list: octet(count + offset)>
2494 */
2495 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2496
2497 count += pDescr->i; /* Adjusted by offset */
2498
2499 if (count > 0)
2500 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002501 if (remaining_bits_len < 0)
2502 {
2503 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2504 }
2505
2506 pui8 = pui8DATA(data, pDescr->offset);
2507
2508 while (count > 0)
2509 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002510 bitvec_write_field(vector, writeIndex, *pui8, 8);
Pau Espin Pedrol74aa3522020-11-24 11:10:52 +01002511 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002512 pui8++;
2513 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002514 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002515 count--;
2516 }
2517 }
2518
2519 pDescr++;
2520 break;
2521 }
2522
2523 case CSN_RECURSIVE_ARRAY:
2524 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2525 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2526 * where <element> ::= bit(value)
2527 * <tag> ::= 0 | 1
2528 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2529 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2530 * REMARK: recursive way to specify an array but an iterative implementation!
2531 */
2532 gint16 no_of_bits = pDescr->i;
2533 guint8 ElementCount = 0;
2534 pui8 = pui8DATA(data, pDescr->offset);
2535 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2536 while (ElementCount > 0)
2537 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002538 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002539 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002540 bit_offset++;
2541 remaining_bits_len--;
2542
2543 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002544 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002545 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002546 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002547 ElementCount--;
2548
2549 if (remaining_bits_len < 0)
2550 {
2551 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2552 }
2553
2554 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002555 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002556 }
2557
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002558 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002559 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002560 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302561 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002562
2563 pDescr++;
2564 break;
2565 }
2566
2567 case CSN_RECURSIVE_TARRAY:
2568 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2569 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2570 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2571 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002572 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002573 guint8 ElementCount = 0;
2574 pui8 = pui8DATA(data, pDescr->offset);
2575 /* Store the counted number of elements of the array */
2576 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2577
2578 while (ElementCount > 0)
2579 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002580 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002581 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002582 bit_offset++;
2583
2584 remaining_bits_len--;
2585 ElementCount--;
2586
2587 { /* unpack the following data structure */
2588 csnStream_t arT = *ar;
2589 gint16 Status;
2590 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002591 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002592
2593 if (Status >= 0)
2594 { /* successful completion */
2595 pui8 += nSizeElement; /* -> to next data element */
2596 remaining_bits_len = arT.remaining_bits_len;
2597 bit_offset = arT.bit_offset;
2598 }
2599 else
2600 { /* something went awry */
2601 return Status;
2602 }
2603 }
2604
2605 if (remaining_bits_len < 0)
2606 {
2607 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2608 }
2609 }
2610
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002611 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002612 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002613 bit_offset++;
2614
2615 pDescr++;
2616 break;
2617 }
2618
2619 case CSN_RECURSIVE_TARRAY_2:
2620 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2621
2622 Tag = REVERSED_TAG;
2623
2624 /* NO break -
2625 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2626 */
2627 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002628 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002629 case CSN_RECURSIVE_TARRAY_1:
2630 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2631 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2632 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2633 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002634 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002635 guint8 ElementCount = 0;
2636 guint8 ElementNum = 0;
2637 csnStream_t arT = *ar;
2638 gint16 Status;
2639
2640 pui8 = pui8DATA(data, pDescr->offset);
2641 /* Store the count of the array */
2642 ElementCount = *pui8DATA(data, pDescr->i);
2643 ElementNum = ElementCount;
2644
2645 while (ElementCount > 0)
2646 { /* get data element */
2647 if (ElementCount != ElementNum)
2648 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002649 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002650 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002651 bit_offset++;
2652 remaining_bits_len--;
2653 }
2654 ElementCount--;
Harald Welte570f9132020-03-19 15:03:01 +01002655 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002656 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002657 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Harald Welte570f9132020-03-19 15:03:01 +01002658 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002659 if (Status >= 0)
2660 { /* successful completion */
2661 pui8 += nSizeElement; /* -> to next */
2662 remaining_bits_len = arT.remaining_bits_len;
2663 bit_offset = arT.bit_offset;
2664 }
2665 else
2666 { /* something went awry */
2667 return Status;
2668 }
2669
2670 if (remaining_bits_len < 0)
2671 {
2672 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2673 }
2674
2675 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002676 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002677 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002678 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002679 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2680 pDescr++;
2681 break;
2682 }
2683
2684 case CSN_FIXED:
2685 { /* Verify the fixed bits */
2686 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002687 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002688 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002689 remaining_bits_len -= no_of_bits;
2690 bit_offset += no_of_bits;
2691 pDescr++;
2692 break;
2693 }
2694
2695 case CSN_CALLBACK:
2696 {
Pau Espin Pedrolc9880b92021-05-28 18:41:19 +02002697 guint16 no_of_bits;
2698 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
2699 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
2700 no_of_bits = callback(vector, writeIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
2701 remaining_bits_len -= no_of_bits;
2702 bit_offset += no_of_bits;
2703 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002704 break;
2705 }
2706
2707 case CSN_TRAP_ERROR:
2708 {
2709 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2710 }
2711
2712 case CSN_END:
2713 {
2714 ar->remaining_bits_len = remaining_bits_len;
2715 ar->bit_offset = bit_offset;
2716 return remaining_bits_len;
2717 }
2718
2719 default:
2720 {
2721 assert(0);
2722 }
2723
2724 }
2725
2726 } while (remaining_bits_len >= 0);
2727
2728 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2729}