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