blob: 5518d063e5ac21c5cf39fa7e91ad397ed77506a9 [file] [log] [blame]
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +02001/* csn1_enc.c
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 <assert.h>
32#include <string.h>
33#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
35#include "csn1.h"
36#include <gprs_debug.h>
37
38#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
40
41extern const unsigned char ixBitsTab[];
42guint8 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits);
43
44/**
45 * ================================================================================================
46 * set initial/start values in help data structure used for packing/unpacking operation
47 * ================================================================================================
48 */
49
50gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
51{
52 gint remaining_bits_len = ar->remaining_bits_len;
53 gint bit_offset = ar->bit_offset;
54 guint8* pui8;
55 guint16* pui16;
56 guint32* pui32;
57 guint64* pui64;
58 unsigned ib;
59
60 guint8 Tag = STANDARD_TAG;
61
62 if (remaining_bits_len < 0)
63 {
64 return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
65 }
66
67 do
68 {
69 switch (pDescr->type)
70 {
71 case CSN_BIT:
72 {
73 if (remaining_bits_len > 0)
74 {
75 pui8 = pui8DATA(data, pDescr->offset);
76 bitvec_write_field(vector, writeIndex, *pui8, 1);
77 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
78 /* end add the bit value to protocol tree */
79 }
80 else if (pDescr->may_be_null)
81 {
82 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
83 }
84 else
85 {
86 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
87 }
88
89 pDescr++;
90 remaining_bits_len--;
91 bit_offset++;
92 break;
93 }
94
95 case CSN_NULL:
96 { /* Empty member! */
97 pDescr++;
98 break;
99 }
100
101 case CSN_UINT:
102 {
103 guint8 no_of_bits = (guint8) pDescr->i;
104
105 if (remaining_bits_len >= no_of_bits)
106 {
107 if (no_of_bits <= 8)
108 {
109 pui8 = pui8DATA(data, pDescr->offset);
110 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
111 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
112 }
113 else if (no_of_bits <= 16)
114 {
115 pui16 = pui16DATA(data, pDescr->offset);
116 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
117 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
118 }
119 else if (no_of_bits <= 32)
120 {
121 pui32 = pui32DATA(data, pDescr->offset);
122 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
123 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
124 }
125 else
126 {
127 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
128 }
129
130 remaining_bits_len -= no_of_bits;
131 bit_offset += no_of_bits;
132 }
133 else if (pDescr->may_be_null)
134 {
135 LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
136 }
137 else
138 {
139 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
140 }
141
142 pDescr++;
143 break;
144 }
145
146 case CSN_UINT_OFFSET:
147 {
148 guint8 no_of_bits = (guint8) pDescr->i;
149
150 if (remaining_bits_len >= no_of_bits)
151 {
152 if (no_of_bits <= 8)
153 {
154 pui8 = pui8DATA(data, pDescr->offset);
155 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
156 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
157 }
158 else if (no_of_bits <= 16)
159 {
160 pui16 = pui16DATA(data, pDescr->offset);
161 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
162 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
163 }
164 else if (no_of_bits <= 32)
165 {
166 pui32 = pui32DATA(data, pDescr->offset);
167 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
168 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
169 }
170 else
171 {
172 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
173 }
174 }
175 else
176 {
177 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
178 }
179
180 remaining_bits_len -= no_of_bits;
181 bit_offset += no_of_bits;
182 pDescr++;
183 break;
184 }
185
186 case CSN_UINT_LH:
187 {
188 guint8 no_of_bits = (guint8) pDescr->i;
189
190 if (remaining_bits_len >= no_of_bits)
191 {
192 if (no_of_bits <= 8)
193 {
194 pui8 = pui8DATA(data, pDescr->offset);
195 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
196 // TODO : Change get_masked_bits8()
197 *writeIndex -= no_of_bits;
198 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
199 *writeIndex -= no_of_bits;
200 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
201 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
202
203 }
204 else
205 {/* Maybe we should support more than 8 bits ? */
206 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
207 }
208 }
209 else
210 {
211 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
212 }
213
214 remaining_bits_len -= no_of_bits;
215 bit_offset += no_of_bits;
216 pDescr++;
217 break;
218 }
219
220 case CSN_UINT_ARRAY:
221 {
222 guint8 no_of_bits = (guint8) pDescr->i;
223 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
224
225 if (pDescr->value != 0)
226 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
227 nCount = *pui16DATA(data, nCount);
228 }
229
230 if (remaining_bits_len >= (no_of_bits * nCount))
231 {
232 if (no_of_bits <= 8)
233 {
234 pui8 = pui8DATA(data, pDescr->offset);
235 do
236 {
237 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
238 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
239 pui8++;
240 remaining_bits_len -= no_of_bits;
241 bit_offset += no_of_bits;
242 } while (--nCount > 0);
243 }
244 else if (no_of_bits <= 16)
245 {
246 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
247 }
248 else if (no_of_bits <= 32)
249 {
250 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
251 }
252 else
253 {
254 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
255 }
256 }
257 else
258 {
259 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
260 }
261 pDescr++;
262 break;
263 }
264
265 case CSN_VARIABLE_TARRAY_OFFSET:
266 case CSN_VARIABLE_TARRAY:
267 case CSN_TYPE_ARRAY:
268 {
269 gint16 Status;
270 csnStream_t arT = *ar;
271 gint16 nCount = pDescr->i;
272 guint16 nSize = (guint16)(gint32)pDescr->value;
273
274 pui8 = pui8DATA(data, pDescr->offset);
275 if (pDescr->type == CSN_VARIABLE_TARRAY)
276 { /* Count specified in field */
277 nCount = *pui8DATA(data, pDescr->i);
278 }
279 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
280 { /* Count specified in field */
281 nCount = *pui8DATA(data, pDescr->i);
282 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
283 }
284
285 while (nCount > 0)
286 { /* resulting array of length 0 is possible
287 * but no bits shall be read from bitstream
288 */
289
290 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
291 csnStreamInit(&arT, bit_offset, remaining_bits_len);
292 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
293 if (Status >= 0)
294 {
295 pui8 += nSize;
296 remaining_bits_len = arT.remaining_bits_len;
297 bit_offset = arT.bit_offset;
298
299 }
300 else
301 {
302 return Status;
303 }
304 nCount--;
305 }
306
307 pDescr++;
308 break;
309 }
310
311 case CSN_BITMAP:
312 { /* bitmap with given length. The result is left aligned! */
313 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
314
315 if (no_of_bits > 0)
316 {
317 if (no_of_bits > remaining_bits_len)
318 {
319 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
320 }
321
322 if (no_of_bits <= 32)
323 {
324 for(ib = 0; ib < 4; ib++)
325 {
326 pui8 = pui8DATA(data, pDescr->offset+ib);
327 bitvec_write_field(vector, writeIndex, *pui8, 8);
328 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
329 }
330 }
331 else if (no_of_bits <= 64)
332 {
333 for(ib = 0; ib < 8; ib++)
334 {
335 pui8 = pui8DATA(data, pDescr->offset+ib);
336 bitvec_write_field(vector, writeIndex, *pui8, 8);
337 LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
338 }
339 }
340 else
341 {
342 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
343 }
344
345 remaining_bits_len -= no_of_bits;
346 bit_offset += no_of_bits;
347 }
348 /* bitmap was successfully extracted or it was empty */
349
350 pDescr++;
351 break;
352 }
353
354 case CSN_TYPE:
355 {
356 gint16 Status;
357 csnStream_t arT = *ar;
358 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
359 csnStreamInit(&arT, bit_offset, remaining_bits_len);
360 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
361 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
362 if (Status >= 0)
363 {
364
365 remaining_bits_len = arT.remaining_bits_len;
366 bit_offset = arT.bit_offset;
367 pDescr++;
368 }
369 else
370 {
371 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
372 return Status;
373 }
374
375 break;
376 }
377
378 case CSN_CHOICE:
379 {
380 gint16 count = pDescr->i;
381 const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
382
383 /* Make sure that the list of choice items is not empty */
384 if (!count)
385 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
386 else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
387 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
388
389 /* Make sure that choice index is not out of range */
390 pui8 = pui8DATA(data, pDescr->offset);
391 if (*pui8 >= count)
392 return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
393
394 pChoice += *pui8;
395 guint8 no_of_bits = pChoice->bits;
396 guint8 value = pChoice->value;
397 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
398 bitvec_write_field(vector, writeIndex, value, no_of_bits);
399
400 CSN_DESCR descr[2];
401 gint16 Status;
402 csnStream_t arT = *ar;
403
404 descr[0] = pChoice->descr;
405 memset(&descr[1], 0x00, sizeof(CSN_DESCR));
406 descr[1].type = CSN_END;
407 bit_offset += no_of_bits;
408 remaining_bits_len -= no_of_bits;
409
410 csnStreamInit(&arT, bit_offset, remaining_bits_len);
411 Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
412
413 if (Status >= 0)
414 {
415 remaining_bits_len = arT.remaining_bits_len;
416 bit_offset = arT.bit_offset;
417 }
418 else
419 {
420 return Status;
421 }
422
423 pDescr++;
424 break;
425 }
426
427 case CSN_SERIALIZE:
428 {
429 StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
430 csnStream_t arT = *ar;
431 guint8 length_len = pDescr->i;
432 gint16 Status = -1;
433 unsigned lengthIndex;
434
435 // store writeIndex for length value (7 bit)
436 lengthIndex = *writeIndex;
437 *writeIndex += length_len;
438 bit_offset += length_len;
439 remaining_bits_len -= length_len;
440 arT.direction = 0;
441 csnStreamInit(&arT, bit_offset, remaining_bits_len);
442 Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
443
444 bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
445 LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
446
447 if (Status >= 0)
448 {
449 remaining_bits_len = arT.remaining_bits_len;
450 bit_offset = arT.bit_offset;
451 pDescr++;
452 }
453 else
454 {
455 // Has already been processed:
456 return Status;
457 }
458
459 break;
460 }
461
462 case CSN_UNION_LH:
463 case CSN_UNION:
464 {
465 gint16 Bits;
466 guint8 index;
467 gint16 count = pDescr->i;
468 const CSN_DESCR* pDescrNext = pDescr;
469
470 pDescrNext += count + 1; /* now this is next after the union */
471 if ((count <= 0) || (count > 16))
472 {
473 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
474 }
475
476 /* Now get the bits to extract the index */
477 Bits = ixBitsTab[count];
478 index = 0;
479
480 /* Assign UnionType */
481 pui8 = pui8DATA(data, pDescr->offset);
482 //read index from data and write to vector
483 bitvec_write_field(vector, writeIndex, *pui8, Bits);
484
485 //decode index
486 *writeIndex -= Bits;
487
488 while (Bits > 0)
489 {
490 index <<= 1;
491
492 if (CSN_UNION_LH == pDescr->type)
493 {
494 index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
495 }
496 else
497 {
498 index |= bitvec_read_field(vector, writeIndex, 1);
499 }
500
501 remaining_bits_len--;
502 bit_offset++;
503 Bits--;
504 }
505
506 *writeIndex -= Bits;
507 bitvec_write_field(vector, writeIndex, index, Bits);
508
509
510 /* script index to continue on, limited in case we do not have a power of 2 */
511 pDescr += (MIN(index + 1, count));
512 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
513
514 switch (pDescr->type)
515 { /* get the right element of the union based on computed index */
516
517 case CSN_BIT:
518 {
519 pui8 = pui8DATA(data, pDescr->offset);
520 bitvec_write_field(vector, writeIndex, *pui8, 1);
521 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
522 remaining_bits_len--;
523 bit_offset++;
524 pDescr++;
525 break;
526 }
527
528 case CSN_NULL:
529 { /* Empty member! */
530 pDescr++;
531 break;
532 }
533
534 case CSN_UINT:
535 {
536 guint8 no_of_bits = (guint8) pDescr->i;
537 if (remaining_bits_len >= no_of_bits)
538 {
539 if (no_of_bits <= 8)
540 {
541 pui8 = pui8DATA(data, pDescr->offset);
542 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
543 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
544 }
545 else if (no_of_bits <= 16)
546 {
547 pui16 = pui16DATA(data, pDescr->offset);
548 bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
549 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
550 }
551 else if (no_of_bits <= 32)
552 {
553 pui32 = pui32DATA(data, pDescr->offset);
554 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
555 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
556 }
557 else
558 {
559 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
560 }
561 }
562 else
563 {
564 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
565 }
566
567 remaining_bits_len -= no_of_bits;
568 bit_offset += no_of_bits;
569 pDescr++;
570 break;
571 }
572
573 case CSN_UINT_OFFSET:
574 {
575 guint8 no_of_bits = (guint8) pDescr->i;
576
577 if (remaining_bits_len >= no_of_bits)
578 {
579 if (no_of_bits <= 8)
580 {
581 pui8 = pui8DATA(data, pDescr->offset);
582 bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
583 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
584 }
585 else if (no_of_bits <= 16)
586 {
587 pui16 = pui16DATA(data, pDescr->offset);
588 bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
589 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
590 }
591 else if (no_of_bits <= 32)
592 {
593 pui32 = pui32DATA(data, pDescr->offset);
594 bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
595 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
596 }
597 else
598 {
599 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
600 }
601 }
602 else
603 {
604 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
605 }
606
607 remaining_bits_len -= no_of_bits;
608 bit_offset += no_of_bits;
609 pDescr++;
610 break;
611 }
612
613 case CSN_UINT_LH:
614 {
615 guint8 no_of_bits = (guint8) pDescr->i;
616
617 if (remaining_bits_len >= no_of_bits)
618 {
619 remaining_bits_len -= no_of_bits;
620 if (no_of_bits <= 8)
621 {
622 pui8 = pui8DATA(data, pDescr->offset);
623 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
624 // TODO : Change get_masked_bits8()
625 *writeIndex -= no_of_bits;
626 guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
627 *writeIndex -= no_of_bits;
628 bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
629 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
630
631 }
632 else
633 {/* Maybe we should support more than 8 bits ? */
634 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
635 }
636 }
637 else
638 {
639 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
640 }
641
642 remaining_bits_len -= no_of_bits;
643 bit_offset += no_of_bits;
644 pDescr++;
645 break;
646 }
647
648 case CSN_UINT_ARRAY:
649 {
650 guint8 no_of_bits = (guint8) pDescr->i;
651 guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
652
653 if (pDescr->value != 0)
654 { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
655 nCount = *pui16DATA(data, nCount);
656 }
657
658 if (remaining_bits_len >= (no_of_bits * nCount))
659 {
660 if (no_of_bits <= 8)
661 {
662 pui8 = pui8DATA(data, pDescr->offset);
663 do
664 {
665 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
666 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
667 pui8++;
668 remaining_bits_len -= no_of_bits;
669 bit_offset += no_of_bits;
670 } while (--nCount > 0);
671 }
672 else if (no_of_bits <= 16)
673 {
674 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
675 }
676 else if (no_of_bits <= 32)
677 {
678 return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
679 }
680 else
681 {
682 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
683 }
684 }
685 else
686 {
687 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
688 }
689 pDescr++;
690 break;
691 }
692
693 case CSN_VARIABLE_TARRAY_OFFSET:
694 case CSN_VARIABLE_TARRAY:
695 case CSN_TYPE_ARRAY:
696 {
697 gint16 Status;
698 csnStream_t arT = *ar;
699 gint16 nCount = pDescr->i;
700 guint16 nSize = (guint16)(gint32)pDescr->value;
701
702 pui8 = pui8DATA(data, pDescr->offset);
703 if (pDescr->type == CSN_VARIABLE_TARRAY)
704 { /* Count specified in field */
705 nCount = *pui8DATA(data, pDescr->i);
706 }
707 else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
708 { /* Count specified in field */
709 nCount = *pui8DATA(data, pDescr->i);
710 /* nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
711 }
712
713 while (nCount > 0)
714 { /* resulting array of length 0 is possible
715 * but no bits shall be read from bitstream
716 */
717
718 LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
719 csnStreamInit(&arT, bit_offset, remaining_bits_len);
720 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
721 if (Status >= 0)
722 {
723 pui8 += nSize;
724 remaining_bits_len = arT.remaining_bits_len;
725 bit_offset = arT.bit_offset;
726 }
727 else
728 {
729 return Status;
730 }
731 nCount--;
732 }
733
734 pDescr++;
735 break;
736 }
737
738 case CSN_BITMAP:
739 { /* bitmap with given length. The result is left aligned! */
740 guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
741
742 if (no_of_bits > 0)
743 {
744 if (no_of_bits > remaining_bits_len)
745 {
746 return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
747 }
748
749 if (no_of_bits <= 32)
750 {
751 pui32 = pui32DATA(data, pDescr->offset);
752 bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
753 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
754 }
755 else if (no_of_bits <= 64)
756 {
757 pui64 = pui64DATA(data, pDescr->offset);
758 bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
759 LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
760 }
761 else
762 {
763 return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
764 }
765
766 remaining_bits_len -= no_of_bits;
767 bit_offset += no_of_bits;
768 }
769 /* bitmap was successfully extracted or it was empty */
770
771 pDescr++;
772 break;
773 }
774
775 case CSN_TYPE:
776 {
777 gint16 Status;
778 csnStream_t arT = *ar;
779 LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
780 csnStreamInit(&arT, bit_offset, remaining_bits_len);
781 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
782 LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
783 if (Status >= 0)
784 {
785 remaining_bits_len = arT.remaining_bits_len;
786 bit_offset = arT.bit_offset;
787 pDescr++;
788 }
789 else
790 {
791 /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr); */
792 return Status;
793 }
794
795 break;
796 }
797
798 default:
799 { /* descriptions of union elements other than above are illegal */
800 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
801 }
802 }
803
804 pDescr = pDescrNext;
805 break;
806 }
807
808 case CSN_EXIST:
809 case CSN_EXIST_LH:
810 {
811 guint8 fExist;
812 unsigned exist = 0;
813 pui8 = pui8DATA(data, pDescr->offset);
814 exist = *pui8;
815 bitvec_write_field(vector, writeIndex, *pui8, 1);
816 writeIndex--;
817 if (CSN_EXIST_LH == pDescr->type)
818 {
819 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
820 }
821 else
822 {
823 fExist = bitvec_read_field(vector, writeIndex, 1);
824 }
825 writeIndex--;
826 bitvec_write_field(vector, writeIndex, fExist, 1);
827 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
828 remaining_bits_len--;
829 bit_offset++;
830 pDescr++;
831
832 if (!exist)
833 {
834 ar->remaining_bits_len = remaining_bits_len;
835 ar->bit_offset = bit_offset;
836 return remaining_bits_len;
837 }
838 break;
839 }
840
841 case CSN_NEXT_EXIST:
842 {
843 guint8 fExist;
844
845 pui8 = pui8DATA(data, pDescr->offset);
846
847 /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
848 if ((pDescr->may_be_null) && (remaining_bits_len == 0))
849 { /* no more bits to decode is fine here - end of message detected and allowed */
850
851 /* Skip i entries + this entry */
852 pDescr += pDescr->i + 1;
853
854 break;
855 }
856
857 bitvec_write_field(vector, writeIndex, *pui8, 1);
858 fExist = *pui8;
859 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
860
861 remaining_bits_len--;
862 bit_offset++;
863
864 if (fExist == 0)
865 { /* Skip 'i' entries */
866 pDescr += pDescr->i;
867 }
868
869 pDescr++;
870 break;
871 }
872
873 case CSN_NEXT_EXIST_LH:
874 {
875 guint8 fExist;
876 pui8 = pui8DATA(data, pDescr->offset);
877
878 /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
879 if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
880 { /* no more bits to decode is fine here - end of message detected and allowed */
881
882 /* skip 'i' entries + this entry */
883 pDescr += pDescr->i + 1;
884
885 /* set the data member to "not exist" */
886 //*pui8 = 0;
887 break;
888 }
889
890 /* the "regular" M_NEXT_EXIST_LH description element */
891 bitvec_write_field(vector, writeIndex, *pui8, 1);
892 writeIndex--;
893 fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
894 writeIndex--;
895 bitvec_write_field(vector, writeIndex, fExist, 1);
896 pui8++;
897
898 remaining_bits_len--;
899 bit_offset++;
900
901 if (fExist == 0)
902 { /* Skip 'i' entries */
903 pDescr += pDescr->i;
904 }
905 pDescr++;
906
907 break;
908 }
909
910 case CSN_VARIABLE_BITMAP_1:
911 { /* Bitmap from here and to the end of message */
912
913 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
914
915 /*no break -
916 * with a length set we have a regular variable length bitmap so we continue */
917 }
918 /* FALL THROUGH */
919 case CSN_VARIABLE_BITMAP:
920 { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
921 * <N: bit (5)> <bitmap: bit(N + offset)>
922 * Bit array with length (in bits) specified in parameter (pDescr->descr)
923 * The result is right aligned!
924 */
925 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
926
927 no_of_bits += pDescr->i; /* adjusted by offset */
928
929 if (no_of_bits > 0)
930 {
931
932 if (remaining_bits_len < 0)
933 {
934 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
935 }
936
937 { /* extract bits */
938 guint8* pui8 = pui8DATA(data, pDescr->offset);
939 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
940
941 if (nB1 > 0)
942 { /* take care of the first byte - it will be right aligned */
943 bitvec_write_field(vector, writeIndex, *pui8, nB1);
944 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
945 pui8++;
946 no_of_bits -= nB1;
947 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
948 remaining_bits_len -= nB1;
949 }
950
951 /* remaining no_of_bits is a multiple of 8 or 0 */
952 while (no_of_bits > 0)
953 {
954 bitvec_write_field(vector, writeIndex, *pui8, 8);
955 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
956 pui8++;
957 no_of_bits -= 8;
958 remaining_bits_len -= 8;
959 }
960 }
961 }
962 pDescr++;
963 break;
964 }
965
966 case CSN_LEFT_ALIGNED_VAR_BMP_1:
967 { /* Bitmap from here and to the end of message */
968
969 //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
970
971 /* no break -
972 * with a length set we have a regular left aligned variable length bitmap so we continue
973 */
974 }
975 /* FALL THROUGH */
976 case CSN_LEFT_ALIGNED_VAR_BMP:
977 { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
978 * <N: bit (5)> <bitmap: bit(N + offset)>
979 * bit array with length (in bits) specified in parameter (pDescr->descr)
980 */
981
982 gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
983
984 no_of_bits += pDescr->i;/* size adjusted by offset */
985
986 if (no_of_bits > 0)
987 {
988 remaining_bits_len -= no_of_bits;
989
990 if (remaining_bits_len < 0)
991 {
992 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
993 }
994
995 { /* extract bits */
996 guint8* pui8 = pui8DATA(data, pDescr->offset);
997 gint16 nB1 = no_of_bits & 0x07;/* no_of_bits Mod 8 */
998
999 while (no_of_bits > 0)
1000 {
1001 bitvec_write_field(vector, writeIndex, *pui8, 8);
1002 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1003 pui8++;
1004 no_of_bits -= 8;
1005 }
1006 if (nB1 > 0)
1007 {
1008 bitvec_write_field(vector, writeIndex, *pui8, nB1);
1009 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1010 pui8++;
1011 no_of_bits -= nB1;
1012 bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
1013 }
1014 }
1015
1016 }
1017
1018 /* bitmap was successfully extracted or it was empty */
1019 pDescr++;
1020 break;
1021 }
1022
1023 case CSN_PADDING_BITS:
1024 { /* Padding from here and to the end of message */
1025 LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
1026 guint8 filler = 0x2b;
1027 if (remaining_bits_len > 0)
1028 {
1029 while (remaining_bits_len > 0)
1030 {
1031 guint8 bits_to_handle = remaining_bits_len%8;
1032 if (bits_to_handle > 0)
1033 {
1034 /* section 11 of 44.060
1035 * The padding bits may be the 'null' string. Otherwise, the
1036 * padding bits starts with bit '0', followed by 'spare padding'
1037 * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
1038 */
1039 guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
1040 bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
1041 LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
1042 remaining_bits_len -= bits_to_handle;
1043 bit_offset += bits_to_handle;
1044 }
1045 else if (bits_to_handle == 0)
1046 {
1047 bitvec_write_field(vector, writeIndex, filler, 8);
1048 LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
1049 remaining_bits_len -= 8;
1050 bit_offset += 8;
1051 }
1052 }
1053 }
1054 if (remaining_bits_len < 0)
1055 {
1056 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1057 }
1058
1059 /* Padding was successfully extracted or it was empty */
1060 pDescr++;
1061 break;
1062 }
1063
1064 case CSN_VARIABLE_ARRAY:
1065 { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1066 * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1067 * Array with length specified in parameter:
1068 * <count: bit (x)>
1069 * <list: octet(count + offset)>
1070 */
1071 gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
1072
1073 count += pDescr->i; /* Adjusted by offset */
1074
1075 if (count > 0)
1076 {
1077 if (remaining_bits_len < 0)
1078 {
1079 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1080 }
1081
1082 pui8 = pui8DATA(data, pDescr->offset);
1083
1084 while (count > 0)
1085 {
1086 bitvec_write_field(vector, writeIndex, *pui8, 8);
1087 LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
1088 pui8++;
1089 bit_offset += 8;
1090 remaining_bits_len -= 8;
1091 count--;
1092 }
1093 }
1094
1095 pDescr++;
1096 break;
1097 }
1098
1099 case CSN_RECURSIVE_ARRAY:
1100 { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1101 * or more generally: <list> ::= { <tag> <element> <list> | <EndTag> }
1102 * where <element> ::= bit(value)
1103 * <tag> ::= 0 | 1
1104 * <EndTag> ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1105 * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1106 * REMARK: recursive way to specify an array but an iterative implementation!
1107 */
1108 gint16 no_of_bits = pDescr->i;
1109 guint8 ElementCount = 0;
1110 pui8 = pui8DATA(data, pDescr->offset);
1111 ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
1112 while (ElementCount > 0)
1113 { /* tag control shows existence of next list elements */
1114 bitvec_write_field(vector, writeIndex, Tag, 1);
1115 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
1116 bit_offset++;
1117 remaining_bits_len--;
1118
1119 /* extract and store no_of_bits long element from bitstream */
1120 bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
1121 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
1122 pui8++;
1123 ElementCount--;
1124
1125 if (remaining_bits_len < 0)
1126 {
1127 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1128 }
1129
1130 bit_offset += no_of_bits;
1131 remaining_bits_len -= no_of_bits;
1132 }
1133
1134 bitvec_write_field(vector, writeIndex, !Tag, 1);
1135 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
1136 bit_offset++;
1137 remaining_bits_len--;
1138
1139 pDescr++;
1140 break;
1141 }
1142
1143 case CSN_RECURSIVE_TARRAY:
1144 { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1145 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1146 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1147 */
1148 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
1149 guint8 ElementCount = 0;
1150 pui8 = pui8DATA(data, pDescr->offset);
1151 /* Store the counted number of elements of the array */
1152 ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
1153
1154 while (ElementCount > 0)
1155 { /* tag control shows existence of next list elements */
1156 bitvec_write_field(vector, writeIndex, Tag, 1);
1157 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
1158 bit_offset++;
1159
1160 remaining_bits_len--;
1161 ElementCount--;
1162
1163 { /* unpack the following data structure */
1164 csnStream_t arT = *ar;
1165 gint16 Status;
1166 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1167 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1168
1169 if (Status >= 0)
1170 { /* successful completion */
1171 pui8 += nSizeElement; /* -> to next data element */
1172 remaining_bits_len = arT.remaining_bits_len;
1173 bit_offset = arT.bit_offset;
1174 }
1175 else
1176 { /* something went awry */
1177 return Status;
1178 }
1179 }
1180
1181 if (remaining_bits_len < 0)
1182 {
1183 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1184 }
1185 }
1186
1187 bitvec_write_field(vector, writeIndex, !Tag, 1);
1188 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
1189 bit_offset++;
1190
1191 pDescr++;
1192 break;
1193 }
1194
1195 case CSN_RECURSIVE_TARRAY_2:
1196 { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1197
1198 Tag = REVERSED_TAG;
1199
1200 /* NO break -
1201 * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1202 */
1203 }
1204 /* FALL THROUGH */
1205 case CSN_RECURSIVE_TARRAY_1:
1206 { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1207 * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1208 * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
1209 */
1210 gint16 nSizeElement = (gint16)(gint32)pDescr->value;
1211 guint8 ElementCount = 0;
1212 guint8 ElementNum = 0;
1213 csnStream_t arT = *ar;
1214 gint16 Status;
1215
1216 pui8 = pui8DATA(data, pDescr->offset);
1217 /* Store the count of the array */
1218 ElementCount = *pui8DATA(data, pDescr->i);
1219 ElementNum = ElementCount;
1220
1221 while (ElementCount > 0)
1222 { /* get data element */
1223 if (ElementCount != ElementNum)
1224 {
1225 bitvec_write_field(vector, writeIndex, Tag, 1);
1226 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
1227 bit_offset++;
1228 remaining_bits_len--;
1229 }
1230 ElementCount--;
1231 LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
1232 csnStreamInit(&arT, bit_offset, remaining_bits_len);
1233 Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
1234 LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
1235 if (Status >= 0)
1236 { /* successful completion */
1237 pui8 += nSizeElement; /* -> to next */
1238 remaining_bits_len = arT.remaining_bits_len;
1239 bit_offset = arT.bit_offset;
1240 }
1241 else
1242 { /* something went awry */
1243 return Status;
1244 }
1245
1246 if (remaining_bits_len < 0)
1247 {
1248 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1249 }
1250
1251 }
1252 bitvec_write_field(vector, writeIndex, !Tag, 1);
1253 bit_offset++;
1254 remaining_bits_len--;
1255 Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1256 pDescr++;
1257 break;
1258 }
1259
1260 case CSN_FIXED:
1261 { /* Verify the fixed bits */
1262 guint8 no_of_bits = (guint8) pDescr->i;
1263 bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
1264 LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
1265 remaining_bits_len -= no_of_bits;
1266 bit_offset += no_of_bits;
1267 pDescr++;
1268 break;
1269 }
1270
1271 case CSN_CALLBACK:
1272 {
1273 guint16 no_of_bits;
1274 DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1275 LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
1276 no_of_bits = callback(vector, writeIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
1277 remaining_bits_len -= no_of_bits;
1278 bit_offset += no_of_bits;
1279 pDescr++;
1280 break;
1281 }
1282
1283 case CSN_TRAP_ERROR:
1284 {
1285 return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
1286 }
1287
1288 case CSN_END:
1289 {
1290 ar->remaining_bits_len = remaining_bits_len;
1291 ar->bit_offset = bit_offset;
1292 return remaining_bits_len;
1293 }
1294
1295 default:
1296 {
1297 assert(0);
1298 }
1299
1300 }
1301
1302 } while (remaining_bits_len >= 0);
1303
1304 return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
1305}