blob: 3db1e1343ecddfb200aad9ea4532087288a3848e [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040031#include <assert.h>
32#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020033#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
Pau Espin Pedrold636f742020-02-03 15:37:08 +010038#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030040
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030050static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
51
52
53/* Returns no_of_bits (up to 8) masked with 0x2B */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030054static guint8
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070055get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030056{
57 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
58 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
59 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
60 guint8 result;
61 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070062 *readIndex -= relative_bit_offset;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030063 if (bit_shift >= 0)
64 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070065 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
66 *readIndex-= bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030067 result &= maskBits[no_of_bits];
68 }
69 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010070 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070071 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030072 hight_part = (guint8) (hight_part << (-bit_shift));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070073 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
74 *readIndex = *readIndex - (8 - (-bit_shift));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030075 result |= hight_part;
76 }
77 return result;
78}
79
80/**
81 * ================================================================================================
82 * set initial/start values in help data structure used for packing/unpacking operation
83 * ================================================================================================
84 */
85void
86csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
87{
88 ar->remaining_bits_len = remaining_bits_len;
89 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040090 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030091}
92
Pau Espin Pedrold636f742020-02-03 15:37:08 +010093static const struct value_string csn1_error_names[] = {
94 { CSN_OK, "General 0" },
95 { CSN_ERROR_GENERAL, "General -1" },
96 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
97 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
98 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
99 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
Vadim Yanitskiyfee767f2020-02-11 05:28:02 +0700100 { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" },
101 { CSN_ERROR_INTERNAL, "INTERNAL" },
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100102 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
103 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
104 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300105};
106
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100107
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700108static gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100109 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300110{
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100111 /* Don't add trailing newline, top caller is responsible for appending it */
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100112 if (err != CSN_OK)
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700113 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %u)",
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100114 sz, get_value_string(csn1_error_names, err), err,
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700115 pDescr ? pDescr->sz : "-", *readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116 return err;
117}
118
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100119#define ProcessError(readIndex, sz, err, pDescr) \
120 ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
121
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300122
123/**
124 * ================================================================================================
125 * Return TRUE if tag in bit stream indicates existence of next list element,
126 * otherwise return FALSE.
127 * Will work for tag values equal to both 0 and 1.
128 * ================================================================================================
129 */
130
131static gboolean
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700132existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300133{
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700134 int res = bitvec_get_bit_pos(vector, (*readIndex)++);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300135 if (Tag == STANDARD_TAG)
136 {
137 return (res > 0);
138 }
139 return (res == 0);
140}
141
142
143gint16
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700144csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300145{
146 gint remaining_bits_len = ar->remaining_bits_len;
147 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100148 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300149 guint16* pui16;
150 guint32* pui32;
151 guint64* pui64;
152 guint8 Tag = STANDARD_TAG;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700153 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300154
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700155 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300156 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700157 return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300158 }
159
160 do
161 {
162 switch (pDescr->type)
163 {
164 case CSN_BIT:
165 {
166 if (remaining_bits_len > 0)
167 {
168 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700169 *pui8 = bitvec_read_field(vector, readIndex, 1);
Harald Welte570f9132020-03-19 15:03:01 +0100170 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300171 /* end add the bit value to protocol tree */
172 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400173 else if(pDescr->may_be_null)
174 {
175 pui8 = pui8DATA(data, pDescr->offset);
176 *pui8 = 0;
Harald Welte570f9132020-03-19 15:03:01 +0100177 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400178 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300179 else
180 {
181 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
182 }
183
184 pDescr++;
185 remaining_bits_len--;
186 bit_offset++;
187 break;
188 }
189
190 case CSN_NULL:
191 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100192 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300193 pDescr++;
194 break;
195 }
196
197 case CSN_UINT:
198 {
199 guint8 no_of_bits = (guint8) pDescr->i;
200
201 if (remaining_bits_len >= no_of_bits)
202 {
203 if (no_of_bits <= 8)
204 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700205 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300206 pui8 = pui8DATA(data, pDescr->offset);
207 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100208 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300209 }
210 else if (no_of_bits <= 16)
211 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700212 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300213 pui16 = pui16DATA(data, pDescr->offset);
214 *pui16 = ui16;
Harald Welte570f9132020-03-19 15:03:01 +0100215 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300216 }
217 else if (no_of_bits <= 32)
218 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700219 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300220 pui32 = pui32DATA(data, pDescr->offset);
221 *pui32 = ui32;
Harald Welte570f9132020-03-19 15:03:01 +0100222 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300223 }
224 else
225 {
226 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
227 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400228 remaining_bits_len -= no_of_bits;
229 bit_offset += no_of_bits;
230 }
231 else if(pDescr->may_be_null)
232 {
233 if (no_of_bits <= 8)
234 {
235 pui8 = pui8DATA(data, pDescr->offset);
236 *pui8 = 0;
237 }
238 else if (no_of_bits <= 16)
239 {
240 pui16 = pui16DATA(data, pDescr->offset);
241 *pui16 = 0;
242 }
243 else if (no_of_bits <= 32)
244 {
245 pui32 = pui32DATA(data, pDescr->offset);
246 *pui32 = 0;
247 }
Harald Welte570f9132020-03-19 15:03:01 +0100248 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300249 }
250 else
251 {
252 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
253 }
254
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300255 pDescr++;
256 break;
257 }
258
259 case CSN_UINT_OFFSET:
260 {
261 guint8 no_of_bits = (guint8) pDescr->i;
262
263 if (remaining_bits_len >= no_of_bits)
264 {
265 if (no_of_bits <= 8)
266 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700267 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300268 pui8 = pui8DATA(data, pDescr->offset);
269 *pui8 = ui8 + (guint8)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100270 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300271 }
272 else if (no_of_bits <= 16)
273 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700274 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300275 pui16 = pui16DATA(data, pDescr->offset);
276 *pui16 = ui16 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100277 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300278 }
279 else if (no_of_bits <= 32)
280 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700281 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300282 pui32 = pui32DATA(data, pDescr->offset);
283 *pui32 = ui32 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100284 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300285 }
286 else
287 {
288 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
289 }
290 }
291 else
292 {
293 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
294 }
295
296 remaining_bits_len -= no_of_bits;
297 bit_offset += no_of_bits;
298 pDescr++;
299 break;
300 }
301
302 case CSN_UINT_LH:
303 {
304 guint8 no_of_bits = (guint8) pDescr->i;
305
306 if (remaining_bits_len >= no_of_bits)
307 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300308 if (no_of_bits <= 8)
309 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100310 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300311 pui8 = pui8DATA(data, pDescr->offset);
312 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100313 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300314 }
315 else
316 {/* Maybe we should support more than 8 bits ? */
317 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
318 }
319 }
320 else
321 {
322 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
323 }
324
325 remaining_bits_len -= no_of_bits;
326 bit_offset += no_of_bits;
327 pDescr++;
328 break;
329 }
330
331 case CSN_UINT_ARRAY:
332 {
333 guint8 no_of_bits = (guint8) pDescr->i;
334 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
335
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100336 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300337 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
338 nCount = *pui16DATA(data, nCount);
339 }
340
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +0100341 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300342 {
343 remaining_bits_len -= (no_of_bits*nCount);
344 if (no_of_bits <= 8)
345 {
346 pui8 = pui8DATA(data, pDescr->offset);
347 do
348 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700349 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100350 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300351 pui8++;
352 bit_offset += no_of_bits;
353 } while (--nCount > 0);
354 }
355 else if (no_of_bits <= 16)
356 {
357 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
358 }
359 else if (no_of_bits <= 32)
360 {
361 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
362 }
363 else
364 {
365 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
366 }
367 }
368 else
369 {
370 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
371 }
372 pDescr++;
373 break;
374 }
375
376 case CSN_VARIABLE_TARRAY_OFFSET:
377 case CSN_VARIABLE_TARRAY:
378 case CSN_TYPE_ARRAY:
379 {
380 gint16 Status;
381 csnStream_t arT = *ar;
382 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100383 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300384
385 pui8 = pui8DATA(data, pDescr->offset);
386 if (pDescr->type == CSN_VARIABLE_TARRAY)
387 { /* Count specified in field */
388 nCount = *pui8DATA(data, pDescr->i);
389 }
390 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
391 { /* Count specified in field */
392 nCount = *pui8DATA(data, pDescr->i);
393 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
394 }
395
396 while (nCount > 0)
397 { /* resulting array of length 0 is possible
398 * but no bits shall be read from bitstream
399 */
400
Harald Welte570f9132020-03-19 15:03:01 +0100401 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300402 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100403 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300404 if (Status >= 0)
405 {
406 pui8 += nSize;
407 remaining_bits_len = arT.remaining_bits_len;
408 bit_offset = arT.bit_offset;
409 }
410 else
411 {
412 return Status;
413 }
414 nCount--;
415 }
416
417 pDescr++;
418 break;
419 }
420
421 case CSN_BITMAP:
422 { /* bitmap with given length. The result is left aligned! */
423 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
424
425 if (no_of_bits > 0)
426 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +0100427 if (no_of_bits > remaining_bits_len)
428 {
429 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
430 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300431
432 if (no_of_bits <= 32)
433 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700434 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400435 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700436 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 pui8 = pui8DATA(data, pDescr->offset+ib);
438 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100439 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400440 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300441 }
442 else if (no_of_bits <= 64)
443 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700444 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400445 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700446 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 pui8 = pui8DATA(data, pDescr->offset+ib);
448 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100449 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400450 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300451 }
452 else
453 {
454 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
455 }
456
457 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300458 bit_offset += no_of_bits;
459 }
460 /* bitmap was successfully extracted or it was empty */
461
462 pDescr++;
463 break;
464 }
465
466 case CSN_TYPE:
467 {
468 gint16 Status;
469 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +0100470 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300471 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100472 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +0100473 LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300474 if (Status >= 0)
475 {
476 remaining_bits_len = arT.remaining_bits_len;
477 bit_offset = arT.bit_offset;
478 pDescr++;
479 }
480 else
481 {
482 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
483 return Status;
484 }
485
486 break;
487 }
488
489 case CSN_CHOICE:
490 {
491 gint16 count = pDescr->i;
492 guint8 i = 0;
493 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
494
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700495 /* Make sure that the list of choice items is not empty */
496 if (!count)
497 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
498
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300499 while (count > 0)
500 {
501 guint8 no_of_bits = pChoice->bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700502 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300503 if (value == pChoice->value)
504 {
505 CSN_DESCR descr[2];
506 gint16 Status;
507 csnStream_t arT = *ar;
508
509 descr[0] = pChoice->descr;
510 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
511 descr[1].type = CSN_END;
512 pui8 = pui8DATA(data, pDescr->offset);
513 *pui8 = i;
Harald Welte570f9132020-03-19 15:03:01 +0100514 LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100515 if (!pChoice->keep_bits) {
516 bit_offset += no_of_bits;
517 remaining_bits_len -= no_of_bits;
518 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300519
520 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100521 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300522
523 if (Status >= 0)
524 {
525 remaining_bits_len = arT.remaining_bits_len;
526 bit_offset = arT.bit_offset;
527 }
528 else
529 {
530 return Status;
531 }
532 break;
533 }
534
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700535 *readIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300536 count--;
537 pChoice++;
538 i++;
539 }
540
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700541 /* Neither of the choice items matched => unknown value */
542 if (!count)
543 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
544
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300545 pDescr++;
546 break;
547 }
548
549 case CSN_SERIALIZE:
550 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100551 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300552 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400553 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300554 gint16 Status = -1;
555
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700556 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300557
Harald Welte570f9132020-03-19 15:03:01 +0100558 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400559 bit_offset += length_len;
560 remaining_bits_len -= length_len;
561
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100562 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100563 arT.direction = 1;
Harald Welte570f9132020-03-19 15:03:01 +0100564 LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100565 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300566
567 if (Status >= 0)
568 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100569 if (length > 0) {
570 remaining_bits_len -= length;
571 bit_offset += length;
572 } else {
573 remaining_bits_len = arT.remaining_bits_len;
574 bit_offset = arT.bit_offset;
575 }
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700576
577 /* Skip bits not handled by serialize(), if any */
578 if (Status > 0) {
Harald Welte570f9132020-03-19 15:03:01 +0100579 LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700580 *readIndex += Status;
581 }
582
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300583 pDescr++;
584 }
585 else
586 {
587 /* Has already been processed: */
588 return Status;
589 }
590
591 break;
592 }
593
594 case CSN_UNION_LH:
595 case CSN_UNION:
596 {
597 gint16 Bits;
598 guint8 index;
599 gint16 count = pDescr->i;
600 const CSN_DESCR* pDescrNext = pDescr;
601
602 pDescrNext += count + 1; /* now this is next after the union */
603 if ((count <= 0) || (count > 16))
604 {
605 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
606 }
607
608 /* Now get the bits to extract the index */
609 Bits = ixBitsTab[count];
610 index = 0;
611
612 while (Bits > 0)
613 {
614 index <<= 1;
615
616 if (CSN_UNION_LH == pDescr->type)
617 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700618 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300619 }
620 else
621 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700622 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300623 }
624 remaining_bits_len--;
625 bit_offset++;
626 Bits--;
627 }
628
629 /* Assign UnionType */
630 pui8 = pui8DATA(data, pDescr->offset);
631 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100632
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300633
634 /* script index to continue on, limited in case we do not have a power of 2 */
635 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +0100636 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300637
638 switch (pDescr->type)
639 { /* get the right element of the union based on computed index */
640
641 case CSN_BIT:
642 {
643 pui8 = pui8DATA(data, pDescr->offset);
644 *pui8 = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700645 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300646 {
647 *pui8 = 0x01;
648 }
Harald Welte570f9132020-03-19 15:03:01 +0100649 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300650 remaining_bits_len -= 1;
651 bit_offset++;
652 pDescr++;
653 break;
654 }
655
656 case CSN_NULL:
657 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100658 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300659 pDescr++;
660 break;
661 }
662
663 case CSN_UINT:
664 {
665 guint8 no_of_bits = (guint8) pDescr->i;
666 if (remaining_bits_len >= no_of_bits)
667 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300668 if (no_of_bits <= 8)
669 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700670 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300671 pui8 = pui8DATA(data, pDescr->offset);
672 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100673 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300674 }
675 else if (no_of_bits <= 16)
676 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700677 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300678 pui16 = pui16DATA(data, pDescr->offset);
679 *pui16 = ui16;
Harald Welte570f9132020-03-19 15:03:01 +0100680 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300681 }
682 else if (no_of_bits <= 32)
683 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700684 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300685 pui32 = pui32DATA(data, pDescr->offset);
686 *pui32 = ui32;
Harald Welte570f9132020-03-19 15:03:01 +0100687 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300688 }
689 else
690 {
691 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
692 }
693 }
694 else
695 {
696 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
697 }
698
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700699 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300700 bit_offset += no_of_bits;
701 pDescr++;
702 break;
703 }
704
705 case CSN_UINT_OFFSET:
706 {
707 guint8 no_of_bits = (guint8) pDescr->i;
708
709 if (remaining_bits_len >= no_of_bits)
710 {
711 if (no_of_bits <= 8)
712 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700713 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300714 pui8 = pui8DATA(data, pDescr->offset);
715 *pui8 = ui8 + (guint8)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100716 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300717 }
718 else if (no_of_bits <= 16)
719 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700720 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300721 pui16 = pui16DATA(data, pDescr->offset);
722 *pui16 = ui16 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100723 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300724 }
725 else if (no_of_bits <= 32)
726 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700727 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300728 pui32 = pui32DATA(data, pDescr->offset);
729 *pui32 = ui32 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100730 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300731 }
732 else
733 {
734 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
735 }
736 }
737 else
738 {
739 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
740 }
741
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700742 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300743 bit_offset += no_of_bits;
744 pDescr++;
745 break;
746 }
747
748 case CSN_UINT_LH:
749 {
750 guint8 no_of_bits = (guint8) pDescr->i;
751
752 if (remaining_bits_len >= no_of_bits)
753 {
754 if (no_of_bits <= 8)
755 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100756 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300757 pui8 = pui8DATA(data, pDescr->offset);
758 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100759 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300760 }
761 else
762 { /* Maybe we should support more than 8 bits ? */
763 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
764 }
765 }
766 else
767 {
768 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
769 }
770
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700771 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300772 bit_offset += no_of_bits;
773 pDescr++;
774 break;
775 }
776
777 case CSN_UINT_ARRAY:
778 {
779 guint8 no_of_bits = (guint8) pDescr->i;
780 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
781
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100782 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300783 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
784 nCount = *pui16DATA(data, nCount);
785 }
786
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +0100787 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300788 {
789 remaining_bits_len -= (no_of_bits * nCount);
790 if (no_of_bits <= 8)
791 {
792 pui8 = pui8DATA(data, pDescr->offset);
793
794 while (nCount > 0)
795 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700796 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100797 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300798 pui8++;
799 bit_offset += no_of_bits;
800 nCount--;
801 }
802 }
803 else if (no_of_bits <= 16)
804 {
805 pui16 = pui16DATA(data, pDescr->offset);
806
807 while (nCount > 0)
808 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700809 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100810 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300811 pui16++;
812 bit_offset += no_of_bits;
813 nCount--;
814 }
815 }
816 else if (no_of_bits <= 32)
817 { /* not supported */
818 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
819 }
820 else
821 {
822 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
823 }
824 }
825 else
826 {
827 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
828 }
829
830 pDescr++;
831 break;
832 }
833
834 case CSN_VARIABLE_TARRAY_OFFSET:
835 case CSN_VARIABLE_TARRAY:
836 case CSN_TYPE_ARRAY:
837 {
838 gint16 Status;
839 csnStream_t arT = *ar;
840 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100841 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300842
843 pui8 = pui8DATA(data, pDescr->offset);
844
845 if (CSN_VARIABLE_TARRAY == pDescr->type)
846 { /* Count specified in field */
847 nCount = *pui8DATA(data, pDescr->i);
848 }
849 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
850 { /* Count specified in field */
851 nCount = *pui8DATA(data, pDescr->i);
852 nCount--; /* Offset 1 */
853 }
854
855 while (nCount--) /* Changed to handle length = 0. */
856 {
Harald Welte570f9132020-03-19 15:03:01 +0100857 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300858 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100859 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300860 if (Status >= 0)
861 {
862 pui8 += nSize;
863 remaining_bits_len = arT.remaining_bits_len;
864 bit_offset = arT.bit_offset;
865 }
866 else
867 {
868 return Status;
869 }
870 }
871
872 pDescr++;
873 break;
874 }
875
876 case CSN_BITMAP:
877 { /* bitmap with given length. The result is left aligned! */
878 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
879
880 if (no_of_bits > 0)
881 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +0100882 if (no_of_bits > remaining_bits_len)
883 {
884 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
885 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300886
887 if (no_of_bits <= 32)
888 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700889 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300890 pui32 = pui32DATA(data, pDescr->offset);
891 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300892 }
893 else if (no_of_bits <= 64)
894 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700895 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300896 pui64 = pui64DATA(data, pDescr->offset);
897 *pui64 = ui64;
Harald Welte570f9132020-03-19 15:03:01 +0100898 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300899 }
900 else
901 {
902 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
903 }
904
905 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300906 bit_offset += no_of_bits;
907 }
908 /* bitmap was successfully extracted or it was empty */
909
910 pDescr++;
911 break;
912 }
913
914 case CSN_TYPE:
915 {
916 gint16 Status;
917 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +0100918 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300919 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100920 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +0100921 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300922 if (Status >= 0)
923 {
924 remaining_bits_len = arT.remaining_bits_len;
925 bit_offset = arT.bit_offset;
926 pDescr++;
927 }
928 else
929 { /* return error code Has already been processed: */
930 return Status;
931 }
932
933 break;
934 }
935
936 default:
937 { /* descriptions of union elements other than above are illegal */
938 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
939 }
940 }
941
942 pDescr = pDescrNext;
943 break;
944 }
945
946 case CSN_EXIST:
947 case CSN_EXIST_LH:
948 {
949 guint8 fExist;
950
951 pui8 = pui8DATA(data, pDescr->offset);
952
953 if (CSN_EXIST_LH == pDescr->type)
954 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100955 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300956 }
957 else
958 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700959 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300960 }
961
962 *pui8 = fExist;
Harald Welte570f9132020-03-19 15:03:01 +0100963 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300964 pDescr++;
Vadim Yanitskiyd8e5e8b2020-02-17 18:16:20 +0700965 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300966 remaining_bits_len -= 1;
967
968 if (!fExist)
969 {
970 ar->remaining_bits_len = remaining_bits_len;
971 ar->bit_offset = bit_offset;
972 return remaining_bits_len;
973 }
974
975 break;
976 }
977
978 case CSN_NEXT_EXIST:
979 {
980 guint8 fExist;
981
982 pui8 = pui8DATA(data, pDescr->offset);
983
984 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400985 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300986 { /* no more bits to decode is fine here - end of message detected and allowed */
987
988 /* Skip i entries + this entry */
989 pDescr += pDescr->i + 1;
990
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300991 /* Set the data member to "not exist" */
992 *pui8 = 0;
993 break;
994 }
995
996 /* the "regular" M_NEXT_EXIST description element */
997
998 fExist = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700999 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001000 {
1001 fExist = 0x01;
1002 }
1003
1004 *pui8 = fExist;
1005 remaining_bits_len -= 1;
Harald Welte570f9132020-03-19 15:03:01 +01001006 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001007 ++bit_offset;
1008
1009 if (fExist == 0)
1010 { /* Skip 'i' entries */
1011 pDescr += pDescr->i;
1012 }
1013
1014 pDescr++;
1015 break;
1016 }
1017
1018 case CSN_NEXT_EXIST_LH:
1019 {
1020 guint8 fExist;
1021 pui8 = pui8DATA(data, pDescr->offset);
1022
1023 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1024 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1025 { /* no more bits to decode is fine here - end of message detected and allowed */
1026
1027 /* skip 'i' entries + this entry */
1028 pDescr += pDescr->i + 1;
1029
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001030 /* set the data member to "not exist" */
1031 *pui8 = 0;
1032 break;
1033 }
1034
1035 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001036 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001037 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001038 *pui8++ = fExist;
1039 remaining_bits_len -= 1;
1040
1041 bit_offset++;
1042
1043 if (fExist == 0)
1044 { /* Skip 'i' entries */
1045 pDescr += pDescr->i;
1046 }
1047 pDescr++;
1048
1049 break;
1050 }
1051
1052 case CSN_VARIABLE_BITMAP_1:
1053 { /* Bitmap from here and to the end of message */
1054
1055 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1056
1057 /*no break -
1058 * with a length set we have a regular variable length bitmap so we continue */
1059 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001060 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001061 case CSN_VARIABLE_BITMAP:
1062 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1063 * <N: bit (5)> <bitmap: bit(N + offset)>
1064 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1065 * The result is right aligned!
1066 */
1067 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1068
1069 no_of_bits += pDescr->i; /* adjusted by offset */
1070
1071 if (no_of_bits > 0)
1072 {
1073 remaining_bits_len -= no_of_bits;
1074
1075 if (remaining_bits_len < 0)
1076 {
1077 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1078 }
1079
1080 { /* extract bits */
1081 guint8* pui8 = pui8DATA(data, pDescr->offset);
1082 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1083
1084 if (nB1 > 0)
1085 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001086 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01001087 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001088 pui8++;
1089 no_of_bits -= nB1;
1090 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1091 }
1092
1093 /* remaining no_of_bits is a multiple of 8 or 0 */
1094 while (no_of_bits > 0)
1095 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001096 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001097 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001098 pui8++;
1099 no_of_bits -= 8;
1100 }
1101 }
1102 }
1103 pDescr++;
1104 break;
1105 }
1106
1107 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1108 { /* Bitmap from here and to the end of message */
1109
1110 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1111
1112 /* no break -
1113 * with a length set we have a regular left aligned variable length bitmap so we continue
1114 */
1115 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001116 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001117 case CSN_LEFT_ALIGNED_VAR_BMP:
1118 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1119 * <N: bit (5)> <bitmap: bit(N + offset)>
1120 * bit array with length (in bits) specified in parameter (pDescr->descr)
1121 */
1122 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1123
1124 no_of_bits += pDescr->i;/* size adjusted by offset */
1125
1126 if (no_of_bits > 0)
1127 {
1128 remaining_bits_len -= no_of_bits;
1129
1130 if (remaining_bits_len < 0)
1131 {
1132 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1133 }
1134
1135 { /* extract bits */
1136 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001137
Neels Hofmeyr02415262016-09-02 02:15:26 +02001138 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001139 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001140 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001141 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001142 pui8++;
1143 no_of_bits -= 8;
1144 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001145 if (no_of_bits > 0)
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01001146 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001147 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001148 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001149 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001150 bit_offset += no_of_bits;
1151 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001152 }
1153 }
1154 }
1155
1156 /* bitmap was successfully extracted or it was empty */
1157 pDescr++;
1158 break;
1159 }
1160
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001161 case CSN_PADDING_BITS:
1162 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01001163 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001164 if (remaining_bits_len > 0)
1165 {
1166 while (remaining_bits_len > 0)
1167 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001168 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001169 if (bits_to_handle > 0)
1170 {
Harald Welte570f9132020-03-19 15:03:01 +01001171 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001172 remaining_bits_len -= bits_to_handle;
1173 bit_offset += bits_to_handle;
1174 }
1175 else if (bits_to_handle == 0)
1176 {
Harald Welte570f9132020-03-19 15:03:01 +01001177 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001178 remaining_bits_len -= 8;
1179 bit_offset += 8;
1180 }
1181 }
1182 }
1183 if (remaining_bits_len < 0)
1184 {
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01001185 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001186 }
1187
1188 /* Padding was successfully extracted or it was empty */
1189 pDescr++;
1190 break;
1191 }
1192
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001193 case CSN_VARIABLE_ARRAY:
1194 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1195 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1196 * Array with length specified in parameter:
1197 * <count: bit (x)>
1198 * <list: octet(count + offset)>
1199 */
1200 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1201
1202 count += pDescr->i; /* Adjusted by offset */
1203
1204 if (count > 0)
1205 {
1206 remaining_bits_len -= count * 8;
1207
1208 if (remaining_bits_len < 0)
1209 {
1210 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1211 }
1212
1213 pui8 = pui8DATA(data, pDescr->offset);
1214
1215 while (count > 0)
1216 {
1217 readIndex -= 8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001218 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001219 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001220 pui8++;
1221 bit_offset += 8;
1222 count--;
1223 }
1224 }
1225
1226 pDescr++;
1227 break;
1228 }
1229
1230 case CSN_RECURSIVE_ARRAY:
1231 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1232 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1233 * where <element> ::= bit(value)
1234 * <tag> ::= 0 | 1
1235 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1236 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1237 * REMARK: recursive way to specify an array but an iterative implementation!
1238 */
1239 gint16 no_of_bits = pDescr->i;
1240 guint8 ElementCount = 0;
1241
1242 pui8 = pui8DATA(data, pDescr->offset);
1243
Alexander Couzensccde5c92017-02-04 03:10:08 +01001244 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001245 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001246 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001247 bit_offset++;
1248 remaining_bits_len--;
1249
1250 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001251 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001252 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001253 pui8++;
1254 remaining_bits_len -= no_of_bits;
1255 ElementCount++;
1256
1257 if (remaining_bits_len < 0)
1258 {
1259 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1260 }
1261
1262 bit_offset += no_of_bits;
1263 }
1264
Harald Welte570f9132020-03-19 15:03:01 +01001265 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001266 /* existNextElement() returned FALSE, 1 bit consumed */
1267 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001268 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001269
1270 /* Store the counted number of elements of the array */
1271 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1272
1273 pDescr++;
1274 break;
1275 }
1276
1277 case CSN_RECURSIVE_TARRAY:
1278 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1279 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001280 * {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 +03001281 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001282 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001283 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001284 guint8 ElementCount = 0;
1285 pui8 = pui8DATA(data, pDescr->offset);
1286
Alexander Couzensccde5c92017-02-04 03:10:08 +01001287 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001288 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001289 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001290 /* existNextElement() returned TRUE, 1 bit consumed */
1291 bit_offset++;
1292 remaining_bits_len--;
1293 ElementCount++;
1294
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001295 if (ElementCount > nSizeArray)
1296 {
1297 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1298 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1299 }
1300
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001301 { /* unpack the following data structure */
1302 csnStream_t arT = *ar;
1303 gint16 Status;
1304 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001305 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001306
1307 if (Status >= 0)
1308 { /* successful completion */
1309 pui8 += nSizeElement; /* -> to next data element */
1310 remaining_bits_len = arT.remaining_bits_len;
1311 bit_offset = arT.bit_offset;
1312 }
1313 else
1314 { /* something went awry */
1315 return Status;
1316 }
1317 }
1318
1319 if (remaining_bits_len < 0)
1320 {
1321 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1322 }
1323 }
1324
Harald Welte570f9132020-03-19 15:03:01 +01001325 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001326
1327 /* existNextElement() returned FALSE, 1 bit consumed */
Vadim Yanitskiye87066d2020-02-17 18:02:32 +07001328 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001329 bit_offset++;
1330
1331 /* Store the counted number of elements of the array */
1332 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1333
1334 pDescr++;
1335 break;
1336 }
1337
1338 case CSN_RECURSIVE_TARRAY_2:
1339 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1340
1341 Tag = REVERSED_TAG;
1342
1343 /* NO break -
1344 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1345 */
1346 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001347 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001348 case CSN_RECURSIVE_TARRAY_1:
1349 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1350 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001351 * {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 +03001352 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001353 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001354 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001355 guint8 ElementCount = 0;
1356 csnStream_t arT = *ar;
1357 gboolean EndOfList = FALSE;
1358 gint16 Status;
1359 pui8 = pui8DATA(data, pDescr->offset);
1360
1361 do
1362 { /* get data element */
1363 ElementCount++;
1364
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001365 if (ElementCount > nSizeArray)
1366 {
1367 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1368 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1369 }
1370
Harald Welte570f9132020-03-19 15:03:01 +01001371 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001372
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001373 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001374 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001375
1376 if (Status >= 0)
1377 { /* successful completion */
1378 pui8 += nSizeElement; /* -> to next */
1379 remaining_bits_len = arT.remaining_bits_len;
1380 bit_offset = arT.bit_offset;
1381 }
1382 else
1383 { /* something went awry */
1384 return Status;
1385 }
1386
1387 if (remaining_bits_len < 0)
1388 {
1389 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1390 }
1391
1392 /* control of next element's tag */
Harald Welte570f9132020-03-19 15:03:01 +01001393 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001394 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001395
1396 bit_offset++;
1397 remaining_bits_len--; /* 1 bit consumed (tag) */
1398 } while (!EndOfList);
1399
1400
1401 /* Store the count of the array */
1402 *pui8DATA(data, pDescr->i) = ElementCount;
1403 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1404 pDescr++;
1405 break;
1406 }
1407
1408 case CSN_FIXED:
1409 { /* Verify the fixed bits */
1410 guint8 no_of_bits = (guint8) pDescr->i;
1411 guint32 ui32;
1412
1413 if (no_of_bits <= 32)
1414 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001415 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001416 }
1417 else
1418 {
1419 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1420 }
1421 if (ui32 != (unsigned)(gint32)pDescr->offset)
1422 {
1423 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1424 }
1425
Harald Welte570f9132020-03-19 15:03:01 +01001426 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001427 remaining_bits_len -= no_of_bits;
1428 bit_offset += no_of_bits;
1429 pDescr++;
1430 break;
1431 }
1432
1433 case CSN_CALLBACK:
1434 {
Pau Espin Pedrolf3ac06b2020-03-26 18:13:19 +01001435 guint16 no_of_bits;
1436 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1437 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
1438 no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
1439 remaining_bits_len -= no_of_bits;
1440 bit_offset += no_of_bits;
1441 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001442 break;
1443 }
1444
1445 case CSN_TRAP_ERROR:
1446 {
1447 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1448 }
1449
1450 case CSN_END:
1451 {
1452 ar->remaining_bits_len = remaining_bits_len;
1453 ar->bit_offset = bit_offset;
1454 return remaining_bits_len;
1455 }
1456
1457 default:
1458 {
1459 assert(0);
1460 }
1461
1462
1463 }
1464
1465 } while (remaining_bits_len >= 0);
1466
1467 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1468}
1469
1470
1471
1472
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001473gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001474{
1475 gint remaining_bits_len = ar->remaining_bits_len;
1476 gint bit_offset = ar->bit_offset;
1477 guint8* pui8;
1478 guint16* pui16;
1479 guint32* pui32;
1480 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001481 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001482
1483 guint8 Tag = STANDARD_TAG;
1484
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001485 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001486 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001487 return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001488 }
1489
1490 do
1491 {
1492 switch (pDescr->type)
1493 {
1494 case CSN_BIT:
1495 {
1496 if (remaining_bits_len > 0)
1497 {
1498 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001499 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001500 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001501 /* end add the bit value to protocol tree */
1502 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001503 else if(pDescr->may_be_null)
1504 {
Harald Welte570f9132020-03-19 15:03:01 +01001505 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001506 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001507 else
1508 {
1509 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1510 }
1511
1512 pDescr++;
1513 remaining_bits_len--;
1514 bit_offset++;
1515 break;
1516 }
1517
1518 case CSN_NULL:
1519 { /* Empty member! */
1520 pDescr++;
1521 break;
1522 }
1523
1524 case CSN_UINT:
1525 {
1526 guint8 no_of_bits = (guint8) pDescr->i;
1527
1528 if (remaining_bits_len >= no_of_bits)
1529 {
1530 if (no_of_bits <= 8)
1531 {
1532 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001533 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001534 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001535 }
1536 else if (no_of_bits <= 16)
1537 {
1538 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001539 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001540 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001541 }
1542 else if (no_of_bits <= 32)
1543 {
1544 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001545 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001546 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001547 }
1548 else
1549 {
1550 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1551 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001552
1553 remaining_bits_len -= no_of_bits;
1554 bit_offset += no_of_bits;
1555 }
1556 else if(pDescr->may_be_null)
1557 {
Harald Welte570f9132020-03-19 15:03:01 +01001558 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001559 }
1560 else
1561 {
1562 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1563 }
1564
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001565 pDescr++;
1566 break;
1567 }
1568
1569 case CSN_UINT_OFFSET:
1570 {
1571 guint8 no_of_bits = (guint8) pDescr->i;
1572
1573 if (remaining_bits_len >= no_of_bits)
1574 {
1575 if (no_of_bits <= 8)
1576 {
1577 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001578 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001579 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001580 }
1581 else if (no_of_bits <= 16)
1582 {
1583 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001584 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001585 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001586 }
1587 else if (no_of_bits <= 32)
1588 {
1589 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001590 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001591 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001592 }
1593 else
1594 {
1595 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1596 }
1597 }
1598 else
1599 {
1600 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1601 }
1602
1603 remaining_bits_len -= no_of_bits;
1604 bit_offset += no_of_bits;
1605 pDescr++;
1606 break;
1607 }
1608
1609 case CSN_UINT_LH:
1610 {
1611 guint8 no_of_bits = (guint8) pDescr->i;
1612
1613 if (remaining_bits_len >= no_of_bits)
1614 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001615 if (no_of_bits <= 8)
1616 {
1617 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001618 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001619 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001620 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001621 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001622 *writeIndex -= no_of_bits;
1623 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001624 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001625
1626 }
1627 else
1628 {/* Maybe we should support more than 8 bits ? */
1629 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1630 }
1631 }
1632 else
1633 {
1634 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1635 }
1636
1637 remaining_bits_len -= no_of_bits;
1638 bit_offset += no_of_bits;
1639 pDescr++;
1640 break;
1641 }
1642
1643 case CSN_UINT_ARRAY:
1644 {
1645 guint8 no_of_bits = (guint8) pDescr->i;
1646 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1647
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001648 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001649 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1650 nCount = *pui16DATA(data, nCount);
1651 }
1652
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +01001653 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001654 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001655 if (no_of_bits <= 8)
1656 {
1657 pui8 = pui8DATA(data, pDescr->offset);
1658 do
1659 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001660 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001661 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001662 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001663 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001664 bit_offset += no_of_bits;
1665 } while (--nCount > 0);
1666 }
1667 else if (no_of_bits <= 16)
1668 {
1669 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1670 }
1671 else if (no_of_bits <= 32)
1672 {
1673 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1674 }
1675 else
1676 {
1677 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1678 }
1679 }
1680 else
1681 {
1682 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1683 }
1684 pDescr++;
1685 break;
1686 }
1687
1688 case CSN_VARIABLE_TARRAY_OFFSET:
1689 case CSN_VARIABLE_TARRAY:
1690 case CSN_TYPE_ARRAY:
1691 {
1692 gint16 Status;
1693 csnStream_t arT = *ar;
1694 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001695 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001696
1697 pui8 = pui8DATA(data, pDescr->offset);
1698 if (pDescr->type == CSN_VARIABLE_TARRAY)
1699 { /* Count specified in field */
1700 nCount = *pui8DATA(data, pDescr->i);
1701 }
1702 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1703 { /* Count specified in field */
1704 nCount = *pui8DATA(data, pDescr->i);
1705 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1706 }
1707
1708 while (nCount > 0)
1709 { /* resulting array of length 0 is possible
1710 * but no bits shall be read from bitstream
1711 */
1712
Harald Welte570f9132020-03-19 15:03:01 +01001713 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001714 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1715 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1716 if (Status >= 0)
1717 {
1718 pui8 += nSize;
1719 remaining_bits_len = arT.remaining_bits_len;
1720 bit_offset = arT.bit_offset;
1721
1722 }
1723 else
1724 {
1725 return Status;
1726 }
1727 nCount--;
1728 }
1729
1730 pDescr++;
1731 break;
1732 }
1733
1734 case CSN_BITMAP:
1735 { /* bitmap with given length. The result is left aligned! */
1736 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1737
1738 if (no_of_bits > 0)
1739 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +01001740 if (no_of_bits > remaining_bits_len)
1741 {
1742 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1743 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001744
1745 if (no_of_bits <= 32)
1746 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001747 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001748 {
1749 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001750 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001751 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001752 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001753 }
1754 else if (no_of_bits <= 64)
1755 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001756 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001757 {
1758 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001759 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001760 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001761 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001762 }
1763 else
1764 {
1765 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1766 }
1767
1768 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001769 bit_offset += no_of_bits;
1770 }
1771 /* bitmap was successfully extracted or it was empty */
1772
1773 pDescr++;
1774 break;
1775 }
1776
1777 case CSN_TYPE:
1778 {
1779 gint16 Status;
1780 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01001781 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001782 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1783 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01001784 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001785 if (Status >= 0)
1786 {
1787
1788 remaining_bits_len = arT.remaining_bits_len;
1789 bit_offset = arT.bit_offset;
1790 pDescr++;
1791 }
1792 else
1793 {
1794 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1795 return Status;
1796 }
1797
1798 break;
1799 }
1800
1801 case CSN_CHOICE:
1802 {
1803 //gint16 count = pDescr->i;
1804 guint8 i = 0;
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
1807 pui8 = pui8DATA(data, pDescr->offset);
1808 i = *pui8;
1809 pChoice += i;
1810 guint8 no_of_bits = pChoice->bits;
1811 guint8 value = pChoice->value;
Harald Welte570f9132020-03-19 15:03:01 +01001812 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001813 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001814
1815 CSN_DESCR descr[2];
1816 gint16 Status;
1817 csnStream_t arT = *ar;
1818
1819 descr[0] = pChoice->descr;
1820 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1821 descr[1].type = CSN_END;
1822 bit_offset += no_of_bits;
1823 remaining_bits_len -= no_of_bits;
1824
1825 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1826 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1827
1828 if (Status >= 0)
1829 {
1830 remaining_bits_len = arT.remaining_bits_len;
1831 bit_offset = arT.bit_offset;
1832 }
1833 else
1834 {
1835 return Status;
1836 }
1837
1838 pDescr++;
1839 break;
1840 }
1841
1842 case CSN_SERIALIZE:
1843 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001844 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001845 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001846 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001847 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001848 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001849
1850 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001851 lengthIndex = *writeIndex;
1852 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001853 bit_offset += length_len;
1854 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001855 arT.direction = 0;
1856 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1857 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001858
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001859 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
Harald Welte570f9132020-03-19 15:03:01 +01001860 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001861
1862 if (Status >= 0)
1863 {
1864 remaining_bits_len = arT.remaining_bits_len;
1865 bit_offset = arT.bit_offset;
1866 pDescr++;
1867 }
1868 else
1869 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001870 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001871 return Status;
1872 }
1873
1874 break;
1875 }
1876
1877 case CSN_UNION_LH:
1878 case CSN_UNION:
1879 {
1880 gint16 Bits;
1881 guint8 index;
1882 gint16 count = pDescr->i;
1883 const CSN_DESCR* pDescrNext = pDescr;
1884
1885 pDescrNext += count + 1; /* now this is next after the union */
1886 if ((count <= 0) || (count > 16))
1887 {
1888 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1889 }
1890
1891 /* Now get the bits to extract the index */
1892 Bits = ixBitsTab[count];
1893 index = 0;
1894
1895 /* Assign UnionType */
1896 pui8 = pui8DATA(data, pDescr->offset);
1897 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001898 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001899
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001900 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001901 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001902
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001903 while (Bits > 0)
1904 {
1905 index <<= 1;
1906
1907 if (CSN_UNION_LH == pDescr->type)
1908 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001909 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001910 }
1911 else
1912 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001913 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001914 }
1915
1916 remaining_bits_len--;
1917 bit_offset++;
1918 Bits--;
1919 }
1920
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001921 *writeIndex -= Bits;
1922 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001923
1924
1925 /* script index to continue on, limited in case we do not have a power of 2 */
1926 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +01001927 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001928
1929 switch (pDescr->type)
1930 { /* get the right element of the union based on computed index */
1931
1932 case CSN_BIT:
1933 {
1934 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001935 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001936 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001937 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001938 bit_offset++;
1939 pDescr++;
1940 break;
1941 }
1942
1943 case CSN_NULL:
1944 { /* Empty member! */
1945 pDescr++;
1946 break;
1947 }
1948
1949 case CSN_UINT:
1950 {
1951 guint8 no_of_bits = (guint8) pDescr->i;
1952 if (remaining_bits_len >= no_of_bits)
1953 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001954 if (no_of_bits <= 8)
1955 {
1956 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001957 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001958 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001959 }
1960 else if (no_of_bits <= 16)
1961 {
1962 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001963 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001964 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001965 }
1966 else if (no_of_bits <= 32)
1967 {
1968 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001969 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001970 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001971 }
1972 else
1973 {
1974 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1975 }
1976 }
1977 else
1978 {
1979 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1980 }
1981
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001982 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001983 bit_offset += no_of_bits;
1984 pDescr++;
1985 break;
1986 }
1987
1988 case CSN_UINT_OFFSET:
1989 {
1990 guint8 no_of_bits = (guint8) pDescr->i;
1991
1992 if (remaining_bits_len >= no_of_bits)
1993 {
1994 if (no_of_bits <= 8)
1995 {
1996 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001997 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001998 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001999 }
2000 else if (no_of_bits <= 16)
2001 {
2002 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002003 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002004 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002005 }
2006 else if (no_of_bits <= 32)
2007 {
2008 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002009 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002010 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002011 }
2012 else
2013 {
2014 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2015 }
2016 }
2017 else
2018 {
2019 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2020 }
2021
2022 remaining_bits_len -= no_of_bits;
2023 bit_offset += no_of_bits;
2024 pDescr++;
2025 break;
2026 }
2027
2028 case CSN_UINT_LH:
2029 {
2030 guint8 no_of_bits = (guint8) pDescr->i;
2031
2032 if (remaining_bits_len >= no_of_bits)
2033 {
2034 remaining_bits_len -= no_of_bits;
2035 if (no_of_bits <= 8)
2036 {
2037 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002038 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002039 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002040 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002041 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002042 *writeIndex -= no_of_bits;
2043 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002044 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002045
2046 }
2047 else
2048 {/* Maybe we should support more than 8 bits ? */
2049 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2050 }
2051 }
2052 else
2053 {
2054 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2055 }
2056
2057 remaining_bits_len -= no_of_bits;
2058 bit_offset += no_of_bits;
2059 pDescr++;
2060 break;
2061 }
2062
2063 case CSN_UINT_ARRAY:
2064 {
2065 guint8 no_of_bits = (guint8) pDescr->i;
2066 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2067
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002068 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002069 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2070 nCount = *pui16DATA(data, nCount);
2071 }
2072
Pau Espin Pedrolf5e275a2020-03-26 19:54:29 +01002073 if (remaining_bits_len >= (no_of_bits * nCount))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002074 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002075 if (no_of_bits <= 8)
2076 {
2077 pui8 = pui8DATA(data, pDescr->offset);
2078 do
2079 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002080 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002081 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002082 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002083 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002084 bit_offset += no_of_bits;
2085 } while (--nCount > 0);
2086 }
2087 else if (no_of_bits <= 16)
2088 {
2089 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2090 }
2091 else if (no_of_bits <= 32)
2092 {
2093 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2094 }
2095 else
2096 {
2097 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2098 }
2099 }
2100 else
2101 {
2102 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2103 }
2104 pDescr++;
2105 break;
2106 }
2107
2108 case CSN_VARIABLE_TARRAY_OFFSET:
2109 case CSN_VARIABLE_TARRAY:
2110 case CSN_TYPE_ARRAY:
2111 {
2112 gint16 Status;
2113 csnStream_t arT = *ar;
2114 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002115 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002116
2117 pui8 = pui8DATA(data, pDescr->offset);
2118 if (pDescr->type == CSN_VARIABLE_TARRAY)
2119 { /* Count specified in field */
2120 nCount = *pui8DATA(data, pDescr->i);
2121 }
2122 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2123 { /* Count specified in field */
2124 nCount = *pui8DATA(data, pDescr->i);
2125 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2126 }
2127
2128 while (nCount > 0)
2129 { /* resulting array of length 0 is possible
2130 * but no bits shall be read from bitstream
2131 */
2132
Harald Welte570f9132020-03-19 15:03:01 +01002133 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002134 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2135 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2136 if (Status >= 0)
2137 {
2138 pui8 += nSize;
2139 remaining_bits_len = arT.remaining_bits_len;
2140 bit_offset = arT.bit_offset;
2141 }
2142 else
2143 {
2144 return Status;
2145 }
2146 nCount--;
2147 }
2148
2149 pDescr++;
2150 break;
2151 }
2152
2153 case CSN_BITMAP:
2154 { /* bitmap with given length. The result is left aligned! */
2155 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2156
2157 if (no_of_bits > 0)
2158 {
Pau Espin Pedrolc8280a52020-03-26 20:29:53 +01002159 if (no_of_bits > remaining_bits_len)
2160 {
2161 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2162 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002163
2164 if (no_of_bits <= 32)
2165 {
2166 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002167 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002168 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002169 }
2170 else if (no_of_bits <= 64)
2171 {
2172 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002173 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002174 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002175 }
2176 else
2177 {
2178 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2179 }
2180
2181 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002182 bit_offset += no_of_bits;
2183 }
2184 /* bitmap was successfully extracted or it was empty */
2185
2186 pDescr++;
2187 break;
2188 }
2189
2190 case CSN_TYPE:
2191 {
2192 gint16 Status;
2193 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01002194 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002195 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2196 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01002197 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002198 if (Status >= 0)
2199 {
2200 remaining_bits_len = arT.remaining_bits_len;
2201 bit_offset = arT.bit_offset;
2202 pDescr++;
2203 }
2204 else
2205 {
2206 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2207 return Status;
2208 }
2209
2210 break;
2211 }
2212
2213 default:
2214 { /* descriptions of union elements other than above are illegal */
2215 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2216 }
2217 }
2218
2219 pDescr = pDescrNext;
2220 break;
2221 }
2222
2223 case CSN_EXIST:
2224 case CSN_EXIST_LH:
2225 {
2226 guint8 fExist;
2227 unsigned exist = 0;
2228 pui8 = pui8DATA(data, pDescr->offset);
2229 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002230 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002231 writeIndex--;
2232 if (CSN_EXIST_LH == pDescr->type)
2233 {
2234 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2235 }
2236 else
2237 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002238 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002239 }
2240 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002241 bitvec_write_field(vector, writeIndex, fExist, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002242 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002243 remaining_bits_len--;
2244 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002245 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002246
2247 if (!exist)
2248 {
2249 ar->remaining_bits_len = remaining_bits_len;
2250 ar->bit_offset = bit_offset;
2251 return remaining_bits_len;
2252 }
2253 break;
2254 }
2255
2256 case CSN_NEXT_EXIST:
2257 {
2258 guint8 fExist;
2259
2260 pui8 = pui8DATA(data, pDescr->offset);
2261
2262 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002263 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002264 { /* no more bits to decode is fine here - end of message detected and allowed */
2265
2266 /* Skip i entries + this entry */
2267 pDescr += pDescr->i + 1;
2268
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002269 break;
2270 }
2271
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002272 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002273 fExist = *pui8;
Harald Welte570f9132020-03-19 15:03:01 +01002274 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002275
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002276 remaining_bits_len--;
2277 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002278
2279 if (fExist == 0)
2280 { /* Skip 'i' entries */
2281 pDescr += pDescr->i;
2282 }
2283
2284 pDescr++;
2285 break;
2286 }
2287
2288 case CSN_NEXT_EXIST_LH:
2289 {
2290 guint8 fExist;
2291 pui8 = pui8DATA(data, pDescr->offset);
2292
2293 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2294 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2295 { /* no more bits to decode is fine here - end of message detected and allowed */
2296
2297 /* skip 'i' entries + this entry */
2298 pDescr += pDescr->i + 1;
2299
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002300 /* set the data member to "not exist" */
2301 //*pui8 = 0;
2302 break;
2303 }
2304
2305 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002306 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002307 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002308 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002309 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002310 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002311 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002312
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002313 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002314 bit_offset++;
2315
2316 if (fExist == 0)
2317 { /* Skip 'i' entries */
2318 pDescr += pDescr->i;
2319 }
2320 pDescr++;
2321
2322 break;
2323 }
2324
2325 case CSN_VARIABLE_BITMAP_1:
2326 { /* Bitmap from here and to the end of message */
2327
2328 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2329
2330 /*no break -
2331 * with a length set we have a regular variable length bitmap so we continue */
2332 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002333 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002334 case CSN_VARIABLE_BITMAP:
2335 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2336 * <N: bit (5)> <bitmap: bit(N + offset)>
2337 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2338 * The result is right aligned!
2339 */
2340 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2341
2342 no_of_bits += pDescr->i; /* adjusted by offset */
2343
2344 if (no_of_bits > 0)
2345 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002346
2347 if (remaining_bits_len < 0)
2348 {
2349 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2350 }
2351
2352 { /* extract bits */
2353 guint8* pui8 = pui8DATA(data, pDescr->offset);
2354 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2355
2356 if (nB1 > 0)
2357 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002358 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002359 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002360 pui8++;
2361 no_of_bits -= nB1;
2362 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002363 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002364 }
2365
2366 /* remaining no_of_bits is a multiple of 8 or 0 */
2367 while (no_of_bits > 0)
2368 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002369 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002370 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002371 pui8++;
2372 no_of_bits -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002373 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002374 }
2375 }
2376 }
2377 pDescr++;
2378 break;
2379 }
2380
2381 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2382 { /* Bitmap from here and to the end of message */
2383
2384 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2385
2386 /* no break -
2387 * with a length set we have a regular left aligned variable length bitmap so we continue
2388 */
2389 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002390 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002391 case CSN_LEFT_ALIGNED_VAR_BMP:
2392 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2393 * <N: bit (5)> <bitmap: bit(N + offset)>
2394 * bit array with length (in bits) specified in parameter (pDescr->descr)
2395 */
2396
2397 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2398
2399 no_of_bits += pDescr->i;/* size adjusted by offset */
2400
2401 if (no_of_bits > 0)
2402 {
2403 remaining_bits_len -= no_of_bits;
2404
2405 if (remaining_bits_len < 0)
2406 {
2407 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2408 }
2409
2410 { /* extract bits */
2411 guint8* pui8 = pui8DATA(data, pDescr->offset);
2412 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2413
2414 while (no_of_bits > 0)
2415 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002416 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002417 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002418 pui8++;
2419 no_of_bits -= 8;
2420 }
2421 if (nB1 > 0)
2422 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002423 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002424 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002425 pui8++;
2426 no_of_bits -= nB1;
2427 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2428 }
2429 }
2430
2431 }
2432
2433 /* bitmap was successfully extracted or it was empty */
2434 pDescr++;
2435 break;
2436 }
2437
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002438 case CSN_PADDING_BITS:
2439 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01002440 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002441 guint8 filler = 0x2b;
2442 if (remaining_bits_len > 0)
2443 {
2444 while (remaining_bits_len > 0)
2445 {
2446 guint8 bits_to_handle = remaining_bits_len%8;
2447 if (bits_to_handle > 0)
2448 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302449 /* section 11 of 44.060
2450 * The padding bits may be the 'null' string. Otherwise, the
2451 * padding bits starts with bit '0', followed by 'spare padding'
2452 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2453 */
2454 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002455 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Harald Welte570f9132020-03-19 15:03:01 +01002456 LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002457 remaining_bits_len -= bits_to_handle;
2458 bit_offset += bits_to_handle;
2459 }
2460 else if (bits_to_handle == 0)
2461 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002462 bitvec_write_field(vector, writeIndex, filler, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002463 LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002464 remaining_bits_len -= 8;
2465 bit_offset += 8;
2466 }
2467 }
2468 }
2469 if (remaining_bits_len < 0)
2470 {
Pau Espin Pedrol70a21172020-03-26 19:50:50 +01002471 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002472 }
2473
2474 /* Padding was successfully extracted or it was empty */
2475 pDescr++;
2476 break;
2477 }
2478
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002479 case CSN_VARIABLE_ARRAY:
2480 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2481 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2482 * Array with length specified in parameter:
2483 * <count: bit (x)>
2484 * <list: octet(count + offset)>
2485 */
2486 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2487
2488 count += pDescr->i; /* Adjusted by offset */
2489
2490 if (count > 0)
2491 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002492 if (remaining_bits_len < 0)
2493 {
2494 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2495 }
2496
2497 pui8 = pui8DATA(data, pDescr->offset);
2498
2499 while (count > 0)
2500 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002501 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002502 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002503 pui8++;
2504 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002505 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002506 count--;
2507 }
2508 }
2509
2510 pDescr++;
2511 break;
2512 }
2513
2514 case CSN_RECURSIVE_ARRAY:
2515 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2516 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2517 * where <element> ::= bit(value)
2518 * <tag> ::= 0 | 1
2519 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2520 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2521 * REMARK: recursive way to specify an array but an iterative implementation!
2522 */
2523 gint16 no_of_bits = pDescr->i;
2524 guint8 ElementCount = 0;
2525 pui8 = pui8DATA(data, pDescr->offset);
2526 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2527 while (ElementCount > 0)
2528 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002529 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002530 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002531 bit_offset++;
2532 remaining_bits_len--;
2533
2534 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002535 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002536 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002537 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002538 ElementCount--;
2539
2540 if (remaining_bits_len < 0)
2541 {
2542 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2543 }
2544
2545 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002546 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002547 }
2548
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002549 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002550 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002551 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302552 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002553
2554 pDescr++;
2555 break;
2556 }
2557
2558 case CSN_RECURSIVE_TARRAY:
2559 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2560 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2561 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2562 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002563 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002564 guint8 ElementCount = 0;
2565 pui8 = pui8DATA(data, pDescr->offset);
2566 /* Store the counted number of elements of the array */
2567 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2568
2569 while (ElementCount > 0)
2570 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002571 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002572 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002573 bit_offset++;
2574
2575 remaining_bits_len--;
2576 ElementCount--;
2577
2578 { /* unpack the following data structure */
2579 csnStream_t arT = *ar;
2580 gint16 Status;
2581 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002582 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002583
2584 if (Status >= 0)
2585 { /* successful completion */
2586 pui8 += nSizeElement; /* -> to next data element */
2587 remaining_bits_len = arT.remaining_bits_len;
2588 bit_offset = arT.bit_offset;
2589 }
2590 else
2591 { /* something went awry */
2592 return Status;
2593 }
2594 }
2595
2596 if (remaining_bits_len < 0)
2597 {
2598 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2599 }
2600 }
2601
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002602 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002603 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002604 bit_offset++;
2605
2606 pDescr++;
2607 break;
2608 }
2609
2610 case CSN_RECURSIVE_TARRAY_2:
2611 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2612
2613 Tag = REVERSED_TAG;
2614
2615 /* NO break -
2616 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2617 */
2618 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002619 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002620 case CSN_RECURSIVE_TARRAY_1:
2621 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2622 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2623 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2624 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002625 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002626 guint8 ElementCount = 0;
2627 guint8 ElementNum = 0;
2628 csnStream_t arT = *ar;
2629 gint16 Status;
2630
2631 pui8 = pui8DATA(data, pDescr->offset);
2632 /* Store the count of the array */
2633 ElementCount = *pui8DATA(data, pDescr->i);
2634 ElementNum = ElementCount;
2635
2636 while (ElementCount > 0)
2637 { /* get data element */
2638 if (ElementCount != ElementNum)
2639 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002640 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002641 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002642 bit_offset++;
2643 remaining_bits_len--;
2644 }
2645 ElementCount--;
Harald Welte570f9132020-03-19 15:03:01 +01002646 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002647 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002648 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Harald Welte570f9132020-03-19 15:03:01 +01002649 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002650 if (Status >= 0)
2651 { /* successful completion */
2652 pui8 += nSizeElement; /* -> to next */
2653 remaining_bits_len = arT.remaining_bits_len;
2654 bit_offset = arT.bit_offset;
2655 }
2656 else
2657 { /* something went awry */
2658 return Status;
2659 }
2660
2661 if (remaining_bits_len < 0)
2662 {
2663 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2664 }
2665
2666 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002667 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002668 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002669 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002670 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2671 pDescr++;
2672 break;
2673 }
2674
2675 case CSN_FIXED:
2676 { /* Verify the fixed bits */
2677 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002678 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002679 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002680 remaining_bits_len -= no_of_bits;
2681 bit_offset += no_of_bits;
2682 pDescr++;
2683 break;
2684 }
2685
2686 case CSN_CALLBACK:
2687 {
2688 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2689 break;
2690 }
2691
2692 case CSN_TRAP_ERROR:
2693 {
2694 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2695 }
2696
2697 case CSN_END:
2698 {
2699 ar->remaining_bits_len = remaining_bits_len;
2700 ar->bit_offset = bit_offset;
2701 return remaining_bits_len;
2702 }
2703
2704 default:
2705 {
2706 assert(0);
2707 }
2708
2709 }
2710
2711 } while (remaining_bits_len >= 0);
2712
2713 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2714}