blob: 71728477b00bacb08e771d522c8cf5425af77392 [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040031#include <assert.h>
32#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020033#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
Pau Espin Pedrold636f742020-02-03 15:37:08 +010038#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030040
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030050static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
51
52
53/* Returns no_of_bits (up to 8) masked with 0x2B */
54
55static guint8
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070056get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030057{
58 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
59 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
60 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
61 guint8 result;
62 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070063 *readIndex -= relative_bit_offset;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030064 if (bit_shift >= 0)
65 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070066 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
67 *readIndex-= bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030068 result &= maskBits[no_of_bits];
69 }
70 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010071 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070072 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030073 hight_part = (guint8) (hight_part << (-bit_shift));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070074 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
75 *readIndex = *readIndex - (8 - (-bit_shift));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030076 result |= hight_part;
77 }
78 return result;
79}
80
81/**
82 * ================================================================================================
83 * set initial/start values in help data structure used for packing/unpacking operation
84 * ================================================================================================
85 */
86void
87csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
88{
89 ar->remaining_bits_len = remaining_bits_len;
90 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040091 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030092}
93
Pau Espin Pedrold636f742020-02-03 15:37:08 +010094static const struct value_string csn1_error_names[] = {
95 { CSN_OK, "General 0" },
96 { CSN_ERROR_GENERAL, "General -1" },
97 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
98 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
99 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
100 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
Vadim Yanitskiyfee767f2020-02-11 05:28:02 +0700101 { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" },
102 { CSN_ERROR_INTERNAL, "INTERNAL" },
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100103 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
104 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
105 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300106};
107
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100108
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700109static gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100110 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111{
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100112 /* Don't add trailing newline, top caller is responsible for appending it */
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100113 if (err != CSN_OK)
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700114 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %u)",
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100115 sz, get_value_string(csn1_error_names, err), err,
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700116 pDescr ? pDescr->sz : "-", *readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300117 return err;
118}
119
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100120#define ProcessError(readIndex, sz, err, pDescr) \
121 ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
122
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300123
124/**
125 * ================================================================================================
126 * Return TRUE if tag in bit stream indicates existence of next list element,
127 * otherwise return FALSE.
128 * Will work for tag values equal to both 0 and 1.
129 * ================================================================================================
130 */
131
132static gboolean
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700133existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300134{
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700135 int res = bitvec_get_bit_pos(vector, (*readIndex)++);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300136 if (Tag == STANDARD_TAG)
137 {
138 return (res > 0);
139 }
140 return (res == 0);
141}
142
143
144gint16
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700145csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300146{
147 gint remaining_bits_len = ar->remaining_bits_len;
148 gint bit_offset = ar->bit_offset;
Anders Bromanc0190c82020-01-24 14:34:14 +0100149 guint8* pui8 = NULL;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300150 guint16* pui16;
151 guint32* pui32;
152 guint64* pui64;
153 guint8 Tag = STANDARD_TAG;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700154 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300155
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700156 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300157 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +0700158 return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300159 }
160
161 do
162 {
163 switch (pDescr->type)
164 {
165 case CSN_BIT:
166 {
167 if (remaining_bits_len > 0)
168 {
169 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700170 *pui8 = bitvec_read_field(vector, readIndex, 1);
Harald Welte570f9132020-03-19 15:03:01 +0100171 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 /* end add the bit value to protocol tree */
173 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400174 else if(pDescr->may_be_null)
175 {
176 pui8 = pui8DATA(data, pDescr->offset);
177 *pui8 = 0;
Harald Welte570f9132020-03-19 15:03:01 +0100178 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400179 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300180 else
181 {
182 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
183 }
184
185 pDescr++;
186 remaining_bits_len--;
187 bit_offset++;
188 break;
189 }
190
191 case CSN_NULL:
192 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100193 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300194 pDescr++;
195 break;
196 }
197
198 case CSN_UINT:
199 {
200 guint8 no_of_bits = (guint8) pDescr->i;
201
202 if (remaining_bits_len >= no_of_bits)
203 {
204 if (no_of_bits <= 8)
205 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700206 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300207 pui8 = pui8DATA(data, pDescr->offset);
208 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100209 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300210 }
211 else if (no_of_bits <= 16)
212 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700213 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300214 pui16 = pui16DATA(data, pDescr->offset);
215 *pui16 = ui16;
Harald Welte570f9132020-03-19 15:03:01 +0100216 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300217 }
218 else if (no_of_bits <= 32)
219 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700220 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300221 pui32 = pui32DATA(data, pDescr->offset);
222 *pui32 = ui32;
Harald Welte570f9132020-03-19 15:03:01 +0100223 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300224 }
225 else
226 {
227 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
228 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400229 remaining_bits_len -= no_of_bits;
230 bit_offset += no_of_bits;
231 }
232 else if(pDescr->may_be_null)
233 {
234 if (no_of_bits <= 8)
235 {
236 pui8 = pui8DATA(data, pDescr->offset);
237 *pui8 = 0;
238 }
239 else if (no_of_bits <= 16)
240 {
241 pui16 = pui16DATA(data, pDescr->offset);
242 *pui16 = 0;
243 }
244 else if (no_of_bits <= 32)
245 {
246 pui32 = pui32DATA(data, pDescr->offset);
247 *pui32 = 0;
248 }
Harald Welte570f9132020-03-19 15:03:01 +0100249 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300250 }
251 else
252 {
253 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
254 }
255
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300256 pDescr++;
257 break;
258 }
259
260 case CSN_UINT_OFFSET:
261 {
262 guint8 no_of_bits = (guint8) pDescr->i;
263
264 if (remaining_bits_len >= no_of_bits)
265 {
266 if (no_of_bits <= 8)
267 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700268 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300269 pui8 = pui8DATA(data, pDescr->offset);
270 *pui8 = ui8 + (guint8)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100271 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300272 }
273 else if (no_of_bits <= 16)
274 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700275 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300276 pui16 = pui16DATA(data, pDescr->offset);
277 *pui16 = ui16 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100278 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300279 }
280 else if (no_of_bits <= 32)
281 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700282 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300283 pui32 = pui32DATA(data, pDescr->offset);
284 *pui32 = ui32 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100285 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300286 }
287 else
288 {
289 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
290 }
291 }
292 else
293 {
294 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
295 }
296
297 remaining_bits_len -= no_of_bits;
298 bit_offset += no_of_bits;
299 pDescr++;
300 break;
301 }
302
303 case CSN_UINT_LH:
304 {
305 guint8 no_of_bits = (guint8) pDescr->i;
306
307 if (remaining_bits_len >= no_of_bits)
308 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300309 if (no_of_bits <= 8)
310 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100311 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300312 pui8 = pui8DATA(data, pDescr->offset);
313 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100314 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300315 }
316 else
317 {/* Maybe we should support more than 8 bits ? */
318 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
319 }
320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
324 }
325
326 remaining_bits_len -= no_of_bits;
327 bit_offset += no_of_bits;
328 pDescr++;
329 break;
330 }
331
332 case CSN_UINT_ARRAY:
333 {
334 guint8 no_of_bits = (guint8) pDescr->i;
335 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
336
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100337 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300338 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
339 nCount = *pui16DATA(data, nCount);
340 }
341
342 if (remaining_bits_len >= no_of_bits)
343 {
344 remaining_bits_len -= (no_of_bits*nCount);
345 if (no_of_bits <= 8)
346 {
347 pui8 = pui8DATA(data, pDescr->offset);
348 do
349 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700350 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100351 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300352 pui8++;
353 bit_offset += no_of_bits;
354 } while (--nCount > 0);
355 }
356 else if (no_of_bits <= 16)
357 {
358 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
359 }
360 else if (no_of_bits <= 32)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else
365 {
366 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
367 }
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
372 }
373 pDescr++;
374 break;
375 }
376
377 case CSN_VARIABLE_TARRAY_OFFSET:
378 case CSN_VARIABLE_TARRAY:
379 case CSN_TYPE_ARRAY:
380 {
381 gint16 Status;
382 csnStream_t arT = *ar;
383 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100384 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300385
386 pui8 = pui8DATA(data, pDescr->offset);
387 if (pDescr->type == CSN_VARIABLE_TARRAY)
388 { /* Count specified in field */
389 nCount = *pui8DATA(data, pDescr->i);
390 }
391 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
395 }
396
397 while (nCount > 0)
398 { /* resulting array of length 0 is possible
399 * but no bits shall be read from bitstream
400 */
401
Harald Welte570f9132020-03-19 15:03:01 +0100402 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300403 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100404 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300405 if (Status >= 0)
406 {
407 pui8 += nSize;
408 remaining_bits_len = arT.remaining_bits_len;
409 bit_offset = arT.bit_offset;
410 }
411 else
412 {
413 return Status;
414 }
415 nCount--;
416 }
417
418 pDescr++;
419 break;
420 }
421
422 case CSN_BITMAP:
423 { /* bitmap with given length. The result is left aligned! */
424 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
425
426 if (no_of_bits > 0)
427 {
428
429 if (no_of_bits <= 32)
430 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700431 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400432 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700433 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400434 pui8 = pui8DATA(data, pDescr->offset+ib);
435 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100436 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 }
439 else if (no_of_bits <= 64)
440 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700441 for(ib = 0; ib < 8; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400442 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700443 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400444 pui8 = pui8DATA(data, pDescr->offset+ib);
445 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100446 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300448 }
449 else
450 {
451 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
452 }
453
454 remaining_bits_len -= no_of_bits;
455 assert(remaining_bits_len >= 0);
456 bit_offset += no_of_bits;
457 }
458 /* bitmap was successfully extracted or it was empty */
459
460 pDescr++;
461 break;
462 }
463
464 case CSN_TYPE:
465 {
466 gint16 Status;
467 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +0100468 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300469 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100470 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +0100471 LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300472 if (Status >= 0)
473 {
474 remaining_bits_len = arT.remaining_bits_len;
475 bit_offset = arT.bit_offset;
476 pDescr++;
477 }
478 else
479 {
480 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
481 return Status;
482 }
483
484 break;
485 }
486
487 case CSN_CHOICE:
488 {
489 gint16 count = pDescr->i;
490 guint8 i = 0;
491 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
492
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700493 /* Make sure that the list of choice items is not empty */
494 if (!count)
495 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
496
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300497 while (count > 0)
498 {
499 guint8 no_of_bits = pChoice->bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700500 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300501 if (value == pChoice->value)
502 {
503 CSN_DESCR descr[2];
504 gint16 Status;
505 csnStream_t arT = *ar;
506
507 descr[0] = pChoice->descr;
508 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
509 descr[1].type = CSN_END;
510 pui8 = pui8DATA(data, pDescr->offset);
511 *pui8 = i;
Harald Welte570f9132020-03-19 15:03:01 +0100512 LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Pau Espin Pedrol7cce8252020-01-24 16:41:14 +0100513 if (!pChoice->keep_bits) {
514 bit_offset += no_of_bits;
515 remaining_bits_len -= no_of_bits;
516 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300517
518 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100519 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300520
521 if (Status >= 0)
522 {
523 remaining_bits_len = arT.remaining_bits_len;
524 bit_offset = arT.bit_offset;
525 }
526 else
527 {
528 return Status;
529 }
530 break;
531 }
532
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700533 *readIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300534 count--;
535 pChoice++;
536 i++;
537 }
538
Vadim Yanitskiy5574a582020-02-11 05:39:06 +0700539 /* Neither of the choice items matched => unknown value */
540 if (!count)
541 return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
542
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300543 pDescr++;
544 break;
545 }
546
547 case CSN_SERIALIZE:
548 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +0100549 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300550 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400551 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300552 gint16 Status = -1;
553
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700554 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300555
Harald Welte570f9132020-03-19 15:03:01 +0100556 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400557 bit_offset += length_len;
558 remaining_bits_len -= length_len;
559
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100560 csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100561 arT.direction = 1;
Harald Welte570f9132020-03-19 15:03:01 +0100562 LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100563 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300564
565 if (Status >= 0)
566 {
Pau Espin Pedrol98e4c532020-01-24 16:26:37 +0100567 if (length > 0) {
568 remaining_bits_len -= length;
569 bit_offset += length;
570 } else {
571 remaining_bits_len = arT.remaining_bits_len;
572 bit_offset = arT.bit_offset;
573 }
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700574
575 /* Skip bits not handled by serialize(), if any */
576 if (Status > 0) {
Harald Welte570f9132020-03-19 15:03:01 +0100577 LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
Vadim Yanitskiy2679ec02020-03-06 07:21:32 +0700578 *readIndex += Status;
579 }
580
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300581 pDescr++;
582 }
583 else
584 {
585 /* Has already been processed: */
586 return Status;
587 }
588
589 break;
590 }
591
592 case CSN_UNION_LH:
593 case CSN_UNION:
594 {
595 gint16 Bits;
596 guint8 index;
597 gint16 count = pDescr->i;
598 const CSN_DESCR* pDescrNext = pDescr;
599
600 pDescrNext += count + 1; /* now this is next after the union */
601 if ((count <= 0) || (count > 16))
602 {
603 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
604 }
605
606 /* Now get the bits to extract the index */
607 Bits = ixBitsTab[count];
608 index = 0;
609
610 while (Bits > 0)
611 {
612 index <<= 1;
613
614 if (CSN_UNION_LH == pDescr->type)
615 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700616 index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300617 }
618 else
619 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700620 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300621 }
622 remaining_bits_len--;
623 bit_offset++;
624 Bits--;
625 }
626
627 /* Assign UnionType */
628 pui8 = pui8DATA(data, pDescr->offset);
629 *pui8 = index;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +0100630
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300631
632 /* script index to continue on, limited in case we do not have a power of 2 */
633 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +0100634 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300635
636 switch (pDescr->type)
637 { /* get the right element of the union based on computed index */
638
639 case CSN_BIT:
640 {
641 pui8 = pui8DATA(data, pDescr->offset);
642 *pui8 = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700643 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300644 {
645 *pui8 = 0x01;
646 }
Harald Welte570f9132020-03-19 15:03:01 +0100647 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300648 remaining_bits_len -= 1;
649 bit_offset++;
650 pDescr++;
651 break;
652 }
653
654 case CSN_NULL:
655 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100656 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300657 pDescr++;
658 break;
659 }
660
661 case CSN_UINT:
662 {
663 guint8 no_of_bits = (guint8) pDescr->i;
664 if (remaining_bits_len >= no_of_bits)
665 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300666 if (no_of_bits <= 8)
667 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700668 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300669 pui8 = pui8DATA(data, pDescr->offset);
670 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100671 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300672 }
673 else if (no_of_bits <= 16)
674 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700675 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300676 pui16 = pui16DATA(data, pDescr->offset);
677 *pui16 = ui16;
Harald Welte570f9132020-03-19 15:03:01 +0100678 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300679 }
680 else if (no_of_bits <= 32)
681 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700682 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300683 pui32 = pui32DATA(data, pDescr->offset);
684 *pui32 = ui32;
Harald Welte570f9132020-03-19 15:03:01 +0100685 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300686 }
687 else
688 {
689 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
690 }
691 }
692 else
693 {
694 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
695 }
696
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700697 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300698 bit_offset += no_of_bits;
699 pDescr++;
700 break;
701 }
702
703 case CSN_UINT_OFFSET:
704 {
705 guint8 no_of_bits = (guint8) pDescr->i;
706
707 if (remaining_bits_len >= no_of_bits)
708 {
709 if (no_of_bits <= 8)
710 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700711 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300712 pui8 = pui8DATA(data, pDescr->offset);
713 *pui8 = ui8 + (guint8)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100714 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300715 }
716 else if (no_of_bits <= 16)
717 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700718 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300719 pui16 = pui16DATA(data, pDescr->offset);
720 *pui16 = ui16 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100721 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300722 }
723 else if (no_of_bits <= 32)
724 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700725 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300726 pui32 = pui32DATA(data, pDescr->offset);
727 *pui32 = ui32 + (guint16)pDescr->descr.value;
Harald Welte570f9132020-03-19 15:03:01 +0100728 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300729 }
730 else
731 {
732 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
733 }
734 }
735 else
736 {
737 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
738 }
739
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700740 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300741 bit_offset += no_of_bits;
742 pDescr++;
743 break;
744 }
745
746 case CSN_UINT_LH:
747 {
748 guint8 no_of_bits = (guint8) pDescr->i;
749
750 if (remaining_bits_len >= no_of_bits)
751 {
752 if (no_of_bits <= 8)
753 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100754 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300755 pui8 = pui8DATA(data, pDescr->offset);
756 *pui8 = ui8;
Harald Welte570f9132020-03-19 15:03:01 +0100757 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300758 }
759 else
760 { /* Maybe we should support more than 8 bits ? */
761 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
762 }
763 }
764 else
765 {
766 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
767 }
768
Vadim Yanitskiye87066d2020-02-17 18:02:32 +0700769 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300770 bit_offset += no_of_bits;
771 pDescr++;
772 break;
773 }
774
775 case CSN_UINT_ARRAY:
776 {
777 guint8 no_of_bits = (guint8) pDescr->i;
778 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
779
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100780 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300781 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
782 nCount = *pui16DATA(data, nCount);
783 }
784
785 if (remaining_bits_len >= no_of_bits)
786 {
787 remaining_bits_len -= (no_of_bits * nCount);
788 if (no_of_bits <= 8)
789 {
790 pui8 = pui8DATA(data, pDescr->offset);
791
792 while (nCount > 0)
793 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700794 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100795 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300796 pui8++;
797 bit_offset += no_of_bits;
798 nCount--;
799 }
800 }
801 else if (no_of_bits <= 16)
802 {
803 pui16 = pui16DATA(data, pDescr->offset);
804
805 while (nCount > 0)
806 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700807 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +0100808 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300809 pui16++;
810 bit_offset += no_of_bits;
811 nCount--;
812 }
813 }
814 else if (no_of_bits <= 32)
815 { /* not supported */
816 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
817 }
818 else
819 {
820 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
821 }
822 }
823 else
824 {
825 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
826 }
827
828 pDescr++;
829 break;
830 }
831
832 case CSN_VARIABLE_TARRAY_OFFSET:
833 case CSN_VARIABLE_TARRAY:
834 case CSN_TYPE_ARRAY:
835 {
836 gint16 Status;
837 csnStream_t arT = *ar;
838 guint16 nCount = (guint16) pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +0100839 guint16 nSize = (guint16)(guint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300840
841 pui8 = pui8DATA(data, pDescr->offset);
842
843 if (CSN_VARIABLE_TARRAY == pDescr->type)
844 { /* Count specified in field */
845 nCount = *pui8DATA(data, pDescr->i);
846 }
847 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
848 { /* Count specified in field */
849 nCount = *pui8DATA(data, pDescr->i);
850 nCount--; /* Offset 1 */
851 }
852
853 while (nCount--) /* Changed to handle length = 0. */
854 {
Harald Welte570f9132020-03-19 15:03:01 +0100855 LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300856 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100857 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300858 if (Status >= 0)
859 {
860 pui8 += nSize;
861 remaining_bits_len = arT.remaining_bits_len;
862 bit_offset = arT.bit_offset;
863 }
864 else
865 {
866 return Status;
867 }
868 }
869
870 pDescr++;
871 break;
872 }
873
874 case CSN_BITMAP:
875 { /* bitmap with given length. The result is left aligned! */
876 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
877
878 if (no_of_bits > 0)
879 {
880
881 if (no_of_bits <= 32)
882 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700883 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300884 pui32 = pui32DATA(data, pDescr->offset);
885 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300886 }
887 else if (no_of_bits <= 64)
888 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700889 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300890 pui64 = pui64DATA(data, pDescr->offset);
891 *pui64 = ui64;
Harald Welte570f9132020-03-19 15:03:01 +0100892 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300893 }
894 else
895 {
896 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
897 }
898
899 remaining_bits_len -= no_of_bits;
900 assert(remaining_bits_len >= 0);
901 bit_offset += no_of_bits;
902 }
903 /* bitmap was successfully extracted or it was empty */
904
905 pDescr++;
906 break;
907 }
908
909 case CSN_TYPE:
910 {
911 gint16 Status;
912 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +0100913 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300914 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100915 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +0100916 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300917 if (Status >= 0)
918 {
919 remaining_bits_len = arT.remaining_bits_len;
920 bit_offset = arT.bit_offset;
921 pDescr++;
922 }
923 else
924 { /* return error code Has already been processed: */
925 return Status;
926 }
927
928 break;
929 }
930
931 default:
932 { /* descriptions of union elements other than above are illegal */
933 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
934 }
935 }
936
937 pDescr = pDescrNext;
938 break;
939 }
940
941 case CSN_EXIST:
942 case CSN_EXIST_LH:
943 {
944 guint8 fExist;
945
946 pui8 = pui8DATA(data, pDescr->offset);
947
948 if (CSN_EXIST_LH == pDescr->type)
949 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100950 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300951 }
952 else
953 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700954 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300955 }
956
957 *pui8 = fExist;
Harald Welte570f9132020-03-19 15:03:01 +0100958 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300959 pDescr++;
Vadim Yanitskiyd8e5e8b2020-02-17 18:16:20 +0700960 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300961 remaining_bits_len -= 1;
962
963 if (!fExist)
964 {
965 ar->remaining_bits_len = remaining_bits_len;
966 ar->bit_offset = bit_offset;
967 return remaining_bits_len;
968 }
969
970 break;
971 }
972
973 case CSN_NEXT_EXIST:
974 {
975 guint8 fExist;
976
977 pui8 = pui8DATA(data, pDescr->offset);
978
979 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400980 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300981 { /* no more bits to decode is fine here - end of message detected and allowed */
982
983 /* Skip i entries + this entry */
984 pDescr += pDescr->i + 1;
985
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300986 /* Set the data member to "not exist" */
987 *pui8 = 0;
988 break;
989 }
990
991 /* the "regular" M_NEXT_EXIST description element */
992
993 fExist = 0x00;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700994 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300995 {
996 fExist = 0x01;
997 }
998
999 *pui8 = fExist;
1000 remaining_bits_len -= 1;
Harald Welte570f9132020-03-19 15:03:01 +01001001 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001002 ++bit_offset;
1003
1004 if (fExist == 0)
1005 { /* Skip 'i' entries */
1006 pDescr += pDescr->i;
1007 }
1008
1009 pDescr++;
1010 break;
1011 }
1012
1013 case CSN_NEXT_EXIST_LH:
1014 {
1015 guint8 fExist;
1016 pui8 = pui8DATA(data, pDescr->offset);
1017
1018 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1019 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1020 { /* no more bits to decode is fine here - end of message detected and allowed */
1021
1022 /* skip 'i' entries + this entry */
1023 pDescr += pDescr->i + 1;
1024
1025 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1026 if ( pDescr->type != CSN_END )
1027 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1028 remaining_bits_len--;
1029 }
1030
1031 /* set the data member to "not exist" */
1032 *pui8 = 0;
1033 break;
1034 }
1035
1036 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001037 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001038 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001039 *pui8++ = fExist;
1040 remaining_bits_len -= 1;
1041
1042 bit_offset++;
1043
1044 if (fExist == 0)
1045 { /* Skip 'i' entries */
1046 pDescr += pDescr->i;
1047 }
1048 pDescr++;
1049
1050 break;
1051 }
1052
1053 case CSN_VARIABLE_BITMAP_1:
1054 { /* Bitmap from here and to the end of message */
1055
1056 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1057
1058 /*no break -
1059 * with a length set we have a regular variable length bitmap so we continue */
1060 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001061 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001062 case CSN_VARIABLE_BITMAP:
1063 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1064 * <N: bit (5)> <bitmap: bit(N + offset)>
1065 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1066 * The result is right aligned!
1067 */
1068 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1069
1070 no_of_bits += pDescr->i; /* adjusted by offset */
1071
1072 if (no_of_bits > 0)
1073 {
1074 remaining_bits_len -= no_of_bits;
1075
1076 if (remaining_bits_len < 0)
1077 {
1078 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1079 }
1080
1081 { /* extract bits */
1082 guint8* pui8 = pui8DATA(data, pDescr->offset);
1083 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1084
1085 if (nB1 > 0)
1086 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001087 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01001088 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001089 pui8++;
1090 no_of_bits -= nB1;
1091 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1092 }
1093
1094 /* remaining no_of_bits is a multiple of 8 or 0 */
1095 while (no_of_bits > 0)
1096 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001097 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001098 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001099 pui8++;
1100 no_of_bits -= 8;
1101 }
1102 }
1103 }
1104 pDescr++;
1105 break;
1106 }
1107
1108 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1109 { /* Bitmap from here and to the end of message */
1110
1111 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1112
1113 /* no break -
1114 * with a length set we have a regular left aligned variable length bitmap so we continue
1115 */
1116 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001117 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001118 case CSN_LEFT_ALIGNED_VAR_BMP:
1119 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1120 * <N: bit (5)> <bitmap: bit(N + offset)>
1121 * bit array with length (in bits) specified in parameter (pDescr->descr)
1122 */
1123 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1124
1125 no_of_bits += pDescr->i;/* size adjusted by offset */
1126
1127 if (no_of_bits > 0)
1128 {
1129 remaining_bits_len -= no_of_bits;
1130
1131 if (remaining_bits_len < 0)
1132 {
1133 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1134 }
1135
1136 { /* extract bits */
1137 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001138
Neels Hofmeyr02415262016-09-02 02:15:26 +02001139 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001140 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001141 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001142 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001143 pui8++;
1144 no_of_bits -= 8;
1145 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001146 if (no_of_bits > 0)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001147 {
1148 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001149 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001150 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001151 bit_offset += no_of_bits;
1152 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001153 }
1154 }
1155 }
1156
1157 /* bitmap was successfully extracted or it was empty */
1158 pDescr++;
1159 break;
1160 }
1161
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001162 case CSN_PADDING_BITS:
1163 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01001164 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001165 if (remaining_bits_len > 0)
1166 {
1167 while (remaining_bits_len > 0)
1168 {
Pascal Quantinc5155512020-01-24 17:33:06 +01001169 guint bits_to_handle = remaining_bits_len%8;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001170 if (bits_to_handle > 0)
1171 {
Harald Welte570f9132020-03-19 15:03:01 +01001172 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001173 remaining_bits_len -= bits_to_handle;
1174 bit_offset += bits_to_handle;
1175 }
1176 else if (bits_to_handle == 0)
1177 {
Harald Welte570f9132020-03-19 15:03:01 +01001178 LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001179 remaining_bits_len -= 8;
1180 bit_offset += 8;
1181 }
1182 }
1183 }
1184 if (remaining_bits_len < 0)
1185 {
1186 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1187 }
1188
1189 /* Padding was successfully extracted or it was empty */
1190 pDescr++;
1191 break;
1192 }
1193
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001194 case CSN_VARIABLE_ARRAY:
1195 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1196 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1197 * Array with length specified in parameter:
1198 * <count: bit (x)>
1199 * <list: octet(count + offset)>
1200 */
1201 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1202
1203 count += pDescr->i; /* Adjusted by offset */
1204
1205 if (count > 0)
1206 {
1207 remaining_bits_len -= count * 8;
1208
1209 if (remaining_bits_len < 0)
1210 {
1211 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1212 }
1213
1214 pui8 = pui8DATA(data, pDescr->offset);
1215
1216 while (count > 0)
1217 {
1218 readIndex -= 8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001219 *pui8 = bitvec_read_field(vector, readIndex, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001220 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001221 pui8++;
1222 bit_offset += 8;
1223 count--;
1224 }
1225 }
1226
1227 pDescr++;
1228 break;
1229 }
1230
1231 case CSN_RECURSIVE_ARRAY:
1232 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1233 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1234 * where <element> ::= bit(value)
1235 * <tag> ::= 0 | 1
1236 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1237 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1238 * REMARK: recursive way to specify an array but an iterative implementation!
1239 */
1240 gint16 no_of_bits = pDescr->i;
1241 guint8 ElementCount = 0;
1242
1243 pui8 = pui8DATA(data, pDescr->offset);
1244
Alexander Couzensccde5c92017-02-04 03:10:08 +01001245 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001246 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001247 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001248 bit_offset++;
1249 remaining_bits_len--;
1250
1251 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001252 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001253 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001254 pui8++;
1255 remaining_bits_len -= no_of_bits;
1256 ElementCount++;
1257
1258 if (remaining_bits_len < 0)
1259 {
1260 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1261 }
1262
1263 bit_offset += no_of_bits;
1264 }
1265
Harald Welte570f9132020-03-19 15:03:01 +01001266 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001267 /* existNextElement() returned FALSE, 1 bit consumed */
1268 bit_offset++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001269 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001270
1271 /* Store the counted number of elements of the array */
1272 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1273
1274 pDescr++;
1275 break;
1276 }
1277
1278 case CSN_RECURSIVE_TARRAY:
1279 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1280 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001281 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001282 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001283 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001284 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001285 guint8 ElementCount = 0;
1286 pui8 = pui8DATA(data, pDescr->offset);
1287
Alexander Couzensccde5c92017-02-04 03:10:08 +01001288 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001289 { /* tag control shows existence of next list elements */
Harald Welte570f9132020-03-19 15:03:01 +01001290 LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001291 /* existNextElement() returned TRUE, 1 bit consumed */
1292 bit_offset++;
1293 remaining_bits_len--;
1294 ElementCount++;
1295
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001296 if (ElementCount > nSizeArray)
1297 {
1298 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1299 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1300 }
1301
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001302 { /* unpack the following data structure */
1303 csnStream_t arT = *ar;
1304 gint16 Status;
1305 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001306 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001307
1308 if (Status >= 0)
1309 { /* successful completion */
1310 pui8 += nSizeElement; /* -> to next data element */
1311 remaining_bits_len = arT.remaining_bits_len;
1312 bit_offset = arT.bit_offset;
1313 }
1314 else
1315 { /* something went awry */
1316 return Status;
1317 }
1318 }
1319
1320 if (remaining_bits_len < 0)
1321 {
1322 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1323 }
1324 }
1325
Harald Welte570f9132020-03-19 15:03:01 +01001326 LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001327
1328 /* existNextElement() returned FALSE, 1 bit consumed */
Vadim Yanitskiye87066d2020-02-17 18:02:32 +07001329 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001330 bit_offset++;
1331
1332 /* Store the counted number of elements of the array */
1333 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1334
1335 pDescr++;
1336 break;
1337 }
1338
1339 case CSN_RECURSIVE_TARRAY_2:
1340 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1341
1342 Tag = REVERSED_TAG;
1343
1344 /* NO break -
1345 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1346 */
1347 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01001348 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001349 case CSN_RECURSIVE_TARRAY_1:
1350 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1351 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001352 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001353 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001354 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001355 guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001356 guint8 ElementCount = 0;
1357 csnStream_t arT = *ar;
1358 gboolean EndOfList = FALSE;
1359 gint16 Status;
1360 pui8 = pui8DATA(data, pDescr->offset);
1361
1362 do
1363 { /* get data element */
1364 ElementCount++;
1365
Pau Espin Pedrolefad80b2020-03-23 14:35:26 +01001366 if (ElementCount > nSizeArray)
1367 {
1368 LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
1369 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
1370 }
1371
Harald Welte570f9132020-03-19 15:03:01 +01001372 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001373
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001374 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001375 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001376
1377 if (Status >= 0)
1378 { /* successful completion */
1379 pui8 += nSizeElement; /* -> to next */
1380 remaining_bits_len = arT.remaining_bits_len;
1381 bit_offset = arT.bit_offset;
1382 }
1383 else
1384 { /* something went awry */
1385 return Status;
1386 }
1387
1388 if (remaining_bits_len < 0)
1389 {
1390 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1391 }
1392
1393 /* control of next element's tag */
Harald Welte570f9132020-03-19 15:03:01 +01001394 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001395 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001396
1397 bit_offset++;
1398 remaining_bits_len--; /* 1 bit consumed (tag) */
1399 } while (!EndOfList);
1400
1401
1402 /* Store the count of the array */
1403 *pui8DATA(data, pDescr->i) = ElementCount;
1404 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1405 pDescr++;
1406 break;
1407 }
1408
1409 case CSN_FIXED:
1410 { /* Verify the fixed bits */
1411 guint8 no_of_bits = (guint8) pDescr->i;
1412 guint32 ui32;
1413
1414 if (no_of_bits <= 32)
1415 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001416 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001417 }
1418 else
1419 {
1420 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1421 }
1422 if (ui32 != (unsigned)(gint32)pDescr->offset)
1423 {
1424 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1425 }
1426
Harald Welte570f9132020-03-19 15:03:01 +01001427 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001428 remaining_bits_len -= no_of_bits;
1429 bit_offset += no_of_bits;
1430 pDescr++;
1431 break;
1432 }
1433
1434 case CSN_CALLBACK:
1435 {
1436 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1437 break;
1438 }
1439
1440 case CSN_TRAP_ERROR:
1441 {
1442 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1443 }
1444
1445 case CSN_END:
1446 {
1447 ar->remaining_bits_len = remaining_bits_len;
1448 ar->bit_offset = bit_offset;
1449 return remaining_bits_len;
1450 }
1451
1452 default:
1453 {
1454 assert(0);
1455 }
1456
1457
1458 }
1459
1460 } while (remaining_bits_len >= 0);
1461
1462 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1463}
1464
1465
1466
1467
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001468gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001469{
1470 gint remaining_bits_len = ar->remaining_bits_len;
1471 gint bit_offset = ar->bit_offset;
1472 guint8* pui8;
1473 guint16* pui16;
1474 guint32* pui32;
1475 guint64* pui64;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001476 unsigned ib;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001477
1478 guint8 Tag = STANDARD_TAG;
1479
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001480 if (remaining_bits_len < 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001481 {
Vadim Yanitskiy29aeb902020-03-06 08:53:36 +07001482 return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001483 }
1484
1485 do
1486 {
1487 switch (pDescr->type)
1488 {
1489 case CSN_BIT:
1490 {
1491 if (remaining_bits_len > 0)
1492 {
1493 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001494 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001495 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001496 /* end add the bit value to protocol tree */
1497 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001498 else if(pDescr->may_be_null)
1499 {
Harald Welte570f9132020-03-19 15:03:01 +01001500 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001501 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001502 else
1503 {
1504 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1505 }
1506
1507 pDescr++;
1508 remaining_bits_len--;
1509 bit_offset++;
1510 break;
1511 }
1512
1513 case CSN_NULL:
1514 { /* Empty member! */
1515 pDescr++;
1516 break;
1517 }
1518
1519 case CSN_UINT:
1520 {
1521 guint8 no_of_bits = (guint8) pDescr->i;
1522
1523 if (remaining_bits_len >= no_of_bits)
1524 {
1525 if (no_of_bits <= 8)
1526 {
1527 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001528 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001529 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001530 }
1531 else if (no_of_bits <= 16)
1532 {
1533 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001534 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001535 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001536 }
1537 else if (no_of_bits <= 32)
1538 {
1539 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001540 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001541 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001542 }
1543 else
1544 {
1545 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1546 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001547
1548 remaining_bits_len -= no_of_bits;
1549 bit_offset += no_of_bits;
1550 }
1551 else if(pDescr->may_be_null)
1552 {
Harald Welte570f9132020-03-19 15:03:01 +01001553 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001554 }
1555 else
1556 {
1557 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1558 }
1559
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001560 pDescr++;
1561 break;
1562 }
1563
1564 case CSN_UINT_OFFSET:
1565 {
1566 guint8 no_of_bits = (guint8) pDescr->i;
1567
1568 if (remaining_bits_len >= no_of_bits)
1569 {
1570 if (no_of_bits <= 8)
1571 {
1572 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001573 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001574 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001575 }
1576 else if (no_of_bits <= 16)
1577 {
1578 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001579 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001580 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001581 }
1582 else if (no_of_bits <= 32)
1583 {
1584 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001585 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001586 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001587 }
1588 else
1589 {
1590 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1591 }
1592 }
1593 else
1594 {
1595 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1596 }
1597
1598 remaining_bits_len -= no_of_bits;
1599 bit_offset += no_of_bits;
1600 pDescr++;
1601 break;
1602 }
1603
1604 case CSN_UINT_LH:
1605 {
1606 guint8 no_of_bits = (guint8) pDescr->i;
1607
1608 if (remaining_bits_len >= no_of_bits)
1609 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001610 if (no_of_bits <= 8)
1611 {
1612 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001613 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001614 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001615 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001616 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001617 *writeIndex -= no_of_bits;
1618 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001619 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001620
1621 }
1622 else
1623 {/* Maybe we should support more than 8 bits ? */
1624 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1625 }
1626 }
1627 else
1628 {
1629 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1630 }
1631
1632 remaining_bits_len -= no_of_bits;
1633 bit_offset += no_of_bits;
1634 pDescr++;
1635 break;
1636 }
1637
1638 case CSN_UINT_ARRAY:
1639 {
1640 guint8 no_of_bits = (guint8) pDescr->i;
1641 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1642
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001643 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001644 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1645 nCount = *pui16DATA(data, nCount);
1646 }
1647
1648 if (remaining_bits_len >= no_of_bits)
1649 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001650 if (no_of_bits <= 8)
1651 {
1652 pui8 = pui8DATA(data, pDescr->offset);
1653 do
1654 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001655 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001656 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001657 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001658 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001659 bit_offset += no_of_bits;
1660 } while (--nCount > 0);
1661 }
1662 else if (no_of_bits <= 16)
1663 {
1664 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1665 }
1666 else if (no_of_bits <= 32)
1667 {
1668 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1669 }
1670 else
1671 {
1672 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1673 }
1674 }
1675 else
1676 {
1677 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1678 }
1679 pDescr++;
1680 break;
1681 }
1682
1683 case CSN_VARIABLE_TARRAY_OFFSET:
1684 case CSN_VARIABLE_TARRAY:
1685 case CSN_TYPE_ARRAY:
1686 {
1687 gint16 Status;
1688 csnStream_t arT = *ar;
1689 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01001690 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001691
1692 pui8 = pui8DATA(data, pDescr->offset);
1693 if (pDescr->type == CSN_VARIABLE_TARRAY)
1694 { /* Count specified in field */
1695 nCount = *pui8DATA(data, pDescr->i);
1696 }
1697 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1698 { /* Count specified in field */
1699 nCount = *pui8DATA(data, pDescr->i);
1700 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1701 }
1702
1703 while (nCount > 0)
1704 { /* resulting array of length 0 is possible
1705 * but no bits shall be read from bitstream
1706 */
1707
Harald Welte570f9132020-03-19 15:03:01 +01001708 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001709 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1710 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1711 if (Status >= 0)
1712 {
1713 pui8 += nSize;
1714 remaining_bits_len = arT.remaining_bits_len;
1715 bit_offset = arT.bit_offset;
1716
1717 }
1718 else
1719 {
1720 return Status;
1721 }
1722 nCount--;
1723 }
1724
1725 pDescr++;
1726 break;
1727 }
1728
1729 case CSN_BITMAP:
1730 { /* bitmap with given length. The result is left aligned! */
1731 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1732
1733 if (no_of_bits > 0)
1734 {
1735
1736 if (no_of_bits <= 32)
1737 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001738 for(ib = 0; ib < 4; ib++)
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001739 {
1740 pui8 = pui8DATA(data, pDescr->offset+ib);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001741 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01001742 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001743 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001744 }
1745 else if (no_of_bits <= 64)
1746 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001747 for(ib = 0; ib < 8; 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
1755 {
1756 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1757 }
1758
1759 remaining_bits_len -= no_of_bits;
1760 assert(remaining_bits_len >= 0);
1761 bit_offset += no_of_bits;
1762 }
1763 /* bitmap was successfully extracted or it was empty */
1764
1765 pDescr++;
1766 break;
1767 }
1768
1769 case CSN_TYPE:
1770 {
1771 gint16 Status;
1772 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01001773 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001774 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1775 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01001776 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001777 if (Status >= 0)
1778 {
1779
1780 remaining_bits_len = arT.remaining_bits_len;
1781 bit_offset = arT.bit_offset;
1782 pDescr++;
1783 }
1784 else
1785 {
1786 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1787 return Status;
1788 }
1789
1790 break;
1791 }
1792
1793 case CSN_CHOICE:
1794 {
1795 //gint16 count = pDescr->i;
1796 guint8 i = 0;
Anders Broman60bf8452020-01-24 17:35:48 +01001797 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001798
1799 pui8 = pui8DATA(data, pDescr->offset);
1800 i = *pui8;
1801 pChoice += i;
1802 guint8 no_of_bits = pChoice->bits;
1803 guint8 value = pChoice->value;
Harald Welte570f9132020-03-19 15:03:01 +01001804 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001805 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001806
1807 CSN_DESCR descr[2];
1808 gint16 Status;
1809 csnStream_t arT = *ar;
1810
1811 descr[0] = pChoice->descr;
1812 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1813 descr[1].type = CSN_END;
1814 bit_offset += no_of_bits;
1815 remaining_bits_len -= no_of_bits;
1816
1817 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1818 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1819
1820 if (Status >= 0)
1821 {
1822 remaining_bits_len = arT.remaining_bits_len;
1823 bit_offset = arT.bit_offset;
1824 }
1825 else
1826 {
1827 return Status;
1828 }
1829
1830 pDescr++;
1831 break;
1832 }
1833
1834 case CSN_SERIALIZE:
1835 {
Pau Espin Pedrol5b716972020-01-24 17:24:01 +01001836 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001837 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001838 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001839 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001840 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001841
1842 // store writeIndex for length value (7 bit)
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001843 lengthIndex = *writeIndex;
1844 *writeIndex += length_len;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001845 bit_offset += length_len;
1846 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001847 arT.direction = 0;
1848 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1849 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001850
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001851 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
Harald Welte570f9132020-03-19 15:03:01 +01001852 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001853
1854 if (Status >= 0)
1855 {
1856 remaining_bits_len = arT.remaining_bits_len;
1857 bit_offset = arT.bit_offset;
1858 pDescr++;
1859 }
1860 else
1861 {
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001862 // Has already been processed:
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001863 return Status;
1864 }
1865
1866 break;
1867 }
1868
1869 case CSN_UNION_LH:
1870 case CSN_UNION:
1871 {
1872 gint16 Bits;
1873 guint8 index;
1874 gint16 count = pDescr->i;
1875 const CSN_DESCR* pDescrNext = pDescr;
1876
1877 pDescrNext += count + 1; /* now this is next after the union */
1878 if ((count <= 0) || (count > 16))
1879 {
1880 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1881 }
1882
1883 /* Now get the bits to extract the index */
1884 Bits = ixBitsTab[count];
1885 index = 0;
1886
1887 /* Assign UnionType */
1888 pui8 = pui8DATA(data, pDescr->offset);
1889 //read index from data and write to vector
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001890 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001891
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001892 //decode index
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001893 *writeIndex -= Bits;
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +01001894
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001895 while (Bits > 0)
1896 {
1897 index <<= 1;
1898
1899 if (CSN_UNION_LH == pDescr->type)
1900 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001901 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001902 }
1903 else
1904 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001905 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001906 }
1907
1908 remaining_bits_len--;
1909 bit_offset++;
1910 Bits--;
1911 }
1912
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001913 *writeIndex -= Bits;
1914 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001915
1916
1917 /* script index to continue on, limited in case we do not have a power of 2 */
1918 pDescr += (MIN(index + 1, count));
Harald Welte570f9132020-03-19 15:03:01 +01001919 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001920
1921 switch (pDescr->type)
1922 { /* get the right element of the union based on computed index */
1923
1924 case CSN_BIT:
1925 {
1926 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001927 bitvec_write_field(vector, writeIndex, *pui8, 1);
Harald Welte570f9132020-03-19 15:03:01 +01001928 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001929 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001930 bit_offset++;
1931 pDescr++;
1932 break;
1933 }
1934
1935 case CSN_NULL:
1936 { /* Empty member! */
1937 pDescr++;
1938 break;
1939 }
1940
1941 case CSN_UINT:
1942 {
1943 guint8 no_of_bits = (guint8) pDescr->i;
1944 if (remaining_bits_len >= no_of_bits)
1945 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001946 if (no_of_bits <= 8)
1947 {
1948 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001949 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001950 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001951 }
1952 else if (no_of_bits <= 16)
1953 {
1954 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001955 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001956 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001957 }
1958 else if (no_of_bits <= 32)
1959 {
1960 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001961 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001962 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001963 }
1964 else
1965 {
1966 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1967 }
1968 }
1969 else
1970 {
1971 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1972 }
1973
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01001974 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001975 bit_offset += no_of_bits;
1976 pDescr++;
1977 break;
1978 }
1979
1980 case CSN_UINT_OFFSET:
1981 {
1982 guint8 no_of_bits = (guint8) pDescr->i;
1983
1984 if (remaining_bits_len >= no_of_bits)
1985 {
1986 if (no_of_bits <= 8)
1987 {
1988 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001989 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001990 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001991 }
1992 else if (no_of_bits <= 16)
1993 {
1994 pui16 = pui16DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07001995 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01001996 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001997 }
1998 else if (no_of_bits <= 32)
1999 {
2000 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002001 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002002 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002003 }
2004 else
2005 {
2006 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2007 }
2008 }
2009 else
2010 {
2011 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2012 }
2013
2014 remaining_bits_len -= no_of_bits;
2015 bit_offset += no_of_bits;
2016 pDescr++;
2017 break;
2018 }
2019
2020 case CSN_UINT_LH:
2021 {
2022 guint8 no_of_bits = (guint8) pDescr->i;
2023
2024 if (remaining_bits_len >= no_of_bits)
2025 {
2026 remaining_bits_len -= no_of_bits;
2027 if (no_of_bits <= 8)
2028 {
2029 pui8 = pui8DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002030 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002031 // TODO : Change get_masked_bits8()
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002032 *writeIndex -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002033 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002034 *writeIndex -= no_of_bits;
2035 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002036 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002037
2038 }
2039 else
2040 {/* Maybe we should support more than 8 bits ? */
2041 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2042 }
2043 }
2044 else
2045 {
2046 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2047 }
2048
2049 remaining_bits_len -= no_of_bits;
2050 bit_offset += no_of_bits;
2051 pDescr++;
2052 break;
2053 }
2054
2055 case CSN_UINT_ARRAY:
2056 {
2057 guint8 no_of_bits = (guint8) pDescr->i;
2058 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2059
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002060 if (pDescr->value != 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002061 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2062 nCount = *pui16DATA(data, nCount);
2063 }
2064
2065 if (remaining_bits_len >= no_of_bits)
2066 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002067 if (no_of_bits <= 8)
2068 {
2069 pui8 = pui8DATA(data, pDescr->offset);
2070 do
2071 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002072 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002073 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002074 pui8++;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002075 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002076 bit_offset += no_of_bits;
2077 } while (--nCount > 0);
2078 }
2079 else if (no_of_bits <= 16)
2080 {
2081 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2082 }
2083 else if (no_of_bits <= 32)
2084 {
2085 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2086 }
2087 else
2088 {
2089 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2090 }
2091 }
2092 else
2093 {
2094 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2095 }
2096 pDescr++;
2097 break;
2098 }
2099
2100 case CSN_VARIABLE_TARRAY_OFFSET:
2101 case CSN_VARIABLE_TARRAY:
2102 case CSN_TYPE_ARRAY:
2103 {
2104 gint16 Status;
2105 csnStream_t arT = *ar;
2106 gint16 nCount = pDescr->i;
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002107 guint16 nSize = (guint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002108
2109 pui8 = pui8DATA(data, pDescr->offset);
2110 if (pDescr->type == CSN_VARIABLE_TARRAY)
2111 { /* Count specified in field */
2112 nCount = *pui8DATA(data, pDescr->i);
2113 }
2114 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2115 { /* Count specified in field */
2116 nCount = *pui8DATA(data, pDescr->i);
2117 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2118 }
2119
2120 while (nCount > 0)
2121 { /* resulting array of length 0 is possible
2122 * but no bits shall be read from bitstream
2123 */
2124
Harald Welte570f9132020-03-19 15:03:01 +01002125 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002126 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2127 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2128 if (Status >= 0)
2129 {
2130 pui8 += nSize;
2131 remaining_bits_len = arT.remaining_bits_len;
2132 bit_offset = arT.bit_offset;
2133 }
2134 else
2135 {
2136 return Status;
2137 }
2138 nCount--;
2139 }
2140
2141 pDescr++;
2142 break;
2143 }
2144
2145 case CSN_BITMAP:
2146 { /* bitmap with given length. The result is left aligned! */
2147 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2148
2149 if (no_of_bits > 0)
2150 {
2151
2152 if (no_of_bits <= 32)
2153 {
2154 pui32 = pui32DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002155 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002156 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002157 }
2158 else if (no_of_bits <= 64)
2159 {
2160 pui64 = pui64DATA(data, pDescr->offset);
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002161 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002162 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002163 }
2164 else
2165 {
2166 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2167 }
2168
2169 remaining_bits_len -= no_of_bits;
2170 assert(remaining_bits_len >= 0);
2171 bit_offset += no_of_bits;
2172 }
2173 /* bitmap was successfully extracted or it was empty */
2174
2175 pDescr++;
2176 break;
2177 }
2178
2179 case CSN_TYPE:
2180 {
2181 gint16 Status;
2182 csnStream_t arT = *ar;
Harald Welte570f9132020-03-19 15:03:01 +01002183 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002184 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2185 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Harald Welte570f9132020-03-19 15:03:01 +01002186 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002187 if (Status >= 0)
2188 {
2189 remaining_bits_len = arT.remaining_bits_len;
2190 bit_offset = arT.bit_offset;
2191 pDescr++;
2192 }
2193 else
2194 {
2195 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2196 return Status;
2197 }
2198
2199 break;
2200 }
2201
2202 default:
2203 { /* descriptions of union elements other than above are illegal */
2204 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2205 }
2206 }
2207
2208 pDescr = pDescrNext;
2209 break;
2210 }
2211
2212 case CSN_EXIST:
2213 case CSN_EXIST_LH:
2214 {
2215 guint8 fExist;
2216 unsigned exist = 0;
2217 pui8 = pui8DATA(data, pDescr->offset);
2218 exist = *pui8;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002219 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002220 writeIndex--;
2221 if (CSN_EXIST_LH == pDescr->type)
2222 {
2223 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2224 }
2225 else
2226 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002227 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002228 }
2229 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002230 bitvec_write_field(vector, writeIndex, fExist, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002231 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002232 remaining_bits_len--;
2233 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002234 pDescr++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002235
2236 if (!exist)
2237 {
2238 ar->remaining_bits_len = remaining_bits_len;
2239 ar->bit_offset = bit_offset;
2240 return remaining_bits_len;
2241 }
2242 break;
2243 }
2244
2245 case CSN_NEXT_EXIST:
2246 {
2247 guint8 fExist;
2248
2249 pui8 = pui8DATA(data, pDescr->offset);
2250
2251 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002252 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002253 { /* no more bits to decode is fine here - end of message detected and allowed */
2254
2255 /* Skip i entries + this entry */
2256 pDescr += pDescr->i + 1;
2257
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002258 break;
2259 }
2260
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002261 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002262 fExist = *pui8;
Harald Welte570f9132020-03-19 15:03:01 +01002263 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002264
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002265 remaining_bits_len--;
2266 bit_offset++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002267
2268 if (fExist == 0)
2269 { /* Skip 'i' entries */
2270 pDescr += pDescr->i;
2271 }
2272
2273 pDescr++;
2274 break;
2275 }
2276
2277 case CSN_NEXT_EXIST_LH:
2278 {
2279 guint8 fExist;
2280 pui8 = pui8DATA(data, pDescr->offset);
2281
2282 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2283 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2284 { /* no more bits to decode is fine here - end of message detected and allowed */
2285
2286 /* skip 'i' entries + this entry */
2287 pDescr += pDescr->i + 1;
2288
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002289 /* set the data member to "not exist" */
2290 //*pui8 = 0;
2291 break;
2292 }
2293
2294 /* the "regular" M_NEXT_EXIST_LH description element */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002295 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002296 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002297 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002298 writeIndex--;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002299 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002300 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002301
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002302 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002303 bit_offset++;
2304
2305 if (fExist == 0)
2306 { /* Skip 'i' entries */
2307 pDescr += pDescr->i;
2308 }
2309 pDescr++;
2310
2311 break;
2312 }
2313
2314 case CSN_VARIABLE_BITMAP_1:
2315 { /* Bitmap from here and to the end of message */
2316
2317 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2318
2319 /*no break -
2320 * with a length set we have a regular variable length bitmap so we continue */
2321 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002322 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002323 case CSN_VARIABLE_BITMAP:
2324 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2325 * <N: bit (5)> <bitmap: bit(N + offset)>
2326 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2327 * The result is right aligned!
2328 */
2329 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2330
2331 no_of_bits += pDescr->i; /* adjusted by offset */
2332
2333 if (no_of_bits > 0)
2334 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002335
2336 if (remaining_bits_len < 0)
2337 {
2338 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2339 }
2340
2341 { /* extract bits */
2342 guint8* pui8 = pui8DATA(data, pDescr->offset);
2343 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2344
2345 if (nB1 > 0)
2346 { /* take care of the first byte - it will be right aligned */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002347 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002348 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002349 pui8++;
2350 no_of_bits -= nB1;
2351 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002352 remaining_bits_len -= nB1;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002353 }
2354
2355 /* remaining no_of_bits is a multiple of 8 or 0 */
2356 while (no_of_bits > 0)
2357 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002358 bitvec_write_field(vector, writeIndex, *pui8, 8);
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 -= 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002362 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002363 }
2364 }
2365 }
2366 pDescr++;
2367 break;
2368 }
2369
2370 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2371 { /* Bitmap from here and to the end of message */
2372
2373 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2374
2375 /* no break -
2376 * with a length set we have a regular left aligned variable length bitmap so we continue
2377 */
2378 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002379 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002380 case CSN_LEFT_ALIGNED_VAR_BMP:
2381 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2382 * <N: bit (5)> <bitmap: bit(N + offset)>
2383 * bit array with length (in bits) specified in parameter (pDescr->descr)
2384 */
2385
2386 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2387
2388 no_of_bits += pDescr->i;/* size adjusted by offset */
2389
2390 if (no_of_bits > 0)
2391 {
2392 remaining_bits_len -= no_of_bits;
2393
2394 if (remaining_bits_len < 0)
2395 {
2396 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2397 }
2398
2399 { /* extract bits */
2400 guint8* pui8 = pui8DATA(data, pDescr->offset);
2401 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2402
2403 while (no_of_bits > 0)
2404 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002405 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002406 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002407 pui8++;
2408 no_of_bits -= 8;
2409 }
2410 if (nB1 > 0)
2411 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002412 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Harald Welte570f9132020-03-19 15:03:01 +01002413 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002414 pui8++;
2415 no_of_bits -= nB1;
2416 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2417 }
2418 }
2419
2420 }
2421
2422 /* bitmap was successfully extracted or it was empty */
2423 pDescr++;
2424 break;
2425 }
2426
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002427 case CSN_PADDING_BITS:
2428 { /* Padding from here and to the end of message */
Harald Welte570f9132020-03-19 15:03:01 +01002429 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002430 guint8 filler = 0x2b;
2431 if (remaining_bits_len > 0)
2432 {
2433 while (remaining_bits_len > 0)
2434 {
2435 guint8 bits_to_handle = remaining_bits_len%8;
2436 if (bits_to_handle > 0)
2437 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302438 /* section 11 of 44.060
2439 * The padding bits may be the 'null' string. Otherwise, the
2440 * padding bits starts with bit '0', followed by 'spare padding'
2441 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2442 */
2443 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002444 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
Harald Welte570f9132020-03-19 15:03:01 +01002445 LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002446 remaining_bits_len -= bits_to_handle;
2447 bit_offset += bits_to_handle;
2448 }
2449 else if (bits_to_handle == 0)
2450 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002451 bitvec_write_field(vector, writeIndex, filler, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002452 LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002453 remaining_bits_len -= 8;
2454 bit_offset += 8;
2455 }
2456 }
2457 }
2458 if (remaining_bits_len < 0)
2459 {
2460 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2461 }
2462
2463 /* Padding was successfully extracted or it was empty */
2464 pDescr++;
2465 break;
2466 }
2467
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002468 case CSN_VARIABLE_ARRAY:
2469 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2470 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2471 * Array with length specified in parameter:
2472 * <count: bit (x)>
2473 * <list: octet(count + offset)>
2474 */
2475 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2476
2477 count += pDescr->i; /* Adjusted by offset */
2478
2479 if (count > 0)
2480 {
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002481 if (remaining_bits_len < 0)
2482 {
2483 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2484 }
2485
2486 pui8 = pui8DATA(data, pDescr->offset);
2487
2488 while (count > 0)
2489 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002490 bitvec_write_field(vector, writeIndex, *pui8, 8);
Harald Welte570f9132020-03-19 15:03:01 +01002491 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002492 pui8++;
2493 bit_offset += 8;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002494 remaining_bits_len -= 8;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002495 count--;
2496 }
2497 }
2498
2499 pDescr++;
2500 break;
2501 }
2502
2503 case CSN_RECURSIVE_ARRAY:
2504 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2505 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2506 * where <element> ::= bit(value)
2507 * <tag> ::= 0 | 1
2508 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2509 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2510 * REMARK: recursive way to specify an array but an iterative implementation!
2511 */
2512 gint16 no_of_bits = pDescr->i;
2513 guint8 ElementCount = 0;
2514 pui8 = pui8DATA(data, pDescr->offset);
2515 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2516 while (ElementCount > 0)
2517 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002518 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002519 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002520 bit_offset++;
2521 remaining_bits_len--;
2522
2523 /* extract and store no_of_bits long element from bitstream */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002524 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002525 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002526 pui8++;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002527 ElementCount--;
2528
2529 if (remaining_bits_len < 0)
2530 {
2531 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2532 }
2533
2534 bit_offset += no_of_bits;
Jeff Morrissc0b4f4a2020-01-24 15:00:58 +01002535 remaining_bits_len -= no_of_bits;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002536 }
2537
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002538 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002539 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002540 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302541 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002542
2543 pDescr++;
2544 break;
2545 }
2546
2547 case CSN_RECURSIVE_TARRAY:
2548 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2549 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2550 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2551 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002552 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002553 guint8 ElementCount = 0;
2554 pui8 = pui8DATA(data, pDescr->offset);
2555 /* Store the counted number of elements of the array */
2556 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2557
2558 while (ElementCount > 0)
2559 { /* tag control shows existence of next list elements */
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002560 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002561 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002562 bit_offset++;
2563
2564 remaining_bits_len--;
2565 ElementCount--;
2566
2567 { /* unpack the following data structure */
2568 csnStream_t arT = *ar;
2569 gint16 Status;
2570 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002571 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002572
2573 if (Status >= 0)
2574 { /* successful completion */
2575 pui8 += nSizeElement; /* -> to next data element */
2576 remaining_bits_len = arT.remaining_bits_len;
2577 bit_offset = arT.bit_offset;
2578 }
2579 else
2580 { /* something went awry */
2581 return Status;
2582 }
2583 }
2584
2585 if (remaining_bits_len < 0)
2586 {
2587 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2588 }
2589 }
2590
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002591 bitvec_write_field(vector, writeIndex, !Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002592 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002593 bit_offset++;
2594
2595 pDescr++;
2596 break;
2597 }
2598
2599 case CSN_RECURSIVE_TARRAY_2:
2600 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2601
2602 Tag = REVERSED_TAG;
2603
2604 /* NO break -
2605 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2606 */
2607 }
Alexis La Gouttee36fb5b2020-01-24 18:22:35 +01002608 /* FALL THROUGH */
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002609 case CSN_RECURSIVE_TARRAY_1:
2610 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2611 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2612 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2613 */
Pau Espin Pedrol900c2e22020-01-24 18:05:00 +01002614 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002615 guint8 ElementCount = 0;
2616 guint8 ElementNum = 0;
2617 csnStream_t arT = *ar;
2618 gint16 Status;
2619
2620 pui8 = pui8DATA(data, pDescr->offset);
2621 /* Store the count of the array */
2622 ElementCount = *pui8DATA(data, pDescr->i);
2623 ElementNum = ElementCount;
2624
2625 while (ElementCount > 0)
2626 { /* get data element */
2627 if (ElementCount != ElementNum)
2628 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002629 bitvec_write_field(vector, writeIndex, Tag, 1);
Harald Welte570f9132020-03-19 15:03:01 +01002630 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002631 bit_offset++;
2632 remaining_bits_len--;
2633 }
2634 ElementCount--;
Harald Welte570f9132020-03-19 15:03:01 +01002635 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002636 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002637 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Harald Welte570f9132020-03-19 15:03:01 +01002638 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002639 if (Status >= 0)
2640 { /* successful completion */
2641 pui8 += nSizeElement; /* -> to next */
2642 remaining_bits_len = arT.remaining_bits_len;
2643 bit_offset = arT.bit_offset;
2644 }
2645 else
2646 { /* something went awry */
2647 return Status;
2648 }
2649
2650 if (remaining_bits_len < 0)
2651 {
2652 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2653 }
2654
2655 }
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002656 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002657 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002658 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002659 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2660 pDescr++;
2661 break;
2662 }
2663
2664 case CSN_FIXED:
2665 { /* Verify the fixed bits */
2666 guint8 no_of_bits = (guint8) pDescr->i;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +07002667 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Harald Welte570f9132020-03-19 15:03:01 +01002668 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002669 remaining_bits_len -= no_of_bits;
2670 bit_offset += no_of_bits;
2671 pDescr++;
2672 break;
2673 }
2674
2675 case CSN_CALLBACK:
2676 {
2677 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2678 break;
2679 }
2680
2681 case CSN_TRAP_ERROR:
2682 {
2683 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2684 }
2685
2686 case CSN_END:
2687 {
2688 ar->remaining_bits_len = remaining_bits_len;
2689 ar->bit_offset = bit_offset;
2690 return remaining_bits_len;
2691 }
2692
2693 default:
2694 {
2695 assert(0);
2696 }
2697
2698 }
2699
2700 } while (remaining_bits_len >= 0);
2701
2702 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2703}