blob: 54cc411cb947e8cfcc671efcbfa9d7297ea93eb6 [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 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040067 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 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040073 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));
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040075 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{
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400136 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);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400170 *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! */
193 pDescr++;
194 break;
195 }
196
197 case CSN_UINT:
198 {
199 guint8 no_of_bits = (guint8) pDescr->i;
200
201 if (remaining_bits_len >= no_of_bits)
202 {
203 if (no_of_bits <= 8)
204 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400205 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300206 pui8 = pui8DATA(data, pDescr->offset);
207 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400208 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300209 }
210 else if (no_of_bits <= 16)
211 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400212 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300213 pui16 = pui16DATA(data, pDescr->offset);
214 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400215 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300216 }
217 else if (no_of_bits <= 32)
218 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400219 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300220 pui32 = pui32DATA(data, pDescr->offset);
221 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400222 LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300223 }
224 else
225 {
226 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
227 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400228 remaining_bits_len -= no_of_bits;
229 bit_offset += no_of_bits;
230 }
231 else if(pDescr->may_be_null)
232 {
233 if (no_of_bits <= 8)
234 {
235 pui8 = pui8DATA(data, pDescr->offset);
236 *pui8 = 0;
237 }
238 else if (no_of_bits <= 16)
239 {
240 pui16 = pui16DATA(data, pDescr->offset);
241 *pui16 = 0;
242 }
243 else if (no_of_bits <= 32)
244 {
245 pui32 = pui32DATA(data, pDescr->offset);
246 *pui32 = 0;
247 }
248 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300249 }
250 else
251 {
252 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
253 }
254
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300255 pDescr++;
256 break;
257 }
258
259 case CSN_UINT_OFFSET:
260 {
261 guint8 no_of_bits = (guint8) pDescr->i;
262
263 if (remaining_bits_len >= no_of_bits)
264 {
265 if (no_of_bits <= 8)
266 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400267 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300268 pui8 = pui8DATA(data, pDescr->offset);
269 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400270 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300271 }
272 else if (no_of_bits <= 16)
273 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400274 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300275 pui16 = pui16DATA(data, pDescr->offset);
276 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400277 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300278 }
279 else if (no_of_bits <= 32)
280 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400281 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300282 pui32 = pui32DATA(data, pDescr->offset);
283 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400284 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300285 }
286 else
287 {
288 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
289 }
290 }
291 else
292 {
293 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
294 }
295
296 remaining_bits_len -= no_of_bits;
297 bit_offset += no_of_bits;
298 pDescr++;
299 break;
300 }
301
302 case CSN_UINT_LH:
303 {
304 guint8 no_of_bits = (guint8) pDescr->i;
305
306 if (remaining_bits_len >= no_of_bits)
307 {
308 remaining_bits_len -= no_of_bits;
309 if (no_of_bits <= 8)
310 {
311 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
312 pui8 = pui8DATA(data, pDescr->offset);
313 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400314 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300315 }
316 else
317 {/* Maybe we should support more than 8 bits ? */
318 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
319 }
320 }
321 else
322 {
323 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
324 }
325
326 remaining_bits_len -= no_of_bits;
327 bit_offset += no_of_bits;
328 pDescr++;
329 break;
330 }
331
332 case CSN_UINT_ARRAY:
333 {
334 guint8 no_of_bits = (guint8) pDescr->i;
335 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
336
337 if (pDescr->serialize.value != 0)
338 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
339 nCount = *pui16DATA(data, nCount);
340 }
341
342 if (remaining_bits_len >= no_of_bits)
343 {
344 remaining_bits_len -= (no_of_bits*nCount);
345 if (no_of_bits <= 8)
346 {
347 pui8 = pui8DATA(data, pDescr->offset);
348 do
349 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400350 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400351 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300352 pui8++;
353 bit_offset += no_of_bits;
354 } while (--nCount > 0);
355 }
356 else if (no_of_bits <= 16)
357 {
358 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
359 }
360 else if (no_of_bits <= 32)
361 {
362 return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
363 }
364 else
365 {
366 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
367 }
368 }
369 else
370 {
371 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
372 }
373 pDescr++;
374 break;
375 }
376
377 case CSN_VARIABLE_TARRAY_OFFSET:
378 case CSN_VARIABLE_TARRAY:
379 case CSN_TYPE_ARRAY:
380 {
381 gint16 Status;
382 csnStream_t arT = *ar;
383 gint16 nCount = pDescr->i;
384 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
385
386 pui8 = pui8DATA(data, pDescr->offset);
387 if (pDescr->type == CSN_VARIABLE_TARRAY)
388 { /* Count specified in field */
389 nCount = *pui8DATA(data, pDescr->i);
390 }
391 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
392 { /* Count specified in field */
393 nCount = *pui8DATA(data, pDescr->i);
394 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
395 }
396
397 while (nCount > 0)
398 { /* resulting array of length 0 is possible
399 * but no bits shall be read from bitstream
400 */
401
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400402 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300403 csnStreamInit(&arT, bit_offset, remaining_bits_len);
404 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
405 if (Status >= 0)
406 {
407 pui8 += nSize;
408 remaining_bits_len = arT.remaining_bits_len;
409 bit_offset = arT.bit_offset;
410 }
411 else
412 {
413 return Status;
414 }
415 nCount--;
416 }
417
418 pDescr++;
419 break;
420 }
421
422 case CSN_BITMAP:
423 { /* bitmap with given length. The result is left aligned! */
424 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
425
426 if (no_of_bits > 0)
427 {
428
429 if (no_of_bits <= 32)
430 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400431 for(unsigned ib = 0; ib < 4; ib++)
432 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400433 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400434 pui8 = pui8DATA(data, pDescr->offset+ib);
435 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400436 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400437 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300438 }
439 else if (no_of_bits <= 64)
440 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400441 for(unsigned ib = 0; ib < 8; ib++)
442 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400443 guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400444 pui8 = pui8DATA(data, pDescr->offset+ib);
445 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400446 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +0400447 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300448 }
449 else
450 {
451 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
452 }
453
454 remaining_bits_len -= no_of_bits;
455 assert(remaining_bits_len >= 0);
456 bit_offset += no_of_bits;
457 }
458 /* bitmap was successfully extracted or it was empty */
459
460 pDescr++;
461 break;
462 }
463
464 case CSN_TYPE:
465 {
466 gint16 Status;
467 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400468 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300469 csnStreamInit(&arT, bit_offset, remaining_bits_len);
470 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400471 LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300472 if (Status >= 0)
473 {
474 remaining_bits_len = arT.remaining_bits_len;
475 bit_offset = arT.bit_offset;
476 pDescr++;
477 }
478 else
479 {
480 /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr); */
481 return Status;
482 }
483
484 break;
485 }
486
487 case CSN_CHOICE:
488 {
489 gint16 count = pDescr->i;
490 guint8 i = 0;
491 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
492
493 while (count > 0)
494 {
495 guint8 no_of_bits = pChoice->bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400496 guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300497 if (value == pChoice->value)
498 {
499 CSN_DESCR descr[2];
500 gint16 Status;
501 csnStream_t arT = *ar;
502
503 descr[0] = pChoice->descr;
504 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
505 descr[1].type = CSN_END;
506 pui8 = pui8DATA(data, pDescr->offset);
507 *pui8 = i;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400508 LOGPC(DCSN1, LOGL_NOTICE, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300509 bit_offset += no_of_bits;
510 remaining_bits_len -= no_of_bits;
511
512 csnStreamInit(&arT, bit_offset, remaining_bits_len);
513 Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
514
515 if (Status >= 0)
516 {
517 remaining_bits_len = arT.remaining_bits_len;
518 bit_offset = arT.bit_offset;
519 }
520 else
521 {
522 return Status;
523 }
524 break;
525 }
526
527 readIndex -= no_of_bits;
528 count--;
529 pChoice++;
530 i++;
531 }
532
533 pDescr++;
534 break;
535 }
536
537 case CSN_SERIALIZE:
538 {
539 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
540 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400541 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300542 gint16 Status = -1;
543
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400544 guint8 length = bitvec_read_field(vector, readIndex, length_len);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300545
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400546 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length);
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400547 bit_offset += length_len;
548 remaining_bits_len -= length_len;
549
550 csnStreamInit(&arT, bit_offset, length);
Daniel Willmann6f0796a2014-01-15 09:57:07 +0100551 arT.direction = 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100552 LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300553 Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
554
555 if (Status >= 0)
556 {
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400557 remaining_bits_len -= length;
558 bit_offset += length;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300559 pDescr++;
560 }
561 else
562 {
563 /* Has already been processed: */
564 return Status;
565 }
566
567 break;
568 }
569
570 case CSN_UNION_LH:
571 case CSN_UNION:
572 {
573 gint16 Bits;
574 guint8 index;
575 gint16 count = pDescr->i;
576 const CSN_DESCR* pDescrNext = pDescr;
577
578 pDescrNext += count + 1; /* now this is next after the union */
579 if ((count <= 0) || (count > 16))
580 {
581 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
582 }
583
584 /* Now get the bits to extract the index */
585 Bits = ixBitsTab[count];
586 index = 0;
587
588 while (Bits > 0)
589 {
590 index <<= 1;
591
592 if (CSN_UNION_LH == pDescr->type)
593 {
594 index |= get_masked_bits8(vector,readIndex, bit_offset, 1);
595 }
596 else
597 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400598 index |= bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300599 }
600 remaining_bits_len--;
601 bit_offset++;
602 Bits--;
603 }
604
605 /* Assign UnionType */
606 pui8 = pui8DATA(data, pDescr->offset);
607 *pui8 = index;
608
609
610 /* script index to continue on, limited in case we do not have a power of 2 */
611 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400612 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300613
614 switch (pDescr->type)
615 { /* get the right element of the union based on computed index */
616
617 case CSN_BIT:
618 {
619 pui8 = pui8DATA(data, pDescr->offset);
620 *pui8 = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400621 if (bitvec_read_field(vector, readIndex, 1) > 0)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300622 {
623 *pui8 = 0x01;
624 }
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400625 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300626 remaining_bits_len -= 1;
627 bit_offset++;
628 pDescr++;
629 break;
630 }
631
632 case CSN_NULL:
633 { /* Empty member! */
634 pDescr++;
635 break;
636 }
637
638 case CSN_UINT:
639 {
640 guint8 no_of_bits = (guint8) pDescr->i;
641 if (remaining_bits_len >= no_of_bits)
642 {
643 remaining_bits_len -= no_of_bits;
644
645 if (no_of_bits <= 8)
646 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400647 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300648 pui8 = pui8DATA(data, pDescr->offset);
649 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400650 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300651 }
652 else if (no_of_bits <= 16)
653 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400654 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300655 pui16 = pui16DATA(data, pDescr->offset);
656 *pui16 = ui16;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400657 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300658 }
659 else if (no_of_bits <= 32)
660 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400661 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300662 pui32 = pui32DATA(data, pDescr->offset);
663 *pui32 = ui32;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400664 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300665 }
666 else
667 {
668 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
669 }
670 }
671 else
672 {
673 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
674 }
675
676 bit_offset += no_of_bits;
677 pDescr++;
678 break;
679 }
680
681 case CSN_UINT_OFFSET:
682 {
683 guint8 no_of_bits = (guint8) pDescr->i;
684
685 if (remaining_bits_len >= no_of_bits)
686 {
687 if (no_of_bits <= 8)
688 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400689 guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300690 pui8 = pui8DATA(data, pDescr->offset);
691 *pui8 = ui8 + (guint8)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400692 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300693 }
694 else if (no_of_bits <= 16)
695 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400696 guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300697 pui16 = pui16DATA(data, pDescr->offset);
698 *pui16 = ui16 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400699 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300700 }
701 else if (no_of_bits <= 32)
702 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400703 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300704 pui32 = pui32DATA(data, pDescr->offset);
705 *pui32 = ui32 + (guint16)pDescr->descr.value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400706 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300707 }
708 else
709 {
710 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
711 }
712 }
713 else
714 {
715 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
716 }
717
718 bit_offset += no_of_bits;
719 pDescr++;
720 break;
721 }
722
723 case CSN_UINT_LH:
724 {
725 guint8 no_of_bits = (guint8) pDescr->i;
726
727 if (remaining_bits_len >= no_of_bits)
728 {
729 if (no_of_bits <= 8)
730 {
731 guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
732 pui8 = pui8DATA(data, pDescr->offset);
733 *pui8 = ui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400734 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300735 }
736 else
737 { /* Maybe we should support more than 8 bits ? */
738 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
739 }
740 }
741 else
742 {
743 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
744 }
745
746 bit_offset += no_of_bits;
747 pDescr++;
748 break;
749 }
750
751 case CSN_UINT_ARRAY:
752 {
753 guint8 no_of_bits = (guint8) pDescr->i;
754 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
755
756 if (pDescr->serialize.value != 0)
757 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
758 nCount = *pui16DATA(data, nCount);
759 }
760
761 if (remaining_bits_len >= no_of_bits)
762 {
763 remaining_bits_len -= (no_of_bits * nCount);
764 if (no_of_bits <= 8)
765 {
766 pui8 = pui8DATA(data, pDescr->offset);
767
768 while (nCount > 0)
769 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400770 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400771 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300772 pui8++;
773 bit_offset += no_of_bits;
774 nCount--;
775 }
776 }
777 else if (no_of_bits <= 16)
778 {
779 pui16 = pui16DATA(data, pDescr->offset);
780
781 while (nCount > 0)
782 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400783 *pui16 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400784 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300785 pui16++;
786 bit_offset += no_of_bits;
787 nCount--;
788 }
789 }
790 else if (no_of_bits <= 32)
791 { /* not supported */
792 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
793 }
794 else
795 {
796 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
797 }
798 }
799 else
800 {
801 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
802 }
803
804 pDescr++;
805 break;
806 }
807
808 case CSN_VARIABLE_TARRAY_OFFSET:
809 case CSN_VARIABLE_TARRAY:
810 case CSN_TYPE_ARRAY:
811 {
812 gint16 Status;
813 csnStream_t arT = *ar;
814 guint16 nCount = (guint16) pDescr->i;
815 guint16 nSize = (guint16)(guint32)pDescr->serialize.value;
816
817 pui8 = pui8DATA(data, pDescr->offset);
818
819 if (CSN_VARIABLE_TARRAY == pDescr->type)
820 { /* Count specified in field */
821 nCount = *pui8DATA(data, pDescr->i);
822 }
823 else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
824 { /* Count specified in field */
825 nCount = *pui8DATA(data, pDescr->i);
826 nCount--; /* Offset 1 */
827 }
828
829 while (nCount--) /* Changed to handle length = 0. */
830 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400831 LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300832 csnStreamInit(&arT, bit_offset, remaining_bits_len);
833 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
834 if (Status >= 0)
835 {
836 pui8 += nSize;
837 remaining_bits_len = arT.remaining_bits_len;
838 bit_offset = arT.bit_offset;
839 }
840 else
841 {
842 return Status;
843 }
844 }
845
846 pDescr++;
847 break;
848 }
849
850 case CSN_BITMAP:
851 { /* bitmap with given length. The result is left aligned! */
852 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
853
854 if (no_of_bits > 0)
855 {
856
857 if (no_of_bits <= 32)
858 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400859 guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300860 pui32 = pui32DATA(data, pDescr->offset);
861 *pui32 = ui32;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300862 }
863 else if (no_of_bits <= 64)
864 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400865 guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300866 pui64 = pui64DATA(data, pDescr->offset);
867 *pui64 = ui64;
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +0200868 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300869 }
870 else
871 {
872 return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
873 }
874
875 remaining_bits_len -= no_of_bits;
876 assert(remaining_bits_len >= 0);
877 bit_offset += no_of_bits;
878 }
879 /* bitmap was successfully extracted or it was empty */
880
881 pDescr++;
882 break;
883 }
884
885 case CSN_TYPE:
886 {
887 gint16 Status;
888 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400889 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300890 csnStreamInit(&arT, bit_offset, remaining_bits_len);
891 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400892 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300893 if (Status >= 0)
894 {
895 remaining_bits_len = arT.remaining_bits_len;
896 bit_offset = arT.bit_offset;
897 pDescr++;
898 }
899 else
900 { /* return error code Has already been processed: */
901 return Status;
902 }
903
904 break;
905 }
906
907 default:
908 { /* descriptions of union elements other than above are illegal */
909 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
910 }
911 }
912
913 pDescr = pDescrNext;
914 break;
915 }
916
917 case CSN_EXIST:
918 case CSN_EXIST_LH:
919 {
920 guint8 fExist;
921
922 pui8 = pui8DATA(data, pDescr->offset);
923
924 if (CSN_EXIST_LH == pDescr->type)
925 {
926 fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
927 }
928 else
929 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400930 fExist = bitvec_read_field(vector, readIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300931 }
932
933 *pui8 = fExist;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400934 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300935 pDescr++;
936 remaining_bits_len -= 1;
937
938 if (!fExist)
939 {
940 ar->remaining_bits_len = remaining_bits_len;
941 ar->bit_offset = bit_offset;
942 return remaining_bits_len;
943 }
944
945 break;
946 }
947
948 case CSN_NEXT_EXIST:
949 {
950 guint8 fExist;
951
952 pui8 = pui8DATA(data, pDescr->offset);
953
954 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +0400955 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300956 { /* no more bits to decode is fine here - end of message detected and allowed */
957
958 /* Skip i entries + this entry */
959 pDescr += pDescr->i + 1;
960
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300961 /* Set the data member to "not exist" */
962 *pui8 = 0;
963 break;
964 }
965
966 /* the "regular" M_NEXT_EXIST description element */
967
968 fExist = 0x00;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +0400969 if (bitvec_read_field(vector, readIndex, 1))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300970 {
971 fExist = 0x01;
972 }
973
974 *pui8 = fExist;
975 remaining_bits_len -= 1;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +0400976 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300977 ++bit_offset;
978
979 if (fExist == 0)
980 { /* Skip 'i' entries */
981 pDescr += pDescr->i;
982 }
983
984 pDescr++;
985 break;
986 }
987
988 case CSN_NEXT_EXIST_LH:
989 {
990 guint8 fExist;
991 pui8 = pui8DATA(data, pDescr->offset);
992
993 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
994 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
995 { /* no more bits to decode is fine here - end of message detected and allowed */
996
997 /* skip 'i' entries + this entry */
998 pDescr += pDescr->i + 1;
999
1000 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
1001 if ( pDescr->type != CSN_END )
1002 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
1003 remaining_bits_len--;
1004 }
1005
1006 /* set the data member to "not exist" */
1007 *pui8 = 0;
1008 break;
1009 }
1010
1011 /* the "regular" M_NEXT_EXIST_LH description element */
1012 fExist = get_masked_bits8(vector,readIndex,bit_offset, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001013 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001014 *pui8++ = fExist;
1015 remaining_bits_len -= 1;
1016
1017 bit_offset++;
1018
1019 if (fExist == 0)
1020 { /* Skip 'i' entries */
1021 pDescr += pDescr->i;
1022 }
1023 pDescr++;
1024
1025 break;
1026 }
1027
1028 case CSN_VARIABLE_BITMAP_1:
1029 { /* Bitmap from here and to the end of message */
1030
1031 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1032
1033 /*no break -
1034 * with a length set we have a regular variable length bitmap so we continue */
1035 }
1036
1037 case CSN_VARIABLE_BITMAP:
1038 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1039 * <N: bit (5)> <bitmap: bit(N + offset)>
1040 * Bit array with length (in bits) specified in parameter (pDescr->descr)
1041 * The result is right aligned!
1042 */
1043 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
1044
1045 no_of_bits += pDescr->i; /* adjusted by offset */
1046
1047 if (no_of_bits > 0)
1048 {
1049 remaining_bits_len -= no_of_bits;
1050
1051 if (remaining_bits_len < 0)
1052 {
1053 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1054 }
1055
1056 { /* extract bits */
1057 guint8* pui8 = pui8DATA(data, pDescr->offset);
1058 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1059
1060 if (nB1 > 0)
1061 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001062 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001063 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001064 pui8++;
1065 no_of_bits -= nB1;
1066 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1067 }
1068
1069 /* remaining no_of_bits is a multiple of 8 or 0 */
1070 while (no_of_bits > 0)
1071 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001072 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001073 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001074 pui8++;
1075 no_of_bits -= 8;
1076 }
1077 }
1078 }
1079 pDescr++;
1080 break;
1081 }
1082
1083 case CSN_LEFT_ALIGNED_VAR_BMP_1:
1084 { /* Bitmap from here and to the end of message */
1085
1086 *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
1087
1088 /* no break -
1089 * with a length set we have a regular left aligned variable length bitmap so we continue
1090 */
1091 }
1092
1093 case CSN_LEFT_ALIGNED_VAR_BMP:
1094 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1095 * <N: bit (5)> <bitmap: bit(N + offset)>
1096 * bit array with length (in bits) specified in parameter (pDescr->descr)
1097 */
1098 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
1099
1100 no_of_bits += pDescr->i;/* size adjusted by offset */
1101
1102 if (no_of_bits > 0)
1103 {
1104 remaining_bits_len -= no_of_bits;
1105
1106 if (remaining_bits_len < 0)
1107 {
1108 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1109 }
1110
1111 { /* extract bits */
1112 guint8* pui8 = pui8DATA(data, pDescr->offset);
1113 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
1114
1115 while (no_of_bits > 0)
1116 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001117 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001118 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001119 pui8++;
1120 no_of_bits -= 8;
1121 }
1122 if (nB1 > 0)
1123 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001124 *pui8 = bitvec_read_field(vector, readIndex, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001125 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001126 pui8++;
1127 no_of_bits -= nB1;
1128 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1129 }
1130 }
1131 }
1132
1133 /* bitmap was successfully extracted or it was empty */
1134 pDescr++;
1135 break;
1136 }
1137
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001138 case CSN_PADDING_BITS:
1139 { /* Padding from here and to the end of message */
1140 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
1141 if (remaining_bits_len > 0)
1142 {
1143 while (remaining_bits_len > 0)
1144 {
1145 guint8 bits_to_handle = remaining_bits_len%8;
1146 if (bits_to_handle > 0)
1147 {
Daniel Willmann5d77f142014-06-04 15:17:10 +02001148 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, readIndex, bits_to_handle));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001149 remaining_bits_len -= bits_to_handle;
1150 bit_offset += bits_to_handle;
1151 }
1152 else if (bits_to_handle == 0)
1153 {
Daniel Willmann5d77f142014-06-04 15:17:10 +02001154 LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, readIndex, 8));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001155 remaining_bits_len -= 8;
1156 bit_offset += 8;
1157 }
1158 }
1159 }
1160 if (remaining_bits_len < 0)
1161 {
1162 return ProcessError(readIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1163 }
1164
1165 /* Padding was successfully extracted or it was empty */
1166 pDescr++;
1167 break;
1168 }
1169
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001170 case CSN_VARIABLE_ARRAY:
1171 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1172 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1173 * Array with length specified in parameter:
1174 * <count: bit (x)>
1175 * <list: octet(count + offset)>
1176 */
1177 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1178
1179 count += pDescr->i; /* Adjusted by offset */
1180
1181 if (count > 0)
1182 {
1183 remaining_bits_len -= count * 8;
1184
1185 if (remaining_bits_len < 0)
1186 {
1187 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1188 }
1189
1190 pui8 = pui8DATA(data, pDescr->offset);
1191
1192 while (count > 0)
1193 {
1194 readIndex -= 8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001195 *pui8 = bitvec_read_field(vector, readIndex, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001196 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001197 pui8++;
1198 bit_offset += 8;
1199 count--;
1200 }
1201 }
1202
1203 pDescr++;
1204 break;
1205 }
1206
1207 case CSN_RECURSIVE_ARRAY:
1208 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1209 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1210 * where <element> ::= bit(value)
1211 * <tag> ::= 0 | 1
1212 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1213 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1214 * REMARK: recursive way to specify an array but an iterative implementation!
1215 */
1216 gint16 no_of_bits = pDescr->i;
1217 guint8 ElementCount = 0;
1218
1219 pui8 = pui8DATA(data, pDescr->offset);
1220
1221 while (existNextElement(vector, readIndex, Tag))
1222 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001223 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001224 bit_offset++;
1225 remaining_bits_len--;
1226
1227 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001228 *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001229 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001230 pui8++;
1231 remaining_bits_len -= no_of_bits;
1232 ElementCount++;
1233
1234 if (remaining_bits_len < 0)
1235 {
1236 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1237 }
1238
1239 bit_offset += no_of_bits;
1240 }
1241
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001242 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001243 /* existNextElement() returned FALSE, 1 bit consumed */
1244 bit_offset++;
1245
1246 /* Store the counted number of elements of the array */
1247 *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
1248
1249 pDescr++;
1250 break;
1251 }
1252
1253 case CSN_RECURSIVE_TARRAY:
1254 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1255 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1256 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1257 */
1258 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1259 guint8 ElementCount = 0;
1260 pui8 = pui8DATA(data, pDescr->offset);
1261
1262 while (existNextElement(vector, readIndex, Tag))
1263 { /* tag control shows existence of next list elements */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001264 LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001265 /* existNextElement() returned TRUE, 1 bit consumed */
1266 bit_offset++;
1267 remaining_bits_len--;
1268 ElementCount++;
1269
1270 { /* unpack the following data structure */
1271 csnStream_t arT = *ar;
1272 gint16 Status;
1273 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04001274 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001275
1276 if (Status >= 0)
1277 { /* successful completion */
1278 pui8 += nSizeElement; /* -> to next data element */
1279 remaining_bits_len = arT.remaining_bits_len;
1280 bit_offset = arT.bit_offset;
1281 }
1282 else
1283 { /* something went awry */
1284 return Status;
1285 }
1286 }
1287
1288 if (remaining_bits_len < 0)
1289 {
1290 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1291 }
1292 }
1293
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001294 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001295
1296 /* existNextElement() returned FALSE, 1 bit consumed */
1297 bit_offset++;
1298
1299 /* Store the counted number of elements of the array */
1300 *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
1301
1302 pDescr++;
1303 break;
1304 }
1305
1306 case CSN_RECURSIVE_TARRAY_2:
1307 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1308
1309 Tag = REVERSED_TAG;
1310
1311 /* NO break -
1312 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1313 */
1314 }
1315
1316 case CSN_RECURSIVE_TARRAY_1:
1317 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1318 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1319 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1320 */
1321 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
1322 guint8 ElementCount = 0;
1323 csnStream_t arT = *ar;
1324 gboolean EndOfList = FALSE;
1325 gint16 Status;
1326 pui8 = pui8DATA(data, pDescr->offset);
1327
1328 do
1329 { /* get data element */
1330 ElementCount++;
1331
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001332 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
1333
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001334 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04001335 Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001336
1337 if (Status >= 0)
1338 { /* successful completion */
1339 pui8 += nSizeElement; /* -> to next */
1340 remaining_bits_len = arT.remaining_bits_len;
1341 bit_offset = arT.bit_offset;
1342 }
1343 else
1344 { /* something went awry */
1345 return Status;
1346 }
1347
1348 if (remaining_bits_len < 0)
1349 {
1350 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1351 }
1352
1353 /* control of next element's tag */
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001354 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001355 EndOfList = !(existNextElement(vector, readIndex, Tag));
1356
1357 bit_offset++;
1358 remaining_bits_len--; /* 1 bit consumed (tag) */
1359 } while (!EndOfList);
1360
1361
1362 /* Store the count of the array */
1363 *pui8DATA(data, pDescr->i) = ElementCount;
1364 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1365 pDescr++;
1366 break;
1367 }
1368
1369 case CSN_FIXED:
1370 { /* Verify the fixed bits */
1371 guint8 no_of_bits = (guint8) pDescr->i;
1372 guint32 ui32;
1373
1374 if (no_of_bits <= 32)
1375 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001376 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001377 }
1378 else
1379 {
1380 return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
1381 }
1382 if (ui32 != (unsigned)(gint32)pDescr->offset)
1383 {
1384 return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
1385 }
1386
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001387 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)ui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001388 remaining_bits_len -= no_of_bits;
1389 bit_offset += no_of_bits;
1390 pDescr++;
1391 break;
1392 }
1393
1394 case CSN_CALLBACK:
1395 {
1396 return ProcessError(readIndex,"csnStreamDecoder Callback not implemented", -1, pDescr);
1397 break;
1398 }
1399
1400 case CSN_TRAP_ERROR:
1401 {
1402 return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
1403 }
1404
1405 case CSN_END:
1406 {
1407 ar->remaining_bits_len = remaining_bits_len;
1408 ar->bit_offset = bit_offset;
1409 return remaining_bits_len;
1410 }
1411
1412 default:
1413 {
1414 assert(0);
1415 }
1416
1417
1418 }
1419
1420 } while (remaining_bits_len >= 0);
1421
1422 return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1423}
1424
1425
1426
1427
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001428gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, bitvec *vector, unsigned& writeIndex, void* data)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001429{
1430 gint remaining_bits_len = ar->remaining_bits_len;
1431 gint bit_offset = ar->bit_offset;
1432 guint8* pui8;
1433 guint16* pui16;
1434 guint32* pui32;
1435 guint64* pui64;
1436
1437 guint8 Tag = STANDARD_TAG;
1438
1439 if (remaining_bits_len <= 0)
1440 {
1441 return 0;
1442 }
1443
1444 do
1445 {
1446 switch (pDescr->type)
1447 {
1448 case CSN_BIT:
1449 {
1450 if (remaining_bits_len > 0)
1451 {
1452 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001453 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001454 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001455 /* end add the bit value to protocol tree */
1456 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001457 else if(pDescr->may_be_null)
1458 {
1459 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
1460 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001461 else
1462 {
1463 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1464 }
1465
1466 pDescr++;
1467 remaining_bits_len--;
1468 bit_offset++;
1469 break;
1470 }
1471
1472 case CSN_NULL:
1473 { /* Empty member! */
1474 pDescr++;
1475 break;
1476 }
1477
1478 case CSN_UINT:
1479 {
1480 guint8 no_of_bits = (guint8) pDescr->i;
1481
1482 if (remaining_bits_len >= no_of_bits)
1483 {
1484 if (no_of_bits <= 8)
1485 {
1486 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001487 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001488 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001489 }
1490 else if (no_of_bits <= 16)
1491 {
1492 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001493 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001494 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001495 }
1496 else if (no_of_bits <= 32)
1497 {
1498 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001499 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001500 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001501 }
1502 else
1503 {
1504 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1505 }
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001506
1507 remaining_bits_len -= no_of_bits;
1508 bit_offset += no_of_bits;
1509 }
1510 else if(pDescr->may_be_null)
1511 {
1512 LOGPC(DCSN1, LOGL_NOTICE, "%s = NULL | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001513 }
1514 else
1515 {
1516 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1517 }
1518
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001519 pDescr++;
1520 break;
1521 }
1522
1523 case CSN_UINT_OFFSET:
1524 {
1525 guint8 no_of_bits = (guint8) pDescr->i;
1526
1527 if (remaining_bits_len >= no_of_bits)
1528 {
1529 if (no_of_bits <= 8)
1530 {
1531 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001532 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001533 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001534 }
1535 else if (no_of_bits <= 16)
1536 {
1537 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001538 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001539 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001540 }
1541 else if (no_of_bits <= 32)
1542 {
1543 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001544 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001545 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001546 }
1547 else
1548 {
1549 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1550 }
1551 }
1552 else
1553 {
1554 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1555 }
1556
1557 remaining_bits_len -= no_of_bits;
1558 bit_offset += no_of_bits;
1559 pDescr++;
1560 break;
1561 }
1562
1563 case CSN_UINT_LH:
1564 {
1565 guint8 no_of_bits = (guint8) pDescr->i;
1566
1567 if (remaining_bits_len >= no_of_bits)
1568 {
1569 remaining_bits_len -= no_of_bits;
1570 if (no_of_bits <= 8)
1571 {
1572 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001573 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001574 // TODO : Change get_masked_bits8()
1575 writeIndex -= no_of_bits;
1576 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1577 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001578 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001579 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001580
1581 }
1582 else
1583 {/* Maybe we should support more than 8 bits ? */
1584 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1585 }
1586 }
1587 else
1588 {
1589 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1590 }
1591
1592 remaining_bits_len -= no_of_bits;
1593 bit_offset += no_of_bits;
1594 pDescr++;
1595 break;
1596 }
1597
1598 case CSN_UINT_ARRAY:
1599 {
1600 guint8 no_of_bits = (guint8) pDescr->i;
1601 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
1602
1603 if (pDescr->serialize.value != 0)
1604 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
1605 nCount = *pui16DATA(data, nCount);
1606 }
1607
1608 if (remaining_bits_len >= no_of_bits)
1609 {
1610 remaining_bits_len -= (no_of_bits*nCount);
1611 if (no_of_bits <= 8)
1612 {
1613 pui8 = pui8DATA(data, pDescr->offset);
1614 do
1615 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001616 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1617 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001618 pui8++;
1619 bit_offset += no_of_bits;
1620 } while (--nCount > 0);
1621 }
1622 else if (no_of_bits <= 16)
1623 {
1624 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1625 }
1626 else if (no_of_bits <= 32)
1627 {
1628 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
1629 }
1630 else
1631 {
1632 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1633 }
1634 }
1635 else
1636 {
1637 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1638 }
1639 pDescr++;
1640 break;
1641 }
1642
1643 case CSN_VARIABLE_TARRAY_OFFSET:
1644 case CSN_VARIABLE_TARRAY:
1645 case CSN_TYPE_ARRAY:
1646 {
1647 gint16 Status;
1648 csnStream_t arT = *ar;
1649 gint16 nCount = pDescr->i;
1650 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
1651
1652 pui8 = pui8DATA(data, pDescr->offset);
1653 if (pDescr->type == CSN_VARIABLE_TARRAY)
1654 { /* Count specified in field */
1655 nCount = *pui8DATA(data, pDescr->i);
1656 }
1657 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
1658 { /* Count specified in field */
1659 nCount = *pui8DATA(data, pDescr->i);
1660 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
1661 }
1662
1663 while (nCount > 0)
1664 { /* resulting array of length 0 is possible
1665 * but no bits shall be read from bitstream
1666 */
1667
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001668 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001669 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1670 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1671 if (Status >= 0)
1672 {
1673 pui8 += nSize;
1674 remaining_bits_len = arT.remaining_bits_len;
1675 bit_offset = arT.bit_offset;
1676
1677 }
1678 else
1679 {
1680 return Status;
1681 }
1682 nCount--;
1683 }
1684
1685 pDescr++;
1686 break;
1687 }
1688
1689 case CSN_BITMAP:
1690 { /* bitmap with given length. The result is left aligned! */
1691 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
1692
1693 if (no_of_bits > 0)
1694 {
1695
1696 if (no_of_bits <= 32)
1697 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001698 for(unsigned ib = 0; ib < 4; ib++)
1699 {
1700 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001701 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001702 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001703 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001704 }
1705 else if (no_of_bits <= 64)
1706 {
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001707 for(unsigned ib = 0; ib < 8; ib++)
1708 {
1709 pui8 = pui8DATA(data, pDescr->offset+ib);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001710 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001711 LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
Ivan Kluchnikov74b459f2012-04-11 22:02:15 +04001712 }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001713 }
1714 else
1715 {
1716 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
1717 }
1718
1719 remaining_bits_len -= no_of_bits;
1720 assert(remaining_bits_len >= 0);
1721 bit_offset += no_of_bits;
1722 }
1723 /* bitmap was successfully extracted or it was empty */
1724
1725 pDescr++;
1726 break;
1727 }
1728
1729 case CSN_TYPE:
1730 {
1731 gint16 Status;
1732 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001733 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001734 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1735 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001736 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001737 if (Status >= 0)
1738 {
1739
1740 remaining_bits_len = arT.remaining_bits_len;
1741 bit_offset = arT.bit_offset;
1742 pDescr++;
1743 }
1744 else
1745 {
1746 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
1747 return Status;
1748 }
1749
1750 break;
1751 }
1752
1753 case CSN_CHOICE:
1754 {
1755 //gint16 count = pDescr->i;
1756 guint8 i = 0;
1757 CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
1758
1759 pui8 = pui8DATA(data, pDescr->offset);
1760 i = *pui8;
1761 pChoice += i;
1762 guint8 no_of_bits = pChoice->bits;
1763 guint8 value = pChoice->value;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001764 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001765 bitvec_write_field(vector, writeIndex, value, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001766
1767 CSN_DESCR descr[2];
1768 gint16 Status;
1769 csnStream_t arT = *ar;
1770
1771 descr[0] = pChoice->descr;
1772 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
1773 descr[1].type = CSN_END;
1774 bit_offset += no_of_bits;
1775 remaining_bits_len -= no_of_bits;
1776
1777 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1778 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
1779
1780 if (Status >= 0)
1781 {
1782 remaining_bits_len = arT.remaining_bits_len;
1783 bit_offset = arT.bit_offset;
1784 }
1785 else
1786 {
1787 return Status;
1788 }
1789
1790 pDescr++;
1791 break;
1792 }
1793
1794 case CSN_SERIALIZE:
1795 {
1796 StreamSerializeFcn_t serialize = pDescr->serialize.fcn;
1797 csnStream_t arT = *ar;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001798 guint8 length_len = pDescr->i;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001799 gint16 Status = -1;
Ivan Kluchnikov9b06ff02012-06-15 10:13:30 +04001800 unsigned lengthIndex;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001801
1802 // store writeIndex for length value (7 bit)
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001803 lengthIndex = writeIndex;
1804 writeIndex += length_len;
1805 bit_offset += length_len;
1806 remaining_bits_len -= length_len;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001807 arT.direction = 0;
1808 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1809 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04001810
1811 bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-length_len, length_len);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001812 LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001813
1814 if (Status >= 0)
1815 {
1816 remaining_bits_len = arT.remaining_bits_len;
1817 bit_offset = arT.bit_offset;
1818 pDescr++;
1819 }
1820 else
1821 {
1822 // Has already been processed:
1823 return Status;
1824 }
1825
1826 break;
1827 }
1828
1829 case CSN_UNION_LH:
1830 case CSN_UNION:
1831 {
1832 gint16 Bits;
1833 guint8 index;
1834 gint16 count = pDescr->i;
1835 const CSN_DESCR* pDescrNext = pDescr;
1836
1837 pDescrNext += count + 1; /* now this is next after the union */
1838 if ((count <= 0) || (count > 16))
1839 {
1840 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
1841 }
1842
1843 /* Now get the bits to extract the index */
1844 Bits = ixBitsTab[count];
1845 index = 0;
1846
1847 /* Assign UnionType */
1848 pui8 = pui8DATA(data, pDescr->offset);
1849 //read index from data and write to vector
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001850 bitvec_write_field(vector, writeIndex, *pui8, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001851
1852 //decode index
1853 writeIndex -= Bits;
1854
1855 while (Bits > 0)
1856 {
1857 index <<= 1;
1858
1859 if (CSN_UNION_LH == pDescr->type)
1860 {
1861 index |= get_masked_bits8(vector,writeIndex, bit_offset, 1);
1862 }
1863 else
1864 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001865 index |= bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001866 }
1867
1868 remaining_bits_len--;
1869 bit_offset++;
1870 Bits--;
1871 }
1872
1873 writeIndex -= Bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001874 bitvec_write_field(vector, writeIndex, index, Bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001875
1876
1877 /* script index to continue on, limited in case we do not have a power of 2 */
1878 pDescr += (MIN(index + 1, count));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001879 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)index);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001880
1881 switch (pDescr->type)
1882 { /* get the right element of the union based on computed index */
1883
1884 case CSN_BIT:
1885 {
1886 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001887 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001888 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001889 remaining_bits_len -= 1;
1890 bit_offset++;
1891 pDescr++;
1892 break;
1893 }
1894
1895 case CSN_NULL:
1896 { /* Empty member! */
1897 pDescr++;
1898 break;
1899 }
1900
1901 case CSN_UINT:
1902 {
1903 guint8 no_of_bits = (guint8) pDescr->i;
1904 if (remaining_bits_len >= no_of_bits)
1905 {
1906 remaining_bits_len -= no_of_bits;
1907
1908 if (no_of_bits <= 8)
1909 {
1910 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001911 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001912 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001913 }
1914 else if (no_of_bits <= 16)
1915 {
1916 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001917 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001918 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001919 }
1920 else if (no_of_bits <= 32)
1921 {
1922 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001923 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001924 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001925 }
1926 else
1927 {
1928 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1929 }
1930 }
1931 else
1932 {
1933 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1934 }
1935
1936 bit_offset += no_of_bits;
1937 pDescr++;
1938 break;
1939 }
1940
1941 case CSN_UINT_OFFSET:
1942 {
1943 guint8 no_of_bits = (guint8) pDescr->i;
1944
1945 if (remaining_bits_len >= no_of_bits)
1946 {
1947 if (no_of_bits <= 8)
1948 {
1949 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001950 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001951 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001952 }
1953 else if (no_of_bits <= 16)
1954 {
1955 pui16 = pui16DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001956 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001957 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001958 }
1959 else if (no_of_bits <= 32)
1960 {
1961 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001962 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001963 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001964 }
1965 else
1966 {
1967 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
1968 }
1969 }
1970 else
1971 {
1972 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1973 }
1974
1975 remaining_bits_len -= no_of_bits;
1976 bit_offset += no_of_bits;
1977 pDescr++;
1978 break;
1979 }
1980
1981 case CSN_UINT_LH:
1982 {
1983 guint8 no_of_bits = (guint8) pDescr->i;
1984
1985 if (remaining_bits_len >= no_of_bits)
1986 {
1987 remaining_bits_len -= no_of_bits;
1988 if (no_of_bits <= 8)
1989 {
1990 pui8 = pui8DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001991 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001992 // TODO : Change get_masked_bits8()
1993 writeIndex -= no_of_bits;
1994 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
1995 writeIndex -= no_of_bits;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04001996 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04001997 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03001998
1999 }
2000 else
2001 {/* Maybe we should support more than 8 bits ? */
2002 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2003 }
2004 }
2005 else
2006 {
2007 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2008 }
2009
2010 remaining_bits_len -= no_of_bits;
2011 bit_offset += no_of_bits;
2012 pDescr++;
2013 break;
2014 }
2015
2016 case CSN_UINT_ARRAY:
2017 {
2018 guint8 no_of_bits = (guint8) pDescr->i;
2019 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
2020
2021 if (pDescr->serialize.value != 0)
2022 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
2023 nCount = *pui16DATA(data, nCount);
2024 }
2025
2026 if (remaining_bits_len >= no_of_bits)
2027 {
2028 remaining_bits_len -= (no_of_bits*nCount);
2029 if (no_of_bits <= 8)
2030 {
2031 pui8 = pui8DATA(data, pDescr->offset);
2032 do
2033 {
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002034 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
2035 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002036 pui8++;
2037 bit_offset += no_of_bits;
2038 } while (--nCount > 0);
2039 }
2040 else if (no_of_bits <= 16)
2041 {
2042 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2043 }
2044 else if (no_of_bits <= 32)
2045 {
2046 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
2047 }
2048 else
2049 {
2050 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
2051 }
2052 }
2053 else
2054 {
2055 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2056 }
2057 pDescr++;
2058 break;
2059 }
2060
2061 case CSN_VARIABLE_TARRAY_OFFSET:
2062 case CSN_VARIABLE_TARRAY:
2063 case CSN_TYPE_ARRAY:
2064 {
2065 gint16 Status;
2066 csnStream_t arT = *ar;
2067 gint16 nCount = pDescr->i;
2068 guint16 nSize = (guint16)(gint32)pDescr->serialize.value;
2069
2070 pui8 = pui8DATA(data, pDescr->offset);
2071 if (pDescr->type == CSN_VARIABLE_TARRAY)
2072 { /* Count specified in field */
2073 nCount = *pui8DATA(data, pDescr->i);
2074 }
2075 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
2076 { /* Count specified in field */
2077 nCount = *pui8DATA(data, pDescr->i);
2078 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
2079 }
2080
2081 while (nCount > 0)
2082 { /* resulting array of length 0 is possible
2083 * but no bits shall be read from bitstream
2084 */
2085
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002086 LOGPC(DCSN1, LOGL_NOTICE, "%s : | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002087 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2088 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
2089 if (Status >= 0)
2090 {
2091 pui8 += nSize;
2092 remaining_bits_len = arT.remaining_bits_len;
2093 bit_offset = arT.bit_offset;
2094 }
2095 else
2096 {
2097 return Status;
2098 }
2099 nCount--;
2100 }
2101
2102 pDescr++;
2103 break;
2104 }
2105
2106 case CSN_BITMAP:
2107 { /* bitmap with given length. The result is left aligned! */
2108 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
2109
2110 if (no_of_bits > 0)
2111 {
2112
2113 if (no_of_bits <= 32)
2114 {
2115 pui32 = pui32DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002116 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002117 LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002118 }
2119 else if (no_of_bits <= 64)
2120 {
2121 pui64 = pui64DATA(data, pDescr->offset);
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002122 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +02002123 LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002124 }
2125 else
2126 {
2127 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
2128 }
2129
2130 remaining_bits_len -= no_of_bits;
2131 assert(remaining_bits_len >= 0);
2132 bit_offset += no_of_bits;
2133 }
2134 /* bitmap was successfully extracted or it was empty */
2135
2136 pDescr++;
2137 break;
2138 }
2139
2140 case CSN_TYPE:
2141 {
2142 gint16 Status;
2143 csnStream_t arT = *ar;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002144 LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002145 csnStreamInit(&arT, bit_offset, remaining_bits_len);
2146 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002147 LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002148 if (Status >= 0)
2149 {
2150 remaining_bits_len = arT.remaining_bits_len;
2151 bit_offset = arT.bit_offset;
2152 pDescr++;
2153 }
2154 else
2155 {
2156 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
2157 return Status;
2158 }
2159
2160 break;
2161 }
2162
2163 default:
2164 { /* descriptions of union elements other than above are illegal */
2165 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
2166 }
2167 }
2168
2169 pDescr = pDescrNext;
2170 break;
2171 }
2172
2173 case CSN_EXIST:
2174 case CSN_EXIST_LH:
2175 {
2176 guint8 fExist;
2177 unsigned exist = 0;
2178 pui8 = pui8DATA(data, pDescr->offset);
2179 exist = *pui8;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002180 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002181 writeIndex--;
2182 if (CSN_EXIST_LH == pDescr->type)
2183 {
2184 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
2185 }
2186 else
2187 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002188 fExist = bitvec_read_field(vector, writeIndex, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002189 }
2190 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002191 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002192 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002193 pDescr++;
2194 remaining_bits_len -= 1;
2195
2196 if (!exist)
2197 {
2198 ar->remaining_bits_len = remaining_bits_len;
2199 ar->bit_offset = bit_offset;
2200 return remaining_bits_len;
2201 }
2202 break;
2203 }
2204
2205 case CSN_NEXT_EXIST:
2206 {
2207 guint8 fExist;
2208
2209 pui8 = pui8DATA(data, pDescr->offset);
2210
2211 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002212 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002213 { /* no more bits to decode is fine here - end of message detected and allowed */
2214
2215 /* Skip i entries + this entry */
2216 pDescr += pDescr->i + 1;
2217
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002218 break;
2219 }
2220
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002221 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002222 fExist = *pui8;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002223 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002224 remaining_bits_len -= 1;
2225
2226 ++bit_offset;
2227
2228 if (fExist == 0)
2229 { /* Skip 'i' entries */
2230 pDescr += pDescr->i;
2231 }
2232
2233 pDescr++;
2234 break;
2235 }
2236
2237 case CSN_NEXT_EXIST_LH:
2238 {
2239 guint8 fExist;
2240 pui8 = pui8DATA(data, pDescr->offset);
2241
2242 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
2243 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
2244 { /* no more bits to decode is fine here - end of message detected and allowed */
2245
2246 /* skip 'i' entries + this entry */
2247 pDescr += pDescr->i + 1;
2248
2249 /* pDescr now must be pointing to a CSN_END entry, if not this is an error */
2250 if ( pDescr->type != CSN_END )
2251 { /* substract one more bit from remaining_bits_len to make the "not enough bits" error to be triggered */
2252 remaining_bits_len--;
2253 }
2254
2255 /* set the data member to "not exist" */
2256 //*pui8 = 0;
2257 break;
2258 }
2259
2260 /* the "regular" M_NEXT_EXIST_LH description element */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002261 bitvec_write_field(vector, writeIndex, *pui8, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002262 writeIndex--;
2263 fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1);
2264 writeIndex--;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002265 bitvec_write_field(vector, writeIndex, fExist, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002266 pui8++;
2267 remaining_bits_len -= 1;
2268
2269 bit_offset++;
2270
2271 if (fExist == 0)
2272 { /* Skip 'i' entries */
2273 pDescr += pDescr->i;
2274 }
2275 pDescr++;
2276
2277 break;
2278 }
2279
2280 case CSN_VARIABLE_BITMAP_1:
2281 { /* Bitmap from here and to the end of message */
2282
2283 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2284
2285 /*no break -
2286 * with a length set we have a regular variable length bitmap so we continue */
2287 }
2288
2289 case CSN_VARIABLE_BITMAP:
2290 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2291 * <N: bit (5)> <bitmap: bit(N + offset)>
2292 * Bit array with length (in bits) specified in parameter (pDescr->descr)
2293 * The result is right aligned!
2294 */
2295 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
2296
2297 no_of_bits += pDescr->i; /* adjusted by offset */
2298
2299 if (no_of_bits > 0)
2300 {
2301 remaining_bits_len -= no_of_bits;
2302
2303 if (remaining_bits_len < 0)
2304 {
2305 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2306 }
2307
2308 { /* extract bits */
2309 guint8* pui8 = pui8DATA(data, pDescr->offset);
2310 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2311
2312 if (nB1 > 0)
2313 { /* take care of the first byte - it will be right aligned */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002314 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002315 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002316 pui8++;
2317 no_of_bits -= nB1;
2318 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2319 }
2320
2321 /* remaining no_of_bits is a multiple of 8 or 0 */
2322 while (no_of_bits > 0)
2323 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002324 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002325 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002326 pui8++;
2327 no_of_bits -= 8;
2328 }
2329 }
2330 }
2331 pDescr++;
2332 break;
2333 }
2334
2335 case CSN_LEFT_ALIGNED_VAR_BMP_1:
2336 { /* Bitmap from here and to the end of message */
2337
2338 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
2339
2340 /* no break -
2341 * with a length set we have a regular left aligned variable length bitmap so we continue
2342 */
2343 }
2344
2345 case CSN_LEFT_ALIGNED_VAR_BMP:
2346 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2347 * <N: bit (5)> <bitmap: bit(N + offset)>
2348 * bit array with length (in bits) specified in parameter (pDescr->descr)
2349 */
2350
2351 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
2352
2353 no_of_bits += pDescr->i;/* size adjusted by offset */
2354
2355 if (no_of_bits > 0)
2356 {
2357 remaining_bits_len -= no_of_bits;
2358
2359 if (remaining_bits_len < 0)
2360 {
2361 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2362 }
2363
2364 { /* extract bits */
2365 guint8* pui8 = pui8DATA(data, pDescr->offset);
2366 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
2367
2368 while (no_of_bits > 0)
2369 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002370 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002371 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002372 pui8++;
2373 no_of_bits -= 8;
2374 }
2375 if (nB1 > 0)
2376 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002377 bitvec_write_field(vector, writeIndex, *pui8, nB1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002378 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002379 pui8++;
2380 no_of_bits -= nB1;
2381 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
2382 }
2383 }
2384
2385 }
2386
2387 /* bitmap was successfully extracted or it was empty */
2388 pDescr++;
2389 break;
2390 }
2391
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002392 case CSN_PADDING_BITS:
2393 { /* Padding from here and to the end of message */
2394 LOGPC(DCSN1, LOGL_NOTICE, "%s = ", pDescr->sz);
2395 guint8 filler = 0x2b;
2396 if (remaining_bits_len > 0)
2397 {
2398 while (remaining_bits_len > 0)
2399 {
2400 guint8 bits_to_handle = remaining_bits_len%8;
2401 if (bits_to_handle > 0)
2402 {
2403 guint8 fl = filler&(0xff>>(8-bits_to_handle));
2404 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
2405 LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl);
2406 remaining_bits_len -= bits_to_handle;
2407 bit_offset += bits_to_handle;
2408 }
2409 else if (bits_to_handle == 0)
2410 {
2411 bitvec_write_field(vector, writeIndex, filler, 8);
2412 LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler);
2413 remaining_bits_len -= 8;
2414 bit_offset += 8;
2415 }
2416 }
2417 }
2418 if (remaining_bits_len < 0)
2419 {
2420 return ProcessError(writeIndex,"csnStreamDissector", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2421 }
2422
2423 /* Padding was successfully extracted or it was empty */
2424 pDescr++;
2425 break;
2426 }
2427
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002428 case CSN_VARIABLE_ARRAY:
2429 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
2430 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2431 * Array with length specified in parameter:
2432 * <count: bit (x)>
2433 * <list: octet(count + offset)>
2434 */
2435 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
2436
2437 count += pDescr->i; /* Adjusted by offset */
2438
2439 if (count > 0)
2440 {
2441 remaining_bits_len -= count * 8;
2442
2443 if (remaining_bits_len < 0)
2444 {
2445 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2446 }
2447
2448 pui8 = pui8DATA(data, pDescr->offset);
2449
2450 while (count > 0)
2451 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002452 bitvec_write_field(vector, writeIndex, *pui8, 8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002453 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002454 pui8++;
2455 bit_offset += 8;
2456 count--;
2457 }
2458 }
2459
2460 pDescr++;
2461 break;
2462 }
2463
2464 case CSN_RECURSIVE_ARRAY:
2465 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
2466 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
2467 * where <element> ::= bit(value)
2468 * <tag> ::= 0 | 1
2469 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
2470 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
2471 * REMARK: recursive way to specify an array but an iterative implementation!
2472 */
2473 gint16 no_of_bits = pDescr->i;
2474 guint8 ElementCount = 0;
2475 pui8 = pui8DATA(data, pDescr->offset);
2476 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
2477 while (ElementCount > 0)
2478 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002479 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002480 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002481 bit_offset++;
2482 remaining_bits_len--;
2483
2484 /* extract and store no_of_bits long element from bitstream */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002485 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002486 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002487 pui8++;
2488 remaining_bits_len -= no_of_bits;
2489 ElementCount--;
2490
2491 if (remaining_bits_len < 0)
2492 {
2493 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2494 }
2495
2496 bit_offset += no_of_bits;
2497 }
2498
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002499 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002500 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002501 bit_offset++;
2502
2503 pDescr++;
2504 break;
2505 }
2506
2507 case CSN_RECURSIVE_TARRAY:
2508 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
2509 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2510 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2511 */
2512 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2513 guint8 ElementCount = 0;
2514 pui8 = pui8DATA(data, pDescr->offset);
2515 /* Store the counted number of elements of the array */
2516 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
2517
2518 while (ElementCount > 0)
2519 { /* tag control shows existence of next list elements */
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002520 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002521 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002522 bit_offset++;
2523
2524 remaining_bits_len--;
2525 ElementCount--;
2526
2527 { /* unpack the following data structure */
2528 csnStream_t arT = *ar;
2529 gint16 Status;
2530 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002531 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002532
2533 if (Status >= 0)
2534 { /* successful completion */
2535 pui8 += nSizeElement; /* -> to next data element */
2536 remaining_bits_len = arT.remaining_bits_len;
2537 bit_offset = arT.bit_offset;
2538 }
2539 else
2540 { /* something went awry */
2541 return Status;
2542 }
2543 }
2544
2545 if (remaining_bits_len < 0)
2546 {
2547 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2548 }
2549 }
2550
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002551 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002552 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002553 bit_offset++;
2554
2555 pDescr++;
2556 break;
2557 }
2558
2559 case CSN_RECURSIVE_TARRAY_2:
2560 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
2561
2562 Tag = REVERSED_TAG;
2563
2564 /* NO break -
2565 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
2566 */
2567 }
2568
2569 case CSN_RECURSIVE_TARRAY_1:
2570 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
2571 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
2572 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
2573 */
2574 gint16 nSizeElement = (gint16)(gint32)pDescr->serialize.value;
2575 guint8 ElementCount = 0;
2576 guint8 ElementNum = 0;
2577 csnStream_t arT = *ar;
2578 gint16 Status;
2579
2580 pui8 = pui8DATA(data, pDescr->offset);
2581 /* Store the count of the array */
2582 ElementCount = *pui8DATA(data, pDescr->i);
2583 ElementNum = ElementCount;
2584
2585 while (ElementCount > 0)
2586 { /* get data element */
2587 if (ElementCount != ElementNum)
2588 {
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002589 bitvec_write_field(vector, writeIndex, Tag, 1);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002590 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002591 bit_offset++;
2592 remaining_bits_len--;
2593 }
2594 ElementCount--;
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002595 LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002596 csnStreamInit(&arT, bit_offset, remaining_bits_len);
Ivan Kluchnikov44408452013-03-01 02:46:10 +04002597 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002598 LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002599 if (Status >= 0)
2600 { /* successful completion */
2601 pui8 += nSizeElement; /* -> to next */
2602 remaining_bits_len = arT.remaining_bits_len;
2603 bit_offset = arT.bit_offset;
2604 }
2605 else
2606 { /* something went awry */
2607 return Status;
2608 }
2609
2610 if (remaining_bits_len < 0)
2611 {
2612 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2613 }
2614
2615 }
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002616 bitvec_write_field(vector, writeIndex, !Tag, 1);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002617 bit_offset++;
Ivan Kluchnikov701d9f82012-10-10 19:43:37 +04002618 remaining_bits_len--;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002619 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
2620 pDescr++;
2621 break;
2622 }
2623
2624 case CSN_FIXED:
2625 { /* Verify the fixed bits */
2626 guint8 no_of_bits = (guint8) pDescr->i;
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +04002627 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +04002628 LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002629 remaining_bits_len -= no_of_bits;
2630 bit_offset += no_of_bits;
2631 pDescr++;
2632 break;
2633 }
2634
2635 case CSN_CALLBACK:
2636 {
2637 return ProcessError(writeIndex,"csnStreamEncoder Callback not implemented", -1, pDescr);
2638 break;
2639 }
2640
2641 case CSN_TRAP_ERROR:
2642 {
2643 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
2644 }
2645
2646 case CSN_END:
2647 {
2648 ar->remaining_bits_len = remaining_bits_len;
2649 ar->bit_offset = bit_offset;
2650 return remaining_bits_len;
2651 }
2652
2653 default:
2654 {
2655 assert(0);
2656 }
2657
2658 }
2659
2660 } while (remaining_bits_len >= 0);
2661
2662 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
2663}
2664