blob: 9ddb9c1880fdbf684fecfb3175e274b979123dff [file] [log] [blame]
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001/* csn1.cpp
2 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
31#include <iostream>
32#include <cstdlib>
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040033#include <assert.h>
34#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020035#define __STDC_FORMAT_MACROS
36#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040038#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030039
40
41#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
42#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
43#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
44#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
45#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
46/* used to tag existence of next element in variable length lists */
47#define STANDARD_TAG 1
48#define REVERSED_TAG 0
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030049
50using namespace std;
51static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
52
53
54/* Returns no_of_bits (up to 8) masked with 0x2B */
55
56static guint8
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +040057get_masked_bits8( bitvec *vector, unsigned& readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030058{
59 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
60 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
61 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
62 guint8 result;
63 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
64 readIndex -= relative_bit_offset;
65 if (bit_shift >= 0)
66 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010067 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030068 readIndex-= bit_shift;
69 result &= maskBits[no_of_bits];
70 }
71 else
72 {
Alexander Couzensccde5c92017-02-04 03:10:08 +010073 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030074 hight_part = (guint8) (hight_part << (-bit_shift));
Alexander Couzensccde5c92017-02-04 03:10:08 +010075 result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> (8 + bit_shift);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030076 readIndex = readIndex - (8 - (-bit_shift));
77 result |= hight_part;
78 }
79 return result;
80}
81
82/**
83 * ================================================================================================
84 * set initial/start values in help data structure used for packing/unpacking operation
85 * ================================================================================================
86 */
87void
88csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
89{
90 ar->remaining_bits_len = remaining_bits_len;
91 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040092 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030093}
94
95static const char* ErrCodes[] =
96{
97 "General 0",
98 "General -1",
99 "DATA_NOT VALID",
100 "IN SCRIPT",
101 "INVALID UNION INDEX",
102 "NEED_MORE BITS TO UNPACK",
103 "ILLEGAL BIT VALUE",
104 "Internal",
105 "STREAM_NOT_SUPPORTED",
106 "MESSAGE_TOO_LONG"
107};
108
109static gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400110ProcessError( unsigned readIndex, const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300111{
112 gint16 i = MIN(-err, ((gint16) ElementsOf(ErrCodes)-1));
113 if (i >= 0)
114 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400115 //LOG(ERR) << sz << "Error code: "<< ErrCodes[i] << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300116 }
117 else
118 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400119 //LOG(ERR) << sz << ": " << pDescr?(pDescr->sz):"-";
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300120 }
121 return err;
122}
123
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300124
125/**
126 * ================================================================================================
127 * Return TRUE if tag in bit stream indicates existence of next list element,
128 * otherwise return FALSE.
129 * Will work for tag values equal to both 0 and 1.
130 * ================================================================================================
131 */
132
133static gboolean
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400134existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300135{
Alexander Couzensccde5c92017-02-04 03:10:08 +0100136 guint8 res = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300137 if (Tag == STANDARD_TAG)
138 {
139 return (res > 0);
140 }
141 return (res == 0);
142}
143
144
145gint16
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +0400146csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& readIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300147{
148 gint remaining_bits_len = ar->remaining_bits_len;
149 gint bit_offset = ar->bit_offset;
150 guint8* pui8;
151 guint16* pui16;
152 guint32* pui32;
153 guint64* pui64;
154 guint8 Tag = STANDARD_TAG;
155
156 if (remaining_bits_len <= 0)
157 {
158 return 0;
159 }
160
161 do
162 {
163 switch (pDescr->type)
164 {
165 case CSN_BIT:
166 {
167 if (remaining_bits_len > 0)
168 {
169 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100170 *pui8 = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400171 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300172 /* end add the bit value to protocol tree */
173 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400174 else if(pDescr->may_be_null)
175 {
176 pui8 = pui8DATA(data, pDescr->offset);
177 *pui8 = 0;
178 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
179 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300180 else
181 {
182 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
183 }
184
185 pDescr++;
186 remaining_bits_len--;
187 bit_offset++;
188 break;
189 }
190
191 case CSN_NULL:
192 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100193 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300194 pDescr++;
195 break;
196 }
197
198 case CSN_UINT:
199 {
200 guint8 no_of_bits = (guint8) pDescr->i;
201
202 if (remaining_bits_len >= no_of_bits)
203 {
204 if (no_of_bits <= 8)
205 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100206 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300207 pui8 = pui8DATA(data, pDescr->offset);
208 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400209 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300210 }
211 else if (no_of_bits <= 16)
212 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100213 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300214 pui16 = pui16DATA(data, pDescr->offset);
215 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400216 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300217 }
218 else if (no_of_bits <= 32)
219 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100220 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300221 pui32 = pui32DATA(data, pDescr->offset);
222 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400223 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300224 }
225 else
226 {
227 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
228 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400229 remaining_bits_len -= no_of_bits;
230 bit_offset += no_of_bits;
231 }
232 else if(pDescr->may_be_null)
233 {
234 if (no_of_bits <= 8)
235 {
236 pui8 = pui8DATA(data, pDescr->offset);
237 *pui8 = 0;
238 }
239 else if (no_of_bits <= 16)
240 {
241 pui16 = pui16DATA(data, pDescr->offset);
242 *pui16 = 0;
243 }
244 else if (no_of_bits <= 32)
245 {
246 pui32 = pui32DATA(data, pDescr->offset);
247 *pui32 = 0;
248 }
249 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300250 }
251 else
252 {
253 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
254 }
255
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300256 pDescr++;
257 break;
258 }
259
260 case CSN_UINT_OFFSET:
261 {
262 guint8 no_of_bits = (guint8) pDescr->i;
263
264 if (remaining_bits_len >= no_of_bits)
265 {
266 if (no_of_bits <= 8)
267 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100268 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300269 pui8 = pui8DATA(data, pDescr->offset);
270 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400271 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300272 }
273 else if (no_of_bits <= 16)
274 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100275 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300276 pui16 = pui16DATA(data, pDescr->offset);
277 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400278 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300279 }
280 else if (no_of_bits <= 32)
281 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100282 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300283 pui32 = pui32DATA(data, pDescr->offset);
284 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400285 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300286 }
287 else
288 {
289 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
290 }
291 }
292 else
293 {
294 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
295 }
296
297 remaining_bits_len -= no_of_bits;
298 bit_offset += no_of_bits;
299 pDescr++;
300 break;
301 }
302
303 case CSN_UINT_LH:
304 {
305 guint8 no_of_bits = (guint8) pDescr->i;
306
307 if (remaining_bits_len >= no_of_bits)
308 {
309 remaining_bits_len -= no_of_bits;
310 if (no_of_bits <= 8)
311 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100312 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300313 pui8 = pui8DATA(data, pDescr->offset);
314 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400315 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300316 }
317 else
318 {/* Maybe we should support more than 8 bits ? */
319 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
320 }
321 }
322 else
323 {
324 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
325 }
326
327 remaining_bits_len -= no_of_bits;
328 bit_offset += no_of_bits;
329 pDescr++;
330 break;
331 }
332
333 case CSN_UINT_ARRAY:
334 {
335 guint8 no_of_bits = (guint8) pDescr->i;
336 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
337
338 if (pDescr->serialize.value != 0)
339 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
340 nCount = *pui16DATA(data, nCount);
341 }
342
343 if (remaining_bits_len >= no_of_bits)
344 {
345 remaining_bits_len -= (no_of_bits*nCount);
346 if (no_of_bits <= 8)
347 {
348 pui8 = pui8DATA(data, pDescr->offset);
349 do
350 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100351 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400352 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300353 pui8++;
354 bit_offset += no_of_bits;
355 } while (--nCount > 0);
356 }
357 else if (no_of_bits <= 16)
358 {
359 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
360 }
361 else if (no_of_bits <= 32)
362 {
363 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
364 }
365 else
366 {
367 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
368 }
369 }
370 else
371 {
372 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
373 }
374 pDescr++;
375 break;
376 }
377
378 case CSN_VARIABLE_TARRAY_OFFSET:
379 case CSN_VARIABLE_TARRAY:
380 case CSN_TYPE_ARRAY:
381 {
382 gint16 Status;
383 csnStream_t arT = *ar;
384 gint16 nCount = pDescr->i;
385 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
386
387 pui8 = pui8DATA(data, pDescr->offset);
388 if (pDescr->type == CSN_VARIABLE_TARRAY)
389 { /* Count specified in field */
390 nCount = *pui8DATA(data, pDescr->i);
391 }
392 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
393 { /* Count specified in field */
394 nCount = *pui8DATA(data, pDescr->i);
395 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
396 }
397
398 while (nCount > 0)
399 { /* resulting array of length 0 is possible
400 * but no bits shall be read from bitstream
401 */
402
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400403 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300404 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100405 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300406 if (Status >= 0)
407 {
408 pui8 += nSize;
409 remaining_bits_len = arT.remaining_bits_len;
410 bit_offset = arT.bit_offset;
411 }
412 else
413 {
414 return Status;
415 }
416 nCount--;
417 }
418
419 pDescr++;
420 break;
421 }
422
423 case CSN_BITMAP:
424 { /* bitmap with given length. The result is left aligned! */
425 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
426
427 if (no_of_bits > 0)
428 {
429
430 if (no_of_bits <= 32)
431 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400432 for(unsigned ib = 0; ib < 4; ib++)
433 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100434 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400435 pui8 = pui8DATA(data, pDescr->offset+ib);
436 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400437 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400438 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300439 }
440 else if (no_of_bits <= 64)
441 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400442 for(unsigned ib = 0; ib < 8; ib++)
443 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100444 guint8 ui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400445 pui8 = pui8DATA(data, pDescr->offset+ib);
446 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400447 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400448 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300449 }
450 else
451 {
452 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
453 }
454
455 remaining_bits_len -= no_of_bits;
456 assert(remaining_bits_len >= 0);
457 bit_offset += no_of_bits;
458 }
459 /* bitmap was successfully extracted or it was empty */
460
461 pDescr++;
462 break;
463 }
464
465 case CSN_TYPE:
466 {
467 gint16 Status;
468 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400469 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300470 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100471 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400472 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300473 if (Status >= 0)
474 {
475 remaining_bits_len = arT.remaining_bits_len;
476 bit_offset = arT.bit_offset;
477 pDescr++;
478 }
479 else
480 {
481 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
482 return Status;
483 }
484
485 break;
486 }
487
488 case CSN_CHOICE:
489 {
490 gint16 count = pDescr->i;
491 guint8 i = 0;
492 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
493
494 while (count > 0)
495 {
496 guint8 no_of_bits = pChoice->bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100497 guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300498 if (value == pChoice->value)
499 {
500 CSN_DESCR descr[2];
501 gint16 Status;
502 csnStream_t arT = *ar;
503
504 descr[0] = pChoice->descr;
505 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
506 descr[1].type = CSN_END;
507 pui8 = pui8DATA(data, pDescr->offset);
508 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400509 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300510 bit_offset += no_of_bits;
511 remaining_bits_len -= no_of_bits;
512
513 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100514 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300515
516 if (Status >= 0)
517 {
518 remaining_bits_len = arT.remaining_bits_len;
519 bit_offset = arT.bit_offset;
520 }
521 else
522 {
523 return Status;
524 }
525 break;
526 }
527
528 readIndex -= no_of_bits;
529 count--;
530 pChoice++;
531 i++;
532 }
533
534 pDescr++;
535 break;
536 }
537
538 case CSN_SERIALIZE:
539 {
540 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
541 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400542 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300543 gint16 Status = -1;
544
Alexander Couzensccde5c92017-02-04 03:10:08 +0100545 guint8 length = bitvec_read_field(vector, &readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300546
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400547 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400548 bit_offset += length_len;
549 remaining_bits_len -= length_len;
550
551 csnStreamInit(&arT, bit_offset, length);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100552 arT.direction = 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100553 LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100554 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300555
556 if (Status >= 0)
557 {
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400558 remaining_bits_len -= length;
559 bit_offset += length;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300560 pDescr++;
561 }
562 else
563 {
564 /* Has already been processed: */
565 return Status;
566 }
567
568 break;
569 }
570
571 case CSN_UNION_LH:
572 case CSN_UNION:
573 {
574 gint16 Bits;
575 guint8 index;
576 gint16 count = pDescr->i;
577 const CSN_DESCR* pDescrNext = pDescr;
578
579 pDescrNext += count + 1; /* now this is next after the union */
580 if ((count <= 0) || (count > 16))
581 {
582 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
583 }
584
585 /* Now get the bits to extract the index */
586 Bits = ixBitsTab[count];
587 index = 0;
588
589 while (Bits > 0)
590 {
591 index <<= 1;
592
593 if (CSN_UNION_LH == pDescr->type)
594 {
595 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
596 }
597 else
598 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100599 index |= bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300600 }
601 remaining_bits_len--;
602 bit_offset++;
603 Bits--;
604 }
605
606 /* Assign UnionType */
607 pui8 = pui8DATA(data, pDescr->offset);
608 *pui8 = index;
609
610
611 /* script index to continue on, limited in case we do not have a power of 2 */
612 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400613 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300614
615 switch (pDescr->type)
616 { /* get the right element of the union based on computed index */
617
618 case CSN_BIT:
619 {
620 pui8 = pui8DATA(data, pDescr->offset);
621 *pui8 = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100622 if (bitvec_read_field(vector, &readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300623 {
624 *pui8 = 0x01;
625 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400626 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300627 remaining_bits_len -= 1;
628 bit_offset++;
629 pDescr++;
630 break;
631 }
632
633 case CSN_NULL:
634 { /* Empty member! */
Anders Broman72c102a2020-01-24 14:31:15 +0100635 bit_offset += pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300636 pDescr++;
637 break;
638 }
639
640 case CSN_UINT:
641 {
642 guint8 no_of_bits = (guint8) pDescr->i;
643 if (remaining_bits_len >= no_of_bits)
644 {
645 remaining_bits_len -= no_of_bits;
646
647 if (no_of_bits <= 8)
648 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100649 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300650 pui8 = pui8DATA(data, pDescr->offset);
651 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400652 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300653 }
654 else if (no_of_bits <= 16)
655 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100656 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300657 pui16 = pui16DATA(data, pDescr->offset);
658 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400659 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300660 }
661 else if (no_of_bits <= 32)
662 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100663 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300664 pui32 = pui32DATA(data, pDescr->offset);
665 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400666 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300667 }
668 else
669 {
670 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
671 }
672 }
673 else
674 {
675 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
676 }
677
678 bit_offset += no_of_bits;
679 pDescr++;
680 break;
681 }
682
683 case CSN_UINT_OFFSET:
684 {
685 guint8 no_of_bits = (guint8) pDescr->i;
686
687 if (remaining_bits_len >= no_of_bits)
688 {
689 if (no_of_bits <= 8)
690 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100691 guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300692 pui8 = pui8DATA(data, pDescr->offset);
693 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400694 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300695 }
696 else if (no_of_bits <= 16)
697 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100698 guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300699 pui16 = pui16DATA(data, pDescr->offset);
700 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400701 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300702 }
703 else if (no_of_bits <= 32)
704 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100705 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300706 pui32 = pui32DATA(data, pDescr->offset);
707 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400708 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300709 }
710 else
711 {
712 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
713 }
714 }
715 else
716 {
717 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
718 }
719
720 bit_offset += no_of_bits;
721 pDescr++;
722 break;
723 }
724
725 case CSN_UINT_LH:
726 {
727 guint8 no_of_bits = (guint8) pDescr->i;
728
729 if (remaining_bits_len >= no_of_bits)
730 {
731 if (no_of_bits <= 8)
732 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100733 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300734 pui8 = pui8DATA(data, pDescr->offset);
735 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400736 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300737 }
738 else
739 { /* Maybe we should support more than 8 bits ? */
740 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
741 }
742 }
743 else
744 {
745 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
746 }
747
748 bit_offset += no_of_bits;
749 pDescr++;
750 break;
751 }
752
753 case CSN_UINT_ARRAY:
754 {
755 guint8 no_of_bits = (guint8) pDescr->i;
756 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
757
758 if (pDescr->serialize.value != 0)
759 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
760 nCount = *pui16DATA(data, nCount);
761 }
762
763 if (remaining_bits_len >= no_of_bits)
764 {
765 remaining_bits_len -= (no_of_bits * nCount);
766 if (no_of_bits <= 8)
767 {
768 pui8 = pui8DATA(data, pDescr->offset);
769
770 while (nCount > 0)
771 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100772 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400773 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300774 pui8++;
775 bit_offset += no_of_bits;
776 nCount--;
777 }
778 }
779 else if (no_of_bits <= 16)
780 {
781 pui16 = pui16DATA(data, pDescr->offset);
782
783 while (nCount > 0)
784 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100785 *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400786 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300787 pui16++;
788 bit_offset += no_of_bits;
789 nCount--;
790 }
791 }
792 else if (no_of_bits <= 32)
793 { /* not supported */
794 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
795 }
796 else
797 {
798 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
799 }
800 }
801 else
802 {
803 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
804 }
805
806 pDescr++;
807 break;
808 }
809
810 case CSN_VARIABLE_TARRAY_OFFSET:
811 case CSN_VARIABLE_TARRAY:
812 case CSN_TYPE_ARRAY:
813 {
814 gint16 Status;
815 csnStream_t arT = *ar;
816 guint16 nCount = (guint16) pDescr->i;
817 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
818
819 pui8 = pui8DATA(data, pDescr->offset);
820
821 if (CSN_VARIABLE_TARRAY == pDescr->type)
822 { /* Count specified in field */
823 nCount = *pui8DATA(data, pDescr->i);
824 }
825 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
826 { /* Count specified in field */
827 nCount = *pui8DATA(data, pDescr->i);
828 nCount--; /* Offset 1 */
829 }
830
831 while (nCount--) /* Changed to handle length = 0. */
832 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400833 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300834 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100835 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300836 if (Status >= 0)
837 {
838 pui8 += nSize;
839 remaining_bits_len = arT.remaining_bits_len;
840 bit_offset = arT.bit_offset;
841 }
842 else
843 {
844 return Status;
845 }
846 }
847
848 pDescr++;
849 break;
850 }
851
852 case CSN_BITMAP:
853 { /* bitmap with given length. The result is left aligned! */
854 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
855
856 if (no_of_bits > 0)
857 {
858
859 if (no_of_bits <= 32)
860 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100861 guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300862 pui32 = pui32DATA(data, pDescr->offset);
863 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300864 }
865 else if (no_of_bits <= 64)
866 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100867 guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300868 pui64 = pui64DATA(data, pDescr->offset);
869 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200870 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300871 }
872 else
873 {
874 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
875 }
876
877 remaining_bits_len -= no_of_bits;
878 assert(remaining_bits_len >= 0);
879 bit_offset += no_of_bits;
880 }
881 /* bitmap was successfully extracted or it was empty */
882
883 pDescr++;
884 break;
885 }
886
887 case CSN_TYPE:
888 {
889 gint16 Status;
890 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400891 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300892 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +0100893 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400894 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300895 if (Status >= 0)
896 {
897 remaining_bits_len = arT.remaining_bits_len;
898 bit_offset = arT.bit_offset;
899 pDescr++;
900 }
901 else
902 { /* return error code Has already been processed: */
903 return Status;
904 }
905
906 break;
907 }
908
909 default:
910 { /* descriptions of union elements other than above are illegal */
911 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
912 }
913 }
914
915 pDescr = pDescrNext;
916 break;
917 }
918
919 case CSN_EXIST:
920 case CSN_EXIST_LH:
921 {
922 guint8 fExist;
923
924 pui8 = pui8DATA(data, pDescr->offset);
925
926 if (CSN_EXIST_LH == pDescr->type)
927 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100928 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300929 }
930 else
931 {
Alexander Couzensccde5c92017-02-04 03:10:08 +0100932 fExist = bitvec_read_field(vector, &readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300933 }
934
935 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400936 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300937 pDescr++;
938 remaining_bits_len -= 1;
939
940 if (!fExist)
941 {
942 ar->remaining_bits_len = remaining_bits_len;
943 ar->bit_offset = bit_offset;
944 return remaining_bits_len;
945 }
946
947 break;
948 }
949
950 case CSN_NEXT_EXIST:
951 {
952 guint8 fExist;
953
954 pui8 = pui8DATA(data, pDescr->offset);
955
956 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400957 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300958 { /* no more bits to decode is fine here - end of message detected and allowed */
959
960 /* Skip i entries + this entry */
961 pDescr += pDescr->i + 1;
962
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300963 /* Set the data member to "not exist" */
964 *pui8 = 0;
965 break;
966 }
967
968 /* the "regular" M_NEXT_EXIST description element */
969
970 fExist = 0x00;
Alexander Couzensccde5c92017-02-04 03:10:08 +0100971 if (bitvec_read_field(vector, &readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300972 {
973 fExist = 0x01;
974 }
975
976 *pui8 = fExist;
977 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400978 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300979 ++bit_offset;
980
981 if (fExist == 0)
982 { /* Skip 'i' entries */
983 pDescr += pDescr->i;
984 }
985
986 pDescr++;
987 break;
988 }
989
990 case CSN_NEXT_EXIST_LH:
991 {
992 guint8 fExist;
993 pui8 = pui8DATA(data, pDescr->offset);
994
995 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
996 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
997 { /* no more bits to decode is fine here - end of message detected and allowed */
998
999 /* skip 'i' entries + this entry */
1000 pDescr += pDescr->i + 1;
1001
1002 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1003 if ( pDescr->type != CSN_END )
1004 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1005 remaining_bits_len--;
1006 }
1007
1008 /* set the data member to "not exist" */
1009 *pui8 = 0;
1010 break;
1011 }
1012
1013 /* the "regular" M_NEXT_EXIST_LH description element */
1014 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001015 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001016 *pui8++ = fExist;
1017 remaining_bits_len -= 1;
1018
1019 bit_offset++;
1020
1021 if (fExist == 0)
1022 { /* Skip 'i' entries */
1023 pDescr += pDescr->i;
1024 }
1025 pDescr++;
1026
1027 break;
1028 }
1029
1030 case CSN_VARIABLE_BITMAP_1:
1031 { /* Bitmap from here and to the end of message */
1032
1033 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1034
1035 /*no break -
1036 * with a length set we have a regular variable length bitmap so we continue */
1037 }
1038
1039 case CSN_VARIABLE_BITMAP:
1040 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1041 * <N: bit (5)> <bitmap: bit(N + offset)>
1042 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1043 * The result is right aligned!
1044 */
1045 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1046
1047 no_of_bits += pDescr->i; /* adjusted by offset */
1048
1049 if (no_of_bits > 0)
1050 {
1051 remaining_bits_len -= no_of_bits;
1052
1053 if (remaining_bits_len < 0)
1054 {
1055 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1056 }
1057
1058 { /* extract bits */
1059 guint8* pui8 = pui8DATA(data, pDescr->offset);
1060 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1061
1062 if (nB1 > 0)
1063 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001064 *pui8 = bitvec_read_field(vector, &readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001065 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001066 pui8++;
1067 no_of_bits -= nB1;
1068 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1069 }
1070
1071 /* remaining no_of_bits is a multiple of 8 or 0 */
1072 while (no_of_bits > 0)
1073 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001074 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001075 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001076 pui8++;
1077 no_of_bits -= 8;
1078 }
1079 }
1080 }
1081 pDescr++;
1082 break;
1083 }
1084
1085 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1086 { /* Bitmap from here and to the end of message */
1087
1088 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1089
1090 /* no break -
1091 * with a length set we have a regular left aligned variable length bitmap so we continue
1092 */
1093 }
1094
1095 case CSN_LEFT_ALIGNED_VAR_BMP:
1096 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1097 * <N: bit (5)> <bitmap: bit(N + offset)>
1098 * bit array with length (in bits) specified in parameter (pDescr->descr)
1099 */
1100 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1101
1102 no_of_bits += pDescr->i;/* size adjusted by offset */
1103
1104 if (no_of_bits > 0)
1105 {
1106 remaining_bits_len -= no_of_bits;
1107
1108 if (remaining_bits_len < 0)
1109 {
1110 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1111 }
1112
1113 { /* extract bits */
1114 guint8* pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001115
Neels Hofmeyr02415262016-09-02 02:15:26 +02001116 while (no_of_bits >= 8)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001117 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001118 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001119 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001120 pui8++;
1121 no_of_bits -= 8;
1122 }
Neels Hofmeyr02415262016-09-02 02:15:26 +02001123 if (no_of_bits > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001124 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001125 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001126 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001127 pui8++;
Neels Hofmeyr02415262016-09-02 02:15:26 +02001128 bit_offset += no_of_bits;
1129 no_of_bits = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001130 }
1131 }
1132 }
1133
1134 /* bitmap was successfully extracted or it was empty */
1135 pDescr++;
1136 break;
1137 }
1138
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001139 case CSN_PADDING_BITS:
1140 { /* Padding from here and to the end of message */
1141 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1142 if (remaining_bits_len > 0)
1143 {
1144 while (remaining_bits_len > 0)
1145 {
1146 guint8 bits_to_handle = remaining_bits_len%8;
1147 if (bits_to_handle > 0)
1148 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001149 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001150 remaining_bits_len -= bits_to_handle;
1151 bit_offset += bits_to_handle;
1152 }
1153 else if (bits_to_handle == 0)
1154 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001155 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001156 remaining_bits_len -= 8;
1157 bit_offset += 8;
1158 }
1159 }
1160 }
1161 if (remaining_bits_len < 0)
1162 {
1163 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1164 }
1165
1166 /* Padding was successfully extracted or it was empty */
1167 pDescr++;
1168 break;
1169 }
1170
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001171 case CSN_VARIABLE_ARRAY:
1172 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1173 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1174 * Array with length specified in parameter:
1175 * <count: bit (x)>
1176 * <list: octet(count + offset)>
1177 */
1178 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1179
1180 count += pDescr->i; /* Adjusted by offset */
1181
1182 if (count > 0)
1183 {
1184 remaining_bits_len -= count * 8;
1185
1186 if (remaining_bits_len < 0)
1187 {
1188 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1189 }
1190
1191 pui8 = pui8DATA(data, pDescr->offset);
1192
1193 while (count > 0)
1194 {
1195 readIndex -= 8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001196 *pui8 = bitvec_read_field(vector, &readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001197 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001198 pui8++;
1199 bit_offset += 8;
1200 count--;
1201 }
1202 }
1203
1204 pDescr++;
1205 break;
1206 }
1207
1208 case CSN_RECURSIVE_ARRAY:
1209 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1210 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1211 * where <element> ::= bit(value)
1212 * <tag> ::= 0 | 1
1213 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1214 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1215 * REMARK: recursive way to specify an array but an iterative implementation!
1216 */
1217 gint16 no_of_bits = pDescr->i;
1218 guint8 ElementCount = 0;
1219
1220 pui8 = pui8DATA(data, pDescr->offset);
1221
Alexander Couzensccde5c92017-02-04 03:10:08 +01001222 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001223 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001224 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001225 bit_offset++;
1226 remaining_bits_len--;
1227
1228 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01001229 *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001230 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001231 pui8++;
1232 remaining_bits_len -= no_of_bits;
1233 ElementCount++;
1234
1235 if (remaining_bits_len < 0)
1236 {
1237 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1238 }
1239
1240 bit_offset += no_of_bits;
1241 }
1242
Alexander Couzensccde5c92017-02-04 03:10:08 +01001243 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001244 /* existNextElement() returned FALSE, 1 bit consumed */
1245 bit_offset++;
1246
1247 /* Store the counted number of elements of the array */
1248 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1249
1250 pDescr++;
1251 break;
1252 }
1253
1254 case CSN_RECURSIVE_TARRAY:
1255 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1256 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1257 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1258 */
1259 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1260 guint8 ElementCount = 0;
1261 pui8 = pui8DATA(data, pDescr->offset);
1262
Alexander Couzensccde5c92017-02-04 03:10:08 +01001263 while (existNextElement(vector, readIndex, Tag))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001264 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001265 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001266 /* existNextElement() returned TRUE, 1 bit consumed */
1267 bit_offset++;
1268 remaining_bits_len--;
1269 ElementCount++;
1270
1271 { /* unpack the following data structure */
1272 csnStream_t arT = *ar;
1273 gint16 Status;
1274 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001275 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001276
1277 if (Status >= 0)
1278 { /* successful completion */
1279 pui8 += nSizeElement; /* -> to next data element */
1280 remaining_bits_len = arT.remaining_bits_len;
1281 bit_offset = arT.bit_offset;
1282 }
1283 else
1284 { /* something went awry */
1285 return Status;
1286 }
1287 }
1288
1289 if (remaining_bits_len < 0)
1290 {
1291 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1292 }
1293 }
1294
Alexander Couzensccde5c92017-02-04 03:10:08 +01001295 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001296
1297 /* existNextElement() returned FALSE, 1 bit consumed */
1298 bit_offset++;
1299
1300 /* Store the counted number of elements of the array */
1301 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1302
1303 pDescr++;
1304 break;
1305 }
1306
1307 case CSN_RECURSIVE_TARRAY_2:
1308 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1309
1310 Tag = REVERSED_TAG;
1311
1312 /* NO break -
1313 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1314 */
1315 }
1316
1317 case CSN_RECURSIVE_TARRAY_1:
1318 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1319 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1320 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1321 */
1322 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1323 guint8 ElementCount = 0;
1324 csnStream_t arT = *ar;
1325 gboolean EndOfList = FALSE;
1326 gint16 Status;
1327 pui8 = pui8DATA(data, pDescr->offset);
1328
1329 do
1330 { /* get data element */
1331 ElementCount++;
1332
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001333 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1334
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001335 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001336 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001337
1338 if (Status >= 0)
1339 { /* successful completion */
1340 pui8 += nSizeElement; /* -> to next */
1341 remaining_bits_len = arT.remaining_bits_len;
1342 bit_offset = arT.bit_offset;
1343 }
1344 else
1345 { /* something went awry */
1346 return Status;
1347 }
1348
1349 if (remaining_bits_len < 0)
1350 {
1351 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1352 }
1353
1354 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001355 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001356 EndOfList = !(existNextElement(vector, readIndex, Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001357
1358 bit_offset++;
1359 remaining_bits_len--; /* 1 bit consumed (tag) */
1360 } while (!EndOfList);
1361
1362
1363 /* Store the count of the array */
1364 *pui8DATA(data, pDescr->i) = ElementCount;
1365 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1366 pDescr++;
1367 break;
1368 }
1369
1370 case CSN_FIXED:
1371 { /* Verify the fixed bits */
1372 guint8 no_of_bits = (guint8) pDescr->i;
1373 guint32 ui32;
1374
1375 if (no_of_bits <= 32)
1376 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001377 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001378 }
1379 else
1380 {
1381 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1382 }
1383 if (ui32 != (unsigned)(gint32)pDescr->offset)
1384 {
1385 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1386 }
1387
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001388 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001389 remaining_bits_len -= no_of_bits;
1390 bit_offset += no_of_bits;
1391 pDescr++;
1392 break;
1393 }
1394
1395 case CSN_CALLBACK:
1396 {
1397 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1398 break;
1399 }
1400
1401 case CSN_TRAP_ERROR:
1402 {
1403 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1404 }
1405
1406 case CSN_END:
1407 {
1408 ar->remaining_bits_len = remaining_bits_len;
1409 ar->bit_offset = bit_offset;
1410 return remaining_bits_len;
1411 }
1412
1413 default:
1414 {
1415 assert(0);
1416 }
1417
1418
1419 }
1420
1421 } while (remaining_bits_len >= 0);
1422
1423 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1424}
1425
1426
1427
1428
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001429gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001430{
1431 gint remaining_bits_len = ar->remaining_bits_len;
1432 gint bit_offset = ar->bit_offset;
1433 guint8* pui8;
1434 guint16* pui16;
1435 guint32* pui32;
1436 guint64* pui64;
1437
1438 guint8 Tag = STANDARD_TAG;
1439
1440 if (remaining_bits_len <= 0)
1441 {
1442 return 0;
1443 }
1444
1445 do
1446 {
1447 switch (pDescr->type)
1448 {
1449 case CSN_BIT:
1450 {
1451 if (remaining_bits_len > 0)
1452 {
1453 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001454 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001455 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001456 /* end add the bit value to protocol tree */
1457 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001458 else if(pDescr->may_be_null)
1459 {
1460 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1461 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001462 else
1463 {
1464 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1465 }
1466
1467 pDescr++;
1468 remaining_bits_len--;
1469 bit_offset++;
1470 break;
1471 }
1472
1473 case CSN_NULL:
1474 { /* Empty member! */
1475 pDescr++;
1476 break;
1477 }
1478
1479 case CSN_UINT:
1480 {
1481 guint8 no_of_bits = (guint8) pDescr->i;
1482
1483 if (remaining_bits_len >= no_of_bits)
1484 {
1485 if (no_of_bits <= 8)
1486 {
1487 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001488 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001489 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001490 }
1491 else if (no_of_bits <= 16)
1492 {
1493 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001494 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001495 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001496 }
1497 else if (no_of_bits <= 32)
1498 {
1499 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001500 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001501 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001502 }
1503 else
1504 {
1505 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1506 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001507
1508 remaining_bits_len -= no_of_bits;
1509 bit_offset += no_of_bits;
1510 }
1511 else if(pDescr->may_be_null)
1512 {
1513 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001514 }
1515 else
1516 {
1517 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1518 }
1519
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001520 pDescr++;
1521 break;
1522 }
1523
1524 case CSN_UINT_OFFSET:
1525 {
1526 guint8 no_of_bits = (guint8) pDescr->i;
1527
1528 if (remaining_bits_len >= no_of_bits)
1529 {
1530 if (no_of_bits <= 8)
1531 {
1532 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001533 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001534 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001535 }
1536 else if (no_of_bits <= 16)
1537 {
1538 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001539 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001540 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001541 }
1542 else if (no_of_bits <= 32)
1543 {
1544 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001545 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001546 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001547 }
1548 else
1549 {
1550 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1551 }
1552 }
1553 else
1554 {
1555 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1556 }
1557
1558 remaining_bits_len -= no_of_bits;
1559 bit_offset += no_of_bits;
1560 pDescr++;
1561 break;
1562 }
1563
1564 case CSN_UINT_LH:
1565 {
1566 guint8 no_of_bits = (guint8) pDescr->i;
1567
1568 if (remaining_bits_len >= no_of_bits)
1569 {
1570 remaining_bits_len -= no_of_bits;
1571 if (no_of_bits <= 8)
1572 {
1573 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001574 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001575 // TODO : Change get_masked_bits8()
1576 writeIndex -= no_of_bits;
1577 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1578 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001579 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001580 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001581
1582 }
1583 else
1584 {/* Maybe we should support more than 8 bits ? */
1585 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1586 }
1587 }
1588 else
1589 {
1590 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1591 }
1592
1593 remaining_bits_len -= no_of_bits;
1594 bit_offset += no_of_bits;
1595 pDescr++;
1596 break;
1597 }
1598
1599 case CSN_UINT_ARRAY:
1600 {
1601 guint8 no_of_bits = (guint8) pDescr->i;
1602 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1603
1604 if (pDescr->serialize.value != 0)
1605 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1606 nCount = *pui16DATA(data, nCount);
1607 }
1608
1609 if (remaining_bits_len >= no_of_bits)
1610 {
1611 remaining_bits_len -= (no_of_bits*nCount);
1612 if (no_of_bits <= 8)
1613 {
1614 pui8 = pui8DATA(data, pDescr->offset);
1615 do
1616 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001617 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001618 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001619 pui8++;
1620 bit_offset += no_of_bits;
1621 } while (--nCount > 0);
1622 }
1623 else if (no_of_bits <= 16)
1624 {
1625 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1626 }
1627 else if (no_of_bits <= 32)
1628 {
1629 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1630 }
1631 else
1632 {
1633 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1634 }
1635 }
1636 else
1637 {
1638 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1639 }
1640 pDescr++;
1641 break;
1642 }
1643
1644 case CSN_VARIABLE_TARRAY_OFFSET:
1645 case CSN_VARIABLE_TARRAY:
1646 case CSN_TYPE_ARRAY:
1647 {
1648 gint16 Status;
1649 csnStream_t arT = *ar;
1650 gint16 nCount = pDescr->i;
1651 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1652
1653 pui8 = pui8DATA(data, pDescr->offset);
1654 if (pDescr->type == CSN_VARIABLE_TARRAY)
1655 { /* Count specified in field */
1656 nCount = *pui8DATA(data, pDescr->i);
1657 }
1658 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1659 { /* Count specified in field */
1660 nCount = *pui8DATA(data, pDescr->i);
1661 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1662 }
1663
1664 while (nCount > 0)
1665 { /* resulting array of length 0 is possible
1666 * but no bits shall be read from bitstream
1667 */
1668
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001669 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001670 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1671 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1672 if (Status >= 0)
1673 {
1674 pui8 += nSize;
1675 remaining_bits_len = arT.remaining_bits_len;
1676 bit_offset = arT.bit_offset;
1677
1678 }
1679 else
1680 {
1681 return Status;
1682 }
1683 nCount--;
1684 }
1685
1686 pDescr++;
1687 break;
1688 }
1689
1690 case CSN_BITMAP:
1691 { /* bitmap with given length. The result is left aligned! */
1692 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1693
1694 if (no_of_bits > 0)
1695 {
1696
1697 if (no_of_bits <= 32)
1698 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001699 for(unsigned ib = 0; ib < 4; ib++)
1700 {
1701 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001702 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001703 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001704 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001705 }
1706 else if (no_of_bits <= 64)
1707 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001708 for(unsigned ib = 0; ib < 8; ib++)
1709 {
1710 pui8 = pui8DATA(data, pDescr->offset+ib);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001711 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001712 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001713 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001714 }
1715 else
1716 {
1717 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1718 }
1719
1720 remaining_bits_len -= no_of_bits;
1721 assert(remaining_bits_len >= 0);
1722 bit_offset += no_of_bits;
1723 }
1724 /* bitmap was successfully extracted or it was empty */
1725
1726 pDescr++;
1727 break;
1728 }
1729
1730 case CSN_TYPE:
1731 {
1732 gint16 Status;
1733 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001734 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001735 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1736 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001737 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001738 if (Status >= 0)
1739 {
1740
1741 remaining_bits_len = arT.remaining_bits_len;
1742 bit_offset = arT.bit_offset;
1743 pDescr++;
1744 }
1745 else
1746 {
1747 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1748 return Status;
1749 }
1750
1751 break;
1752 }
1753
1754 case CSN_CHOICE:
1755 {
1756 //gint16 count = pDescr->i;
1757 guint8 i = 0;
1758 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1759
1760 pui8 = pui8DATA(data, pDescr->offset);
1761 i = *pui8;
1762 pChoice += i;
1763 guint8 no_of_bits = pChoice->bits;
1764 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001765 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001766 bitvec_write_field(vector, &writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001767
1768 CSN_DESCR descr[2];
1769 gint16 Status;
1770 csnStream_t arT = *ar;
1771
1772 descr[0] = pChoice->descr;
1773 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1774 descr[1].type = CSN_END;
1775 bit_offset += no_of_bits;
1776 remaining_bits_len -= no_of_bits;
1777
1778 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1779 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1780
1781 if (Status >= 0)
1782 {
1783 remaining_bits_len = arT.remaining_bits_len;
1784 bit_offset = arT.bit_offset;
1785 }
1786 else
1787 {
1788 return Status;
1789 }
1790
1791 pDescr++;
1792 break;
1793 }
1794
1795 case CSN_SERIALIZE:
1796 {
1797 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1798 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001799 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001800 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001801 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001802
1803 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001804 lengthIndex = writeIndex;
1805 writeIndex += length_len;
1806 bit_offset += length_len;
1807 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001808 arT.direction = 0;
1809 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1810 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001811
Alexander Couzensccde5c92017-02-04 03:10:08 +01001812 bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001813 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001814
1815 if (Status >= 0)
1816 {
1817 remaining_bits_len = arT.remaining_bits_len;
1818 bit_offset = arT.bit_offset;
1819 pDescr++;
1820 }
1821 else
1822 {
1823 // Has already been processed:
1824 return Status;
1825 }
1826
1827 break;
1828 }
1829
1830 case CSN_UNION_LH:
1831 case CSN_UNION:
1832 {
1833 gint16 Bits;
1834 guint8 index;
1835 gint16 count = pDescr->i;
1836 const CSN_DESCR* pDescrNext = pDescr;
1837
1838 pDescrNext += count + 1; /* now this is next after the union */
1839 if ((count <= 0) || (count > 16))
1840 {
1841 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1842 }
1843
1844 /* Now get the bits to extract the index */
1845 Bits = ixBitsTab[count];
1846 index = 0;
1847
1848 /* Assign UnionType */
1849 pui8 = pui8DATA(data, pDescr->offset);
1850 //read index from data and write to vector
Alexander Couzensccde5c92017-02-04 03:10:08 +01001851 bitvec_write_field(vector, &writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001852
1853 //decode index
1854 writeIndex -= Bits;
1855
1856 while (Bits > 0)
1857 {
1858 index <<= 1;
1859
1860 if (CSN_UNION_LH == pDescr->type)
1861 {
1862 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1863 }
1864 else
1865 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01001866 index |= bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001867 }
1868
1869 remaining_bits_len--;
1870 bit_offset++;
1871 Bits--;
1872 }
1873
1874 writeIndex -= Bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001875 bitvec_write_field(vector, &writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001876
1877
1878 /* script index to continue on, limited in case we do not have a power of 2 */
1879 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001880 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001881
1882 switch (pDescr->type)
1883 { /* get the right element of the union based on computed index */
1884
1885 case CSN_BIT:
1886 {
1887 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001888 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001889 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001890 remaining_bits_len -= 1;
1891 bit_offset++;
1892 pDescr++;
1893 break;
1894 }
1895
1896 case CSN_NULL:
1897 { /* Empty member! */
1898 pDescr++;
1899 break;
1900 }
1901
1902 case CSN_UINT:
1903 {
1904 guint8 no_of_bits = (guint8) pDescr->i;
1905 if (remaining_bits_len >= no_of_bits)
1906 {
1907 remaining_bits_len -= no_of_bits;
1908
1909 if (no_of_bits <= 8)
1910 {
1911 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001912 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001913 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001914 }
1915 else if (no_of_bits <= 16)
1916 {
1917 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001918 bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001919 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001920 }
1921 else if (no_of_bits <= 32)
1922 {
1923 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001924 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001925 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001926 }
1927 else
1928 {
1929 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1930 }
1931 }
1932 else
1933 {
1934 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1935 }
1936
1937 bit_offset += no_of_bits;
1938 pDescr++;
1939 break;
1940 }
1941
1942 case CSN_UINT_OFFSET:
1943 {
1944 guint8 no_of_bits = (guint8) pDescr->i;
1945
1946 if (remaining_bits_len >= no_of_bits)
1947 {
1948 if (no_of_bits <= 8)
1949 {
1950 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001951 bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001952 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001953 }
1954 else if (no_of_bits <= 16)
1955 {
1956 pui16 = pui16DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001957 bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001958 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001959 }
1960 else if (no_of_bits <= 32)
1961 {
1962 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001963 bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001964 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001965 }
1966 else
1967 {
1968 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1969 }
1970 }
1971 else
1972 {
1973 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1974 }
1975
1976 remaining_bits_len -= no_of_bits;
1977 bit_offset += no_of_bits;
1978 pDescr++;
1979 break;
1980 }
1981
1982 case CSN_UINT_LH:
1983 {
1984 guint8 no_of_bits = (guint8) pDescr->i;
1985
1986 if (remaining_bits_len >= no_of_bits)
1987 {
1988 remaining_bits_len -= no_of_bits;
1989 if (no_of_bits <= 8)
1990 {
1991 pui8 = pui8DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01001992 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001993 // TODO : Change get_masked_bits8()
1994 writeIndex -= no_of_bits;
1995 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1996 writeIndex -= no_of_bits;
Alexander Couzensccde5c92017-02-04 03:10:08 +01001997 bitvec_write_field(vector, &writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001998 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001999
2000 }
2001 else
2002 {/* Maybe we should support more than 8 bits ? */
2003 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2004 }
2005 }
2006 else
2007 {
2008 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2009 }
2010
2011 remaining_bits_len -= no_of_bits;
2012 bit_offset += no_of_bits;
2013 pDescr++;
2014 break;
2015 }
2016
2017 case CSN_UINT_ARRAY:
2018 {
2019 guint8 no_of_bits = (guint8) pDescr->i;
2020 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2021
2022 if (pDescr->serialize.value != 0)
2023 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2024 nCount = *pui16DATA(data, nCount);
2025 }
2026
2027 if (remaining_bits_len >= no_of_bits)
2028 {
2029 remaining_bits_len -= (no_of_bits*nCount);
2030 if (no_of_bits <= 8)
2031 {
2032 pui8 = pui8DATA(data, pDescr->offset);
2033 do
2034 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002035 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002036 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002037 pui8++;
2038 bit_offset += no_of_bits;
2039 } while (--nCount > 0);
2040 }
2041 else if (no_of_bits <= 16)
2042 {
2043 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2044 }
2045 else if (no_of_bits <= 32)
2046 {
2047 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2048 }
2049 else
2050 {
2051 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2052 }
2053 }
2054 else
2055 {
2056 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2057 }
2058 pDescr++;
2059 break;
2060 }
2061
2062 case CSN_VARIABLE_TARRAY_OFFSET:
2063 case CSN_VARIABLE_TARRAY:
2064 case CSN_TYPE_ARRAY:
2065 {
2066 gint16 Status;
2067 csnStream_t arT = *ar;
2068 gint16 nCount = pDescr->i;
2069 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2070
2071 pui8 = pui8DATA(data, pDescr->offset);
2072 if (pDescr->type == CSN_VARIABLE_TARRAY)
2073 { /* Count specified in field */
2074 nCount = *pui8DATA(data, pDescr->i);
2075 }
2076 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2077 { /* Count specified in field */
2078 nCount = *pui8DATA(data, pDescr->i);
2079 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2080 }
2081
2082 while (nCount > 0)
2083 { /* resulting array of length 0 is possible
2084 * but no bits shall be read from bitstream
2085 */
2086
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002087 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002088 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2089 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2090 if (Status >= 0)
2091 {
2092 pui8 += nSize;
2093 remaining_bits_len = arT.remaining_bits_len;
2094 bit_offset = arT.bit_offset;
2095 }
2096 else
2097 {
2098 return Status;
2099 }
2100 nCount--;
2101 }
2102
2103 pDescr++;
2104 break;
2105 }
2106
2107 case CSN_BITMAP:
2108 { /* bitmap with given length. The result is left aligned! */
2109 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2110
2111 if (no_of_bits > 0)
2112 {
2113
2114 if (no_of_bits <= 32)
2115 {
2116 pui32 = pui32DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002117 bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002118 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002119 }
2120 else if (no_of_bits <= 64)
2121 {
2122 pui64 = pui64DATA(data, pDescr->offset);
Alexander Couzensccde5c92017-02-04 03:10:08 +01002123 bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002124 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002125 }
2126 else
2127 {
2128 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2129 }
2130
2131 remaining_bits_len -= no_of_bits;
2132 assert(remaining_bits_len >= 0);
2133 bit_offset += no_of_bits;
2134 }
2135 /* bitmap was successfully extracted or it was empty */
2136
2137 pDescr++;
2138 break;
2139 }
2140
2141 case CSN_TYPE:
2142 {
2143 gint16 Status;
2144 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002145 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002146 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2147 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002148 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002149 if (Status >= 0)
2150 {
2151 remaining_bits_len = arT.remaining_bits_len;
2152 bit_offset = arT.bit_offset;
2153 pDescr++;
2154 }
2155 else
2156 {
2157 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2158 return Status;
2159 }
2160
2161 break;
2162 }
2163
2164 default:
2165 { /* descriptions of union elements other than above are illegal */
2166 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2167 }
2168 }
2169
2170 pDescr = pDescrNext;
2171 break;
2172 }
2173
2174 case CSN_EXIST:
2175 case CSN_EXIST_LH:
2176 {
2177 guint8 fExist;
2178 unsigned exist = 0;
2179 pui8 = pui8DATA(data, pDescr->offset);
2180 exist = *pui8;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002181 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002182 writeIndex--;
2183 if (CSN_EXIST_LH == pDescr->type)
2184 {
2185 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2186 }
2187 else
2188 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002189 fExist = bitvec_read_field(vector, &writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002190 }
2191 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002192 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002193 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002194 pDescr++;
2195 remaining_bits_len -= 1;
2196
2197 if (!exist)
2198 {
2199 ar->remaining_bits_len = remaining_bits_len;
2200 ar->bit_offset = bit_offset;
2201 return remaining_bits_len;
2202 }
2203 break;
2204 }
2205
2206 case CSN_NEXT_EXIST:
2207 {
2208 guint8 fExist;
2209
2210 pui8 = pui8DATA(data, pDescr->offset);
2211
2212 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002213 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002214 { /* no more bits to decode is fine here - end of message detected and allowed */
2215
2216 /* Skip i entries + this entry */
2217 pDescr += pDescr->i + 1;
2218
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002219 break;
2220 }
2221
Alexander Couzensccde5c92017-02-04 03:10:08 +01002222 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002223 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002224 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002225 remaining_bits_len -= 1;
2226
2227 ++bit_offset;
2228
2229 if (fExist == 0)
2230 { /* Skip 'i' entries */
2231 pDescr += pDescr->i;
2232 }
2233
2234 pDescr++;
2235 break;
2236 }
2237
2238 case CSN_NEXT_EXIST_LH:
2239 {
2240 guint8 fExist;
2241 pui8 = pui8DATA(data, pDescr->offset);
2242
2243 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2244 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2245 { /* no more bits to decode is fine here - end of message detected and allowed */
2246
2247 /* skip 'i' entries + this entry */
2248 pDescr += pDescr->i + 1;
2249
2250 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2251 if ( pDescr->type != CSN_END )
2252 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2253 remaining_bits_len--;
2254 }
2255
2256 /* set the data member to "not exist" */
2257 //*pui8 = 0;
2258 break;
2259 }
2260
2261 /* the "regular" M_NEXT_EXIST_LH description element */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002262 bitvec_write_field(vector, &writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002263 writeIndex--;
2264 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2265 writeIndex--;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002266 bitvec_write_field(vector, &writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002267 pui8++;
2268 remaining_bits_len -= 1;
2269
2270 bit_offset++;
2271
2272 if (fExist == 0)
2273 { /* Skip 'i' entries */
2274 pDescr += pDescr->i;
2275 }
2276 pDescr++;
2277
2278 break;
2279 }
2280
2281 case CSN_VARIABLE_BITMAP_1:
2282 { /* Bitmap from here and to the end of message */
2283
2284 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2285
2286 /*no break -
2287 * with a length set we have a regular variable length bitmap so we continue */
2288 }
2289
2290 case CSN_VARIABLE_BITMAP:
2291 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2292 * <N: bit (5)> <bitmap: bit(N + offset)>
2293 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2294 * The result is right aligned!
2295 */
2296 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2297
2298 no_of_bits += pDescr->i; /* adjusted by offset */
2299
2300 if (no_of_bits > 0)
2301 {
2302 remaining_bits_len -= no_of_bits;
2303
2304 if (remaining_bits_len < 0)
2305 {
2306 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2307 }
2308
2309 { /* extract bits */
2310 guint8* pui8 = pui8DATA(data, pDescr->offset);
2311 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2312
2313 if (nB1 > 0)
2314 { /* take care of the first byte - it will be right aligned */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002315 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002316 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002317 pui8++;
2318 no_of_bits -= nB1;
2319 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2320 }
2321
2322 /* remaining no_of_bits is a multiple of 8 or 0 */
2323 while (no_of_bits > 0)
2324 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002325 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002326 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002327 pui8++;
2328 no_of_bits -= 8;
2329 }
2330 }
2331 }
2332 pDescr++;
2333 break;
2334 }
2335
2336 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2337 { /* Bitmap from here and to the end of message */
2338
2339 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2340
2341 /* no break -
2342 * with a length set we have a regular left aligned variable length bitmap so we continue
2343 */
2344 }
2345
2346 case CSN_LEFT_ALIGNED_VAR_BMP:
2347 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2348 * <N: bit (5)> <bitmap: bit(N + offset)>
2349 * bit array with length (in bits) specified in parameter (pDescr->descr)
2350 */
2351
2352 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2353
2354 no_of_bits += pDescr->i;/* size adjusted by offset */
2355
2356 if (no_of_bits > 0)
2357 {
2358 remaining_bits_len -= no_of_bits;
2359
2360 if (remaining_bits_len < 0)
2361 {
2362 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2363 }
2364
2365 { /* extract bits */
2366 guint8* pui8 = pui8DATA(data, pDescr->offset);
2367 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2368
2369 while (no_of_bits > 0)
2370 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002371 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002372 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002373 pui8++;
2374 no_of_bits -= 8;
2375 }
2376 if (nB1 > 0)
2377 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002378 bitvec_write_field(vector, &writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002379 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002380 pui8++;
2381 no_of_bits -= nB1;
2382 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2383 }
2384 }
2385
2386 }
2387
2388 /* bitmap was successfully extracted or it was empty */
2389 pDescr++;
2390 break;
2391 }
2392
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002393 case CSN_PADDING_BITS:
2394 { /* Padding from here and to the end of message */
2395 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2396 guint8 filler = 0x2b;
2397 if (remaining_bits_len > 0)
2398 {
2399 while (remaining_bits_len > 0)
2400 {
2401 guint8 bits_to_handle = remaining_bits_len%8;
2402 if (bits_to_handle > 0)
2403 {
Saurabh Sharan656eed52016-03-10 14:15:29 +05302404 /* section 11 of 44.060
2405 * The padding bits may be the 'null' string. Otherwise, the
2406 * padding bits starts with bit '0', followed by 'spare padding'
2407 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
2408 */
2409 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
Alexander Couzensccde5c92017-02-04 03:10:08 +01002410 bitvec_write_field(vector, &writeIndex, fl, bits_to_handle);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002411 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2412 remaining_bits_len -= bits_to_handle;
2413 bit_offset += bits_to_handle;
2414 }
2415 else if (bits_to_handle == 0)
2416 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002417 bitvec_write_field(vector, &writeIndex, filler, 8);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002418 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2419 remaining_bits_len -= 8;
2420 bit_offset += 8;
2421 }
2422 }
2423 }
2424 if (remaining_bits_len < 0)
2425 {
2426 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2427 }
2428
2429 /* Padding was successfully extracted or it was empty */
2430 pDescr++;
2431 break;
2432 }
2433
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002434 case CSN_VARIABLE_ARRAY:
2435 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2436 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2437 * Array with length specified in parameter:
2438 * <count: bit (x)>
2439 * <list: octet(count + offset)>
2440 */
2441 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2442
2443 count += pDescr->i; /* Adjusted by offset */
2444
2445 if (count > 0)
2446 {
2447 remaining_bits_len -= count * 8;
2448
2449 if (remaining_bits_len < 0)
2450 {
2451 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2452 }
2453
2454 pui8 = pui8DATA(data, pDescr->offset);
2455
2456 while (count > 0)
2457 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002458 bitvec_write_field(vector, &writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002459 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002460 pui8++;
2461 bit_offset += 8;
2462 count--;
2463 }
2464 }
2465
2466 pDescr++;
2467 break;
2468 }
2469
2470 case CSN_RECURSIVE_ARRAY:
2471 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2472 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2473 * where <element> ::= bit(value)
2474 * <tag> ::= 0 | 1
2475 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2476 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2477 * REMARK: recursive way to specify an array but an iterative implementation!
2478 */
2479 gint16 no_of_bits = pDescr->i;
2480 guint8 ElementCount = 0;
2481 pui8 = pui8DATA(data, pDescr->offset);
2482 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2483 while (ElementCount > 0)
2484 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002485 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002486 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002487 bit_offset++;
2488 remaining_bits_len--;
2489
2490 /* extract and store no_of_bits long element from bitstream */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002491 bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002492 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002493 pui8++;
2494 remaining_bits_len -= no_of_bits;
2495 ElementCount--;
2496
2497 if (remaining_bits_len < 0)
2498 {
2499 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2500 }
2501
2502 bit_offset += no_of_bits;
2503 }
2504
Alexander Couzensccde5c92017-02-04 03:10:08 +01002505 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002506 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002507 bit_offset++;
Saurabh Sharan2b09c392016-03-16 19:17:32 +05302508 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002509
2510 pDescr++;
2511 break;
2512 }
2513
2514 case CSN_RECURSIVE_TARRAY:
2515 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2516 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2517 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2518 */
2519 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2520 guint8 ElementCount = 0;
2521 pui8 = pui8DATA(data, pDescr->offset);
2522 /* Store the counted number of elements of the array */
2523 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2524
2525 while (ElementCount > 0)
2526 { /* tag control shows existence of next list elements */
Alexander Couzensccde5c92017-02-04 03:10:08 +01002527 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002528 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002529 bit_offset++;
2530
2531 remaining_bits_len--;
2532 ElementCount--;
2533
2534 { /* unpack the following data structure */
2535 csnStream_t arT = *ar;
2536 gint16 Status;
2537 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002538 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002539
2540 if (Status >= 0)
2541 { /* successful completion */
2542 pui8 += nSizeElement; /* -> to next data element */
2543 remaining_bits_len = arT.remaining_bits_len;
2544 bit_offset = arT.bit_offset;
2545 }
2546 else
2547 { /* something went awry */
2548 return Status;
2549 }
2550 }
2551
2552 if (remaining_bits_len < 0)
2553 {
2554 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2555 }
2556 }
2557
Alexander Couzensccde5c92017-02-04 03:10:08 +01002558 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002559 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002560 bit_offset++;
2561
2562 pDescr++;
2563 break;
2564 }
2565
2566 case CSN_RECURSIVE_TARRAY_2:
2567 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2568
2569 Tag = REVERSED_TAG;
2570
2571 /* NO break -
2572 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2573 */
2574 }
2575
2576 case CSN_RECURSIVE_TARRAY_1:
2577 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2578 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2579 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2580 */
2581 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2582 guint8 ElementCount = 0;
2583 guint8 ElementNum = 0;
2584 csnStream_t arT = *ar;
2585 gint16 Status;
2586
2587 pui8 = pui8DATA(data, pDescr->offset);
2588 /* Store the count of the array */
2589 ElementCount = *pui8DATA(data, pDescr->i);
2590 ElementNum = ElementCount;
2591
2592 while (ElementCount > 0)
2593 { /* get data element */
2594 if (ElementCount != ElementNum)
2595 {
Alexander Couzensccde5c92017-02-04 03:10:08 +01002596 bitvec_write_field(vector, &writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002597 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002598 bit_offset++;
2599 remaining_bits_len--;
2600 }
2601 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002602 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002603 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002604 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002605 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002606 if (Status >= 0)
2607 { /* successful completion */
2608 pui8 += nSizeElement; /* -> to next */
2609 remaining_bits_len = arT.remaining_bits_len;
2610 bit_offset = arT.bit_offset;
2611 }
2612 else
2613 { /* something went awry */
2614 return Status;
2615 }
2616
2617 if (remaining_bits_len < 0)
2618 {
2619 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2620 }
2621
2622 }
Alexander Couzensccde5c92017-02-04 03:10:08 +01002623 bitvec_write_field(vector, &writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002624 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002625 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002626 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2627 pDescr++;
2628 break;
2629 }
2630
2631 case CSN_FIXED:
2632 { /* Verify the fixed bits */
2633 guint8 no_of_bits = (guint8) pDescr->i;
Alexander Couzensccde5c92017-02-04 03:10:08 +01002634 bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002635 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002636 remaining_bits_len -= no_of_bits;
2637 bit_offset += no_of_bits;
2638 pDescr++;
2639 break;
2640 }
2641
2642 case CSN_CALLBACK:
2643 {
2644 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2645 break;
2646 }
2647
2648 case CSN_TRAP_ERROR:
2649 {
2650 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2651 }
2652
2653 case CSN_END:
2654 {
2655 ar->remaining_bits_len = remaining_bits_len;
2656 ar->bit_offset = bit_offset;
2657 return remaining_bits_len;
2658 }
2659
2660 default:
2661 {
2662 assert(0);
2663 }
2664
2665 }
2666
2667 } while (remaining_bits_len >= 0);
2668
2669 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2670}
2671