Change in osmo-pcu[master]: Split csn1.c into common, enc and dec files

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Tue Oct 19 12:48:36 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-pcu/+/25827 )


Change subject: Split csn1.c into common, enc and dec files
......................................................................

Split csn1.c into common, enc and dec files

The CSN1 encoder/decoder code is already lengthy and complex enough,
there's no need to keep it in the same file, specially because when
debugging, only is interested in one of the 2 functions, and they both
look really similar (long spaghetti switches).

This patch should also be ported to wireshark in order to keep similar
code structure. It is kept the same as much as possible here for the
same reason.

Change-Id: I7d1b1f7e6d7f89b052b3fd73a960419bb2673020
---
M debian/copyright
M src/Makefile.am
M src/csn1.c
M src/csn1.h
A src/csn1_dec.c
A src/csn1_enc.c
6 files changed, 2,718 insertions(+), 2,627 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/27/25827/1

diff --git a/debian/copyright b/debian/copyright
index 99ea408..4e9347e 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -81,7 +81,9 @@
 License:   GPL-2.0+
 
 Files:     src/csn1.h
-           src/csn1.cpp
+           src/csn1.c
+           src/csn1_dec.c
+           src/csn1_enc.c
            src/gsm_rlcmac.cpp
            src/gsm_rlcmac.h
 Copyright: 2011 Vincent Helfre
diff --git a/src/Makefile.am b/src/Makefile.am
index 08b3309..25fdab2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,6 +41,8 @@
 libgprs_la_SOURCES = \
 	gprs_debug.cpp \
 	csn1.c \
+	csn1_dec.c \
+	csn1_enc.c \
 	gsm_rlcmac.c \
 	gprs_bssgp_pcu.c \
 	gprs_bssgp_rim.c \
diff --git a/src/csn1.c b/src/csn1.c
index 2be0392..e165e92 100644
--- a/src/csn1.c
+++ b/src/csn1.c
@@ -1,4 +1,4 @@
-/* csn1.cpp
+/* csn1_enc.c
  * Routines for CSN1 dissection in wireshark.
  *
  * Copyright (C) 2011 Ivan Klyuchnikov
@@ -38,20 +38,10 @@
 #include <osmocom/core/logging.h>
 #include <osmocom/core/utils.h>
 
-#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
-#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
-#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
-#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
-#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
-/* used to tag existence of next element in variable length lists */
-#define STANDARD_TAG 1
-#define REVERSED_TAG 0
-
-static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
-
+const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
 
 /* Returns no_of_bits (up to 8) masked with 0x2B */
-static guint8
+guint8
 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset,  const gint no_of_bits)
 {
   static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
@@ -105,7 +95,7 @@
 };
 
 
-static gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
+gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
                                 const char* sz, gint16 err, const CSN_DESCR* pDescr)
 {
   /* Don't add trailing newline, top caller is responsible for appending it */
@@ -115,2615 +105,3 @@
             pDescr ? pDescr->sz : "-", *readIndex);
   return err;
 }
-
-#define ProcessError(readIndex, sz, err, pDescr) \
-        ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
-
-
-/**
- * ================================================================================================
- * Return TRUE if tag in bit stream indicates existence of next list element,
- * otherwise return FALSE.
- * Will work for tag values equal to both 0 and 1.
- * ================================================================================================
- */
-
-static gboolean
-existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
-{
-  int res = bitvec_get_bit_pos(vector, (*readIndex)++);
-  if (Tag == STANDARD_TAG)
-  {
-    return (res > 0);
-  }
-  return (res == 0);
-}
-
-
-gint16
-csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
-{
-  gint  remaining_bits_len = ar->remaining_bits_len;
-  gint  bit_offset         = ar->bit_offset;
-  guint8*  pui8 = NULL;
-  guint16* pui16;
-  guint32* pui32;
-  guint64* pui64;
-  guint8 Tag = STANDARD_TAG;
-  unsigned ib;
-
-  if (remaining_bits_len < 0)
-  {
-    return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-  }
-
-  do
-  {
-    switch (pDescr->type)
-    {
-      case CSN_BIT:
-      {
-        if (remaining_bits_len > 0)
-        {
-          pui8  = pui8DATA(data, pDescr->offset);
-	  *pui8 = bitvec_read_field(vector, readIndex, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          /* end add the bit value to protocol tree */
-        }
-        else if (pDescr->may_be_null)
-        {
-           pui8  = pui8DATA(data, pDescr->offset);
-           *pui8 = 0;
-           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        remaining_bits_len--;
-        bit_offset++;
-        break;
-      }
-
-      case CSN_NULL:
-      { /* Empty member! */
-        bit_offset += pDescr->i;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = ui8;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else if (no_of_bits <= 16)
-          {
-	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui16       = pui16DATA(data, pDescr->offset);
-            *pui16      = ui16;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-          }
-          else if (no_of_bits <= 32)
-          {
-	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui32       = pui32DATA(data, pDescr->offset);
-            *pui32      = ui32;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
-          }
-          else
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        else if (pDescr->may_be_null)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = 0;
-          }
-          else if (no_of_bits <= 16)
-          {
-            pui16      = pui16DATA(data, pDescr->offset);
-            *pui16     = 0;
-          }
-          else if (no_of_bits <= 32)
-          {
-            pui32      = pui32DATA(data, pDescr->offset);
-            *pui32     = 0;
-          }
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_OFFSET:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = ui8 + (guint8)pDescr->descr.value;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else if (no_of_bits <= 16)
-          {
-	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui16       = pui16DATA(data, pDescr->offset);
-            *pui16      = ui16 + (guint16)pDescr->descr.value;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-          }
-          else if (no_of_bits <= 32)
-          {
-	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-            pui32       = pui32DATA(data, pDescr->offset);
-            *pui32      = ui32 + (guint16)pDescr->descr.value;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-          }
-          else
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_LH:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-	    guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
-            pui8      = pui8DATA(data, pDescr->offset);
-            *pui8     = ui8;
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else
-          {/* Maybe we should support more than 8 bits ? */
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_ARRAY:
-      {
-        guint8  no_of_bits  = (guint8) pDescr->i;
-        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-        if (pDescr->value != 0)
-        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-          nCount = *pui16DATA(data, nCount);
-        }
-
-        if (remaining_bits_len >= (no_of_bits * nCount))
-        {
-          remaining_bits_len -= (no_of_bits*nCount);
-          if (no_of_bits <= 8)
-          {
-            pui8 = pui8DATA(data, pDescr->offset);
-            do
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              bit_offset += no_of_bits;
-            } while (--nCount > 0);
-          }
-          else if (no_of_bits <= 16)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else if (no_of_bits <= 32)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_TARRAY_OFFSET:
-      case CSN_VARIABLE_TARRAY:
-      case CSN_TYPE_ARRAY:
-      {
-        gint16      Status;
-        csnStream_t arT    = *ar;
-        gint16      nCount = pDescr->i;
-        guint16      nSize  = (guint16)(gint32)pDescr->value;
-
-        pui8 = pui8DATA(data, pDescr->offset);
-        if (pDescr->type == CSN_VARIABLE_TARRAY)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-        }
-        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
-        }
-
-        while (nCount > 0)
-        { /* resulting array of length 0 is possible
-           * but no bits shall be read from bitstream
-           */
-
-          LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-          if (Status >= 0)
-          {
-            pui8    += nSize;
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-          else
-          {
-            return Status;
-          }
-          nCount--;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_BITMAP:
-      { /* bitmap with given length. The result is left aligned! */
-        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-        if (no_of_bits > 0)
-        {
-          if (no_of_bits > remaining_bits_len)
-          {
-            return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          if (no_of_bits <= 32)
-          {
-            for(ib = 0; ib < 4; ib++)
-            {
-	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-              *pui8      = ui8;
-               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else if (no_of_bits <= 64)
-          {
-            for(ib = 0; ib < 8; ib++)
-            {
-	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-              *pui8      = ui8;
-               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else
-          {
-          	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
-          }
-
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        /* bitmap was successfully extracted or it was empty */
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_TYPE:
-      {
-        gint16      Status;
-        csnStream_t arT = *ar;
-        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
-        LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
-        if (Status >= 0)
-        {
-          remaining_bits_len  = arT.remaining_bits_len;
-          bit_offset          = arT.bit_offset;
-          pDescr++;
-        }
-        else
-        {
-          /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr);  */
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_CHOICE:
-      {
-        gint16 count = pDescr->i;
-        guint8 i     = 0;
-        CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
-
-        /* Make sure that the list of choice items is not empty */
-        if (!count)
-          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
-        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
-          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
-
-        while (count > 0)
-        {
-          guint8 no_of_bits = pChoice->bits;
-	  guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
-          if (value == pChoice->value)
-          {
-            CSN_DESCR   descr[2];
-            gint16      Status;
-            csnStream_t arT = *ar;
-
-            descr[0]      = pChoice->descr;
-            memset(&descr[1], 0x00, sizeof(CSN_DESCR));
-            descr[1].type = CSN_END;
-            pui8          = pui8DATA(data, pDescr->offset);
-            *pui8         = i;
-            LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
-            if (!pChoice->keep_bits) {
-              bit_offset += no_of_bits;
-              remaining_bits_len -= no_of_bits;
-            }
-
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	    Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
-
-            if (Status >= 0)
-            {
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-            }
-            else
-            {
-              return Status;
-            }
-            break;
-          }
-
-          *readIndex -= no_of_bits;
-          count--;
-          pChoice++;
-          i++;
-        }
-
-        /* Neither of the choice items matched => unknown value */
-        if (!count)
-          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_SERIALIZE:
-      {
-        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
-        csnStream_t          arT       = *ar;
-        guint8 length_len              = pDescr->i;
-        gint16               Status    = -1;
-
-	guint8 length = bitvec_read_field(vector, readIndex, length_len);
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
-        bit_offset += length_len;
-        remaining_bits_len -= length_len;
-
-        csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
-        arT.direction = 1;
-        LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
-	Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
-
-        if (Status >= 0)
-        {
-          if (length > 0) {
-            remaining_bits_len -= length;
-            bit_offset         += length;
-          } else {
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-
-          /* Skip bits not handled by serialize(), if any */
-          if (Status > 0) {
-            LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
-            *readIndex += Status;
-          }
-
-          pDescr++;
-        }
-        else
-        {
-          /* Has already been processed: */
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_UNION_LH:
-      case CSN_UNION:
-      {
-        gint16           Bits;
-        guint8           index;
-        gint16           count      = pDescr->i;
-        const CSN_DESCR* pDescrNext = pDescr;
-
-        pDescrNext += count + 1; /* now this is next after the union */
-        if ((count <= 0) || (count > 16))
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
-        }
-
-        /* Now get the bits to extract the index */
-        Bits = ixBitsTab[count];
-        index = 0;
-
-        while (Bits > 0)
-        {
-          index <<= 1;
-
-          if (CSN_UNION_LH == pDescr->type)
-          {
-            index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
-          }
-          else
-          {
-	    index |= bitvec_read_field(vector, readIndex, 1);
-          }
-          remaining_bits_len--;
-          bit_offset++;
-          Bits--;
-        }
-
-        /* Assign UnionType */
-        pui8  = pui8DATA(data, pDescr->offset);
-        *pui8 = index;
-
-
-        /* script index to continue on, limited in case we do not have a power of 2 */
-        pDescr += (MIN(index + 1, count));
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-        switch (pDescr->type)
-        { /* get the right element of the union based on computed index */
-
-          case CSN_BIT:
-          {
-            pui8  = pui8DATA(data, pDescr->offset);
-            *pui8 = 0x00;
-	    if (bitvec_read_field(vector, readIndex, 1) > 0)
-            {
-              *pui8 = 0x01;
-            }
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-            remaining_bits_len -= 1;
-            bit_offset++;
-            pDescr++;
-            break;
-          }
-
-          case CSN_NULL:
-          { /* Empty member! */
-            bit_offset += pDescr->i;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui8       = pui8DATA(data, pDescr->offset);
-                *pui8      = ui8;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else if (no_of_bits <= 16)
-              {
-		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui16        = pui16DATA(data, pDescr->offset);
-                *pui16       = ui16;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-              }
-              else if (no_of_bits <= 32)
-              {
-		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui32       = pui32DATA(data, pDescr->offset);
-                *pui32      = ui32;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else
-              {
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_OFFSET:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui8      = pui8DATA(data, pDescr->offset);
-                *pui8     = ui8 + (guint8)pDescr->descr.value;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else if (no_of_bits <= 16)
-              {
-		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui16       = pui16DATA(data, pDescr->offset);
-                *pui16      = ui16 + (guint16)pDescr->descr.value;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-              }
-              else if (no_of_bits <= 32)
-              {
-		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                pui32       = pui32DATA(data, pDescr->offset);
-                *pui32      = ui32 + (guint16)pDescr->descr.value;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else
-              {
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_LH:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-		guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
-                pui8      = pui8DATA(data, pDescr->offset);
-                *pui8     = ui8;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else
-              { /* Maybe we should support more than 8 bits ? */
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_ARRAY:
-          {
-            guint8  no_of_bits  = (guint8) pDescr->i;
-            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-            if (pDescr->value != 0)
-            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-              nCount = *pui16DATA(data, nCount);
-            }
-
-            if (remaining_bits_len >= (no_of_bits * nCount))
-            {
-              remaining_bits_len -= (no_of_bits * nCount);
-              if (no_of_bits <= 8)
-              {
-                pui8 = pui8DATA(data, pDescr->offset);
-
-                while (nCount > 0)
-                {
-		  *pui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-                  pui8++;
-                  bit_offset += no_of_bits;
-                  nCount--;
-                }
-              }
-              else if (no_of_bits <= 16)
-              {
-                pui16 = pui16DATA(data, pDescr->offset);
-
-                while (nCount > 0)
-                {
-		 *pui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
-                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-                  pui16++;
-                  bit_offset += no_of_bits;
-                  nCount--;
-                }
-              }
-              else if (no_of_bits <= 32)
-              { /* not supported */
-                return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
-              }
-              else
-              {
-                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_VARIABLE_TARRAY_OFFSET:
-          case CSN_VARIABLE_TARRAY:
-          case CSN_TYPE_ARRAY:
-          {
-            gint16      Status;
-            csnStream_t arT    = *ar;
-            guint16      nCount = (guint16) pDescr->i;
-            guint16      nSize  = (guint16)(guint32)pDescr->value;
-
-            pui8  = pui8DATA(data, pDescr->offset);
-
-            if (CSN_VARIABLE_TARRAY == pDescr->type)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-            }
-            else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-              nCount--; /* Offset 1 */
-            }
-
-            while (nCount--)    /* Changed to handle length = 0.  */
-            {
-              LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
-              csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	      Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-              if (Status >= 0)
-              {
-                pui8    += nSize;
-                remaining_bits_len = arT.remaining_bits_len;
-                bit_offset         = arT.bit_offset;
-              }
-              else
-              {
-                return Status;
-              }
-            }
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_BITMAP:
-          { /* bitmap with given length. The result is left aligned! */
-            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-            if (no_of_bits > 0)
-            {
-              if (no_of_bits > remaining_bits_len)
-              {
-                return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-              }
-
-              if (no_of_bits <= 32)
-              {
-		guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-                pui32       = pui32DATA(data, pDescr->offset);
-                *pui32      = ui32;
-              }
-              else if (no_of_bits <= 64)
-              {
-		guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
-                pui64       = pui64DATA(data, pDescr->offset);
-                *pui64      = ui64;
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
-              }
-              else
-              {
-              	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
-              }
-
-              remaining_bits_len -= no_of_bits;
-              bit_offset += no_of_bits;
-            }
-            /* bitmap was successfully extracted or it was empty */
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_TYPE:
-          {
-            gint16      Status;
-            csnStream_t arT = *ar;
-            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
-            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
-            if (Status >= 0)
-            {
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-              pDescr++;
-            }
-            else
-            { /* return error code Has already been processed:  */
-              return Status;
-            }
-
-            break;
-          }
-
-          default:
-          { /* descriptions of union elements other than above are illegal */
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
-          }
-        }
-
-        pDescr = pDescrNext;
-        break;
-      }
-
-      case CSN_EXIST:
-      case CSN_EXIST_LH:
-      {
-        guint8 fExist;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        if (CSN_EXIST_LH == pDescr->type)
-        {
-	  fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
-        }
-        else
-        {
-	  fExist = bitvec_read_field(vector, readIndex, 1);
-        }
-
-        *pui8 = fExist;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-        pDescr++;
-        bit_offset++;
-        remaining_bits_len -= 1;
-
-        if (!fExist)
-        {
-          ar->remaining_bits_len  = remaining_bits_len;
-          ar->bit_offset          = bit_offset;
-          return remaining_bits_len;
-        }
-
-        break;
-      }
-
-      case CSN_NEXT_EXIST:
-      {
-        guint8 fExist;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
-        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* Skip i entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          /* Set the data member to "not exist" */
-          *pui8 = 0;
-          break;
-        }
-
-        /* the "regular" M_NEXT_EXIST description element */
-
-        fExist = 0x00;
-	if (bitvec_read_field(vector, readIndex, 1))
-        {
-          fExist = 0x01;
-        }
-
-        *pui8     = fExist;
-        remaining_bits_len -= 1;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-        ++bit_offset;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_NEXT_EXIST_LH:
-      {
-        guint8 fExist;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
-        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* skip 'i' entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          /* set the data member to "not exist" */
-          *pui8 = 0;
-          break;
-        }
-
-        /* the "regular" M_NEXT_EXIST_LH description element */
-        fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
-        *pui8++   = fExist;
-        remaining_bits_len -= 1;
-
-        bit_offset++;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-        pDescr++;
-
-        break;
-      }
-
-      case CSN_VARIABLE_BITMAP_1:
-      { /* Bitmap from here and to the end of message */
-
-        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /*no break -
-         * with a length set we have a regular variable length bitmap so we continue */
-      }
-      /* FALL THROUGH */
-      case CSN_VARIABLE_BITMAP:
-      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * Bit array with length (in bits) specified in parameter (pDescr->descr)
-         * The result is right aligned!
-         */
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        no_of_bits += pDescr->i; /* adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-          remaining_bits_len -= no_of_bits;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
-
-            if (nB1 > 0)
-            { /* take care of the first byte - it will be right aligned */
-	      *pui8 = bitvec_read_field(vector, readIndex, nB1);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits  -= nB1;
-              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
-            }
-
-            /* remaining no_of_bits is a multiple of 8 or 0 */
-            while (no_of_bits > 0)
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-            }
-          }
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_LEFT_ALIGNED_VAR_BMP_1:
-      { /* Bitmap from here and to the end of message */
-
-        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /* no break -
-         * with a length set we have a regular left aligned variable length bitmap so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_LEFT_ALIGNED_VAR_BMP:
-      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * bit array with length (in bits) specified in parameter (pDescr->descr)
-         */
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
-
-        no_of_bits += pDescr->i;/* size adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-          remaining_bits_len -= no_of_bits;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-
-            while (no_of_bits >= 8)
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-            }
-            if (no_of_bits > 0)
-            {
-	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              bit_offset += no_of_bits;
-              no_of_bits = 0;
-            }
-          }
-        }
-
-        /* bitmap was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_PADDING_BITS:
-      { /* Padding from here and to the end of message */
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
-        if (remaining_bits_len > 0)
-        {
-          while (remaining_bits_len > 0)
-          {
-            guint bits_to_handle = remaining_bits_len%8;
-            if (bits_to_handle > 0)
-            {
-              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
-              remaining_bits_len -= bits_to_handle;
-              bit_offset += bits_to_handle;
-            }
-            else if (bits_to_handle == 0)
-            {
-              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
-              remaining_bits_len -= 8;
-              bit_offset += 8;
-            }
-          }
-        }
-        if (remaining_bits_len < 0)
-        {
-          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        /* Padding was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_ARRAY:
-      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
-         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * Array with length specified in parameter:
-         *  <count: bit (x)>
-         *  <list: octet(count + offset)>
-         */
-        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        count += pDescr->i; /* Adjusted by offset */
-
-        if (count > 0)
-        {
-          remaining_bits_len -= count * 8;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          pui8 = pui8DATA(data, pDescr->offset);
-
-          while (count > 0)
-          {
-	    *pui8 = bitvec_read_field(vector, readIndex, 8);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
-            pui8++;
-            bit_offset += 8;
-            count--;
-          }
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_ARRAY:
-      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
-         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
-         *  where <element> ::= bit(value)
-         *        <tag>     ::= 0 | 1
-         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
-         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * REMARK: recursive way to specify an array but an iterative implementation!
-         */
-        gint16 no_of_bits        = pDescr->i;
-        guint8  ElementCount = 0;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-	while (existNextElement(vector, readIndex, Tag))
-        { /* tag control shows existence of next list elements */
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
-          bit_offset++;
-          remaining_bits_len--;
-
-          /* extract and store no_of_bits long element from bitstream */
-	  *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          pui8++;
-          remaining_bits_len -= no_of_bits;
-          ElementCount++;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          bit_offset += no_of_bits;
-        }
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
-        /* existNextElement() returned FALSE, 1 bit consumed */
-        bit_offset++;
-        remaining_bits_len--;
-
-        /* Store the counted number of elements of the array */
-        *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY:
-      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
-         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
-         */
-        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
-        guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
-        guint8  ElementCount = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-	while (existNextElement(vector, readIndex, Tag))
-        { /* tag control shows existence of next list elements */
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
-          /* existNextElement() returned TRUE, 1 bit consumed */
-          bit_offset++;
-          remaining_bits_len--;
-          ElementCount++;
-
-          if (ElementCount > nSizeArray)
-          {
-            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
-          }
-
-          { /* unpack the following data structure */
-            csnStream_t arT = *ar;
-            gint16      Status;
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-
-            if (Status >= 0)
-            { /* successful completion */
-              pui8    += nSizeElement;  /* -> to next data element */
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-            }
-            else
-            { /* something went awry */
-              return Status;
-            }
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-        }
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
-
-        /* existNextElement() returned FALSE, 1 bit consumed */
-        remaining_bits_len--;
-        bit_offset++;
-
-        /* Store the counted number of elements of the array */
-        *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY_2:
-      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
-
-        Tag = REVERSED_TAG;
-
-        /* NO break -
-         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_RECURSIVE_TARRAY_1:
-      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
-         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
-         */
-        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
-        guint32     nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
-        guint8       ElementCount = 0;
-        csnStream_t arT          = *ar;
-        gboolean     EndOfList    = FALSE;
-        gint16      Status;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        do
-        { /* get data element */
-          ElementCount++;
-
-          if (ElementCount > nSizeArray)
-          {
-            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
-          }
-
-          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
-
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
-
-          if (Status >= 0)
-          { /* successful completion */
-            pui8    += nSizeElement;  /* -> to next */
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-          else
-          { /* something went awry */
-            return Status;
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          /* control of next element's tag */
-          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
-	  EndOfList         = !(existNextElement(vector, readIndex, Tag));
-
-          bit_offset++;
-          remaining_bits_len--; /* 1 bit consumed (tag) */
-        } while (!EndOfList);
-
-
-        /* Store the count of the array */
-        *pui8DATA(data, pDescr->i) = ElementCount;
-        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
-        pDescr++;
-        break;
-      }
-
-      case CSN_FIXED:
-      { /* Verify the fixed bits */
-        guint8  no_of_bits = (guint8) pDescr->i;
-        guint32 ui32;
-
-        if (no_of_bits <= 32)
-        {
-	  ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
-        }
-        else
-        {
-          return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
-        }
-        if (ui32 != (unsigned)(gint32)pDescr->offset)
-        {
-          return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
-        }
-
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
-        remaining_bits_len   -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_CALLBACK:
-      {
-        guint16  no_of_bits;
-        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
-        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
-        no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_TRAP_ERROR:
-      {
-        return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
-      }
-
-      case CSN_END:
-      {
-        ar->remaining_bits_len  = remaining_bits_len;
-        ar->bit_offset = bit_offset;
-        return remaining_bits_len;
-      }
-
-      default:
-      {
-        assert(0);
-      }
-
-
-    }
-
-  } while (remaining_bits_len >= 0);
-
-  return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-}
-
-
-
-
-gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
-{
-  gint  remaining_bits_len = ar->remaining_bits_len;
-  gint  bit_offset         = ar->bit_offset;
-  guint8*  pui8;
-  guint16* pui16;
-  guint32* pui32;
-  guint64* pui64;
-  unsigned ib;
-
-  guint8 Tag = STANDARD_TAG;
-
-  if (remaining_bits_len < 0)
-  {
-    return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-  }
-
-  do
-  {
-    switch (pDescr->type)
-    {
-      case CSN_BIT:
-      {
-        if (remaining_bits_len > 0)
-        {
-          pui8  = pui8DATA(data, pDescr->offset);
-	  bitvec_write_field(vector, writeIndex, *pui8, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          /* end add the bit value to protocol tree */
-        }
-        else if (pDescr->may_be_null)
-        {
-           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        remaining_bits_len--;
-        bit_offset++;
-        break;
-      }
-
-      case CSN_NULL:
-      { /* Empty member! */
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          }
-          else if (no_of_bits <= 16)
-          {
-            pui16       = pui16DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-          }
-          else if (no_of_bits <= 32)
-          {
-            pui32       = pui32DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-          }
-          else
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        else if (pDescr->may_be_null)
-        {
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_OFFSET:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
-          }
-          else if (no_of_bits <= 16)
-          {
-            pui16       = pui16DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
-          }
-          else if (no_of_bits <= 32)
-          {
-            pui32       = pui32DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
-          }
-          else
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_LH:
-      {
-        guint8 no_of_bits = (guint8) pDescr->i;
-
-        if (remaining_bits_len >= no_of_bits)
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8      = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-            // TODO : Change get_masked_bits8()
-            *writeIndex -= no_of_bits;
-            guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
-            *writeIndex -= no_of_bits;
-	    bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-          }
-          else
-          {/* Maybe we should support more than 8 bits ? */
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_UINT_ARRAY:
-      {
-        guint8  no_of_bits  = (guint8) pDescr->i;
-        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-        if (pDescr->value != 0)
-        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-          nCount = *pui16DATA(data, nCount);
-        }
-
-        if (remaining_bits_len >= (no_of_bits * nCount))
-        {
-          if (no_of_bits <= 8)
-          {
-            pui8 = pui8DATA(data, pDescr->offset);
-            do
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              remaining_bits_len -= no_of_bits;
-              bit_offset += no_of_bits;
-            } while (--nCount > 0);
-          }
-          else if (no_of_bits <= 16)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else if (no_of_bits <= 32)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-          }
-          else
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-          }
-        }
-        else
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_TARRAY_OFFSET:
-      case CSN_VARIABLE_TARRAY:
-      case CSN_TYPE_ARRAY:
-      {
-        gint16      Status;
-        csnStream_t arT    = *ar;
-        gint16      nCount = pDescr->i;
-        guint16     nSize  = (guint16)(gint32)pDescr->value;
-
-        pui8 = pui8DATA(data, pDescr->offset);
-        if (pDescr->type == CSN_VARIABLE_TARRAY)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-        }
-        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
-        { /* Count specified in field */
-          nCount = *pui8DATA(data, pDescr->i);
-	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
-        }
-
-        while (nCount > 0)
-        { /* resulting array of length 0 is possible
-           * but no bits shall be read from bitstream
-           */
-
-          LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-          if (Status >= 0)
-          {
-            pui8    += nSize;
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-
-          }
-          else
-          {
-            return Status;
-          }
-          nCount--;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_BITMAP:
-      { /* bitmap with given length. The result is left aligned! */
-        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-        if (no_of_bits > 0)
-        {
-          if (no_of_bits > remaining_bits_len)
-          {
-            return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          if (no_of_bits <= 32)
-          {
-            for(ib = 0; ib < 4; ib++)
-            {
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else if (no_of_bits <= 64)
-          {
-            for(ib = 0; ib < 8; ib++)
-            {
-              pui8      = pui8DATA(data, pDescr->offset+ib);
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
-            }
-          }
-          else
-          {
-          	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
-          }
-
-          remaining_bits_len -= no_of_bits;
-          bit_offset += no_of_bits;
-        }
-        /* bitmap was successfully extracted or it was empty */
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_TYPE:
-      {
-        gint16      Status;
-        csnStream_t arT = *ar;
-        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-        Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
-        LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
-        if (Status >= 0)
-        {
-
-          remaining_bits_len  = arT.remaining_bits_len;
-          bit_offset          = arT.bit_offset;
-          pDescr++;
-        }
-        else
-        {
-          /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_CHOICE:
-      {
-        gint16 count = pDescr->i;
-        const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
-
-        /* Make sure that the list of choice items is not empty */
-        if (!count)
-          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
-        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
-          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
-
-        /* Make sure that choice index is not out of range */
-        pui8 = pui8DATA(data, pDescr->offset);
-        if (*pui8 >= count)
-          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
-
-        pChoice += *pui8;
-        guint8 no_of_bits = pChoice->bits;
-        guint8 value = pChoice->value;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
-	bitvec_write_field(vector, writeIndex, value, no_of_bits);
-
-        CSN_DESCR   descr[2];
-        gint16      Status;
-        csnStream_t arT = *ar;
-
-        descr[0]      = pChoice->descr;
-        memset(&descr[1], 0x00, sizeof(CSN_DESCR));
-        descr[1].type = CSN_END;
-        bit_offset += no_of_bits;
-        remaining_bits_len -= no_of_bits;
-
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-        Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
-
-        if (Status >= 0)
-        {
-          remaining_bits_len = arT.remaining_bits_len;
-          bit_offset         = arT.bit_offset;
-        }
-        else
-        {
-          return Status;
-        }
-
-        pDescr++;
-        break;
-      }
-
-   case CSN_SERIALIZE:
-      {
-        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
-        csnStream_t          arT       = *ar;
-        guint8 length_len              = pDescr->i;
-        gint16               Status = -1;
-        unsigned lengthIndex;
-
-        // store writeIndex for length value (7 bit)
-        lengthIndex = *writeIndex;
-        *writeIndex += length_len;
-        bit_offset += length_len;
-        remaining_bits_len -= length_len;
-        arT.direction = 0;
-        csnStreamInit(&arT, bit_offset, remaining_bits_len);
-        Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
-
-	bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
-
-        if (Status >= 0)
-        {
-          remaining_bits_len = arT.remaining_bits_len;
-          bit_offset         = arT.bit_offset;
-          pDescr++;
-        }
-        else
-        {
-          // Has already been processed:
-          return Status;
-        }
-
-        break;
-      }
-
-      case CSN_UNION_LH:
-      case CSN_UNION:
-      {
-        gint16           Bits;
-        guint8           index;
-        gint16           count      = pDescr->i;
-        const CSN_DESCR* pDescrNext = pDescr;
-
-        pDescrNext += count + 1; /* now this is next after the union */
-        if ((count <= 0) || (count > 16))
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
-        }
-
-        /* Now get the bits to extract the index */
-        Bits = ixBitsTab[count];
-        index = 0;
-
-        /* Assign UnionType */
-        pui8  = pui8DATA(data, pDescr->offset);
-	//read index from data and write to vector
-	bitvec_write_field(vector, writeIndex, *pui8, Bits);
-
-	//decode index
-        *writeIndex -= Bits;
-
-        while (Bits > 0)
-        {
-          index <<= 1;
-
-          if (CSN_UNION_LH == pDescr->type)
-          {
-            index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
-          }
-          else
-          {
-	    index |= bitvec_read_field(vector, writeIndex, 1);
-          }
-
-          remaining_bits_len--;
-          bit_offset++;
-          Bits--;
-        }
-
-        *writeIndex -= Bits;
-	bitvec_write_field(vector, writeIndex, index, Bits);
-
-
-        /* script index to continue on, limited in case we do not have a power of 2 */
-        pDescr += (MIN(index + 1, count));
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
-
-        switch (pDescr->type)
-        { /* get the right element of the union based on computed index */
-
-          case CSN_BIT:
-          {
-            pui8  = pui8DATA(data, pDescr->offset);
-	    bitvec_write_field(vector, writeIndex, *pui8, 1);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-            remaining_bits_len--;
-            bit_offset++;
-            pDescr++;
-            break;
-          }
-
-          case CSN_NULL:
-          { /* Empty member! */
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-                pui8      = pui8DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              }
-              else if (no_of_bits <= 16)
-              {
-                pui16       = pui16DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
-              }
-              else if (no_of_bits <= 32)
-              {
-                pui32       = pui32DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_OFFSET:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              if (no_of_bits <= 8)
-              {
-                pui8      = pui8DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
-              }
-              else if (no_of_bits <= 16)
-              {
-                pui16       = pui16DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
-              }
-              else if (no_of_bits <= 32)
-              {
-                pui32       = pui32DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
-              }
-              else
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_LH:
-          {
-            guint8 no_of_bits = (guint8) pDescr->i;
-
-            if (remaining_bits_len >= no_of_bits)
-            {
-              remaining_bits_len -= no_of_bits;
-              if (no_of_bits <= 8)
-              {
-                pui8      = pui8DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-                // TODO : Change get_masked_bits8()
-                *writeIndex -= no_of_bits;
-                guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
-                *writeIndex -= no_of_bits;
-		bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-              }
-              else
-              {/* Maybe we should support more than 8 bits ? */
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-
-            remaining_bits_len -= no_of_bits;
-            bit_offset += no_of_bits;
-            pDescr++;
-            break;
-          }
-
-          case CSN_UINT_ARRAY:
-          {
-            guint8  no_of_bits  = (guint8) pDescr->i;
-            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
-
-            if (pDescr->value != 0)
-            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
-              nCount = *pui16DATA(data, nCount);
-            }
-
-            if (remaining_bits_len >= (no_of_bits * nCount))
-            {
-              if (no_of_bits <= 8)
-              {
-                pui8 = pui8DATA(data, pDescr->offset);
-                do
-                {
-		  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-                  pui8++;
-                  remaining_bits_len -= no_of_bits;
-                  bit_offset += no_of_bits;
-                } while (--nCount > 0);
-              }
-              else if (no_of_bits <= 16)
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-              }
-              else if (no_of_bits <= 32)
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
-              }
-              else
-              {
-                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
-              }
-            }
-            else
-            {
-              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-            }
-            pDescr++;
-            break;
-          }
-
-          case CSN_VARIABLE_TARRAY_OFFSET:
-          case CSN_VARIABLE_TARRAY:
-          case CSN_TYPE_ARRAY:
-          {
-            gint16      Status;
-            csnStream_t arT    = *ar;
-            gint16      nCount = pDescr->i;
-            guint16     nSize  = (guint16)(gint32)pDescr->value;
-
-            pui8 = pui8DATA(data, pDescr->offset);
-            if (pDescr->type == CSN_VARIABLE_TARRAY)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-            }
-            else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
-            { /* Count specified in field */
-              nCount = *pui8DATA(data, pDescr->i);
-              /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
-            }
-
-            while (nCount > 0)
-            { /* resulting array of length 0 is possible
-               * but no bits shall be read from bitstream
-               */
-
-              LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
-              csnStreamInit(&arT, bit_offset, remaining_bits_len);
-              Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-              if (Status >= 0)
-              {
-                pui8    += nSize;
-                remaining_bits_len = arT.remaining_bits_len;
-                bit_offset         = arT.bit_offset;
-              }
-              else
-              {
-                return Status;
-              }
-              nCount--;
-            }
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_BITMAP:
-          { /* bitmap with given length. The result is left aligned! */
-            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
-
-            if (no_of_bits > 0)
-            {
-              if (no_of_bits > remaining_bits_len)
-              {
-                return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-              }
-
-              if (no_of_bits <= 32)
-              {
-                pui32 = pui32DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
-              }
-              else if (no_of_bits <= 64)
-              {
-                pui64 = pui64DATA(data, pDescr->offset);
-		bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
-                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
-              }
-              else
-              {
-              	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
-              }
-
-              remaining_bits_len -= no_of_bits;
-              bit_offset += no_of_bits;
-            }
-            /* bitmap was successfully extracted or it was empty */
-
-            pDescr++;
-            break;
-          }
-
-          case CSN_TYPE:
-          {
-            gint16      Status;
-            csnStream_t arT = *ar;
-            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
-            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
-            if (Status >= 0)
-            {
-              remaining_bits_len  = arT.remaining_bits_len;
-              bit_offset          = arT.bit_offset;
-              pDescr++;
-            }
-            else
-            {
-              /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
-              return Status;
-            }
-
-            break;
-          }
-
-          default:
-          { /* descriptions of union elements other than above are illegal */
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
-          }
-        }
-
-        pDescr = pDescrNext;
-        break;
-      }
-
-      case CSN_EXIST:
-      case CSN_EXIST_LH:
-      {
-        guint8 fExist;
-        unsigned exist = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-        exist = *pui8;
-	bitvec_write_field(vector, writeIndex, *pui8, 1);
-        writeIndex--;
-        if (CSN_EXIST_LH == pDescr->type)
-        {
-          fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
-        }
-        else
-        {
-	  fExist = bitvec_read_field(vector, writeIndex, 1);
-        }
-        writeIndex--;
-	bitvec_write_field(vector, writeIndex, fExist, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
-        remaining_bits_len--;
-        bit_offset++;
-        pDescr++;
-
-        if (!exist)
-        {
-          ar->remaining_bits_len  = remaining_bits_len;
-          ar->bit_offset          = bit_offset;
-          return remaining_bits_len;
-        }
-        break;
-      }
-
-      case CSN_NEXT_EXIST:
-      {
-        guint8 fExist;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
-        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* Skip i entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          break;
-        }
-
-	bitvec_write_field(vector, writeIndex, *pui8, 1);
-        fExist = *pui8;
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-
-        remaining_bits_len--;
-        bit_offset++;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_NEXT_EXIST_LH:
-      {
-        guint8 fExist;
-        pui8  = pui8DATA(data, pDescr->offset);
-
-        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
-        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
-        { /* no more bits to decode is fine here - end of message detected and allowed */
-
-          /* skip 'i' entries + this entry */
-          pDescr += pDescr->i + 1;
-
-          /* set the data member to "not exist" */
-          //*pui8 = 0;
-          break;
-        }
-
-        /* the "regular" M_NEXT_EXIST_LH description element */
-	bitvec_write_field(vector, writeIndex, *pui8, 1);
-        writeIndex--;
-        fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
-        writeIndex--;
-	bitvec_write_field(vector, writeIndex, fExist, 1);
-        pui8++;
-
-        remaining_bits_len--;
-        bit_offset++;
-
-        if (fExist == 0)
-        { /* Skip 'i' entries */
-          pDescr += pDescr->i;
-        }
-        pDescr++;
-
-        break;
-      }
-
-      case CSN_VARIABLE_BITMAP_1:
-      { /* Bitmap from here and to the end of message */
-
-        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /*no break -
-         * with a length set we have a regular variable length bitmap so we continue */
-      }
-      /* FALL THROUGH */
-      case CSN_VARIABLE_BITMAP:
-      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * Bit array with length (in bits) specified in parameter (pDescr->descr)
-         * The result is right aligned!
-         */
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        no_of_bits += pDescr->i; /* adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
-
-            if (nB1 > 0)
-            { /* take care of the first byte - it will be right aligned */
-	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits  -= nB1;
-              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
-              remaining_bits_len -= nB1;
-            }
-
-            /* remaining no_of_bits is a multiple of 8 or 0 */
-            while (no_of_bits > 0)
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-              remaining_bits_len -= 8;
-            }
-          }
-        }
-        pDescr++;
-        break;
-      }
-
-      case CSN_LEFT_ALIGNED_VAR_BMP_1:
-      { /* Bitmap from here and to the end of message */
-
-        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
-
-        /* no break -
-         * with a length set we have a regular left aligned variable length bitmap so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_LEFT_ALIGNED_VAR_BMP:
-      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * <N: bit (5)> <bitmap: bit(N + offset)>
-         * bit array with length (in bits) specified in parameter (pDescr->descr)
-         */
-
-        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
-
-        no_of_bits += pDescr->i;/* size adjusted by offset */
-
-        if (no_of_bits > 0)
-        {
-          remaining_bits_len -= no_of_bits;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          { /* extract bits */
-            guint8* pui8 = pui8DATA(data, pDescr->offset);
-            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
-
-            while (no_of_bits > 0)
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits -= 8;
-            }
-            if (nB1 > 0)
-            {
-	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
-              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-              pui8++;
-              no_of_bits  -= nB1;
-              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
-            }
-          }
-
-        }
-
-        /* bitmap was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_PADDING_BITS:
-      { /* Padding from here and to the end of message */
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
-        guint8 filler = 0x2b;
-        if (remaining_bits_len > 0)
-        {
-          while (remaining_bits_len > 0)
-          {
-            guint8 bits_to_handle = remaining_bits_len%8;
-            if (bits_to_handle > 0)
-            {
-              /* section 11 of 44.060
-               * The padding bits may be the 'null' string. Otherwise, the
-               * padding bits starts with bit '0', followed by 'spare padding'
-               * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
-              */
-              guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
-	      bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
-              LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
-              remaining_bits_len -= bits_to_handle;
-              bit_offset += bits_to_handle;
-            }
-            else if (bits_to_handle == 0)
-            {
-	      bitvec_write_field(vector, writeIndex, filler, 8);
-              LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
-              remaining_bits_len -= 8;
-              bit_offset += 8;
-            }
-          }
-        }
-        if (remaining_bits_len < 0)
-        {
-          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-        }
-
-        /* Padding was successfully extracted or it was empty */
-        pDescr++;
-        break;
-      }
-
-      case CSN_VARIABLE_ARRAY:
-      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
-         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * Array with length specified in parameter:
-         *  <count: bit (x)>
-         *  <list: octet(count + offset)>
-         */
-        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
-
-        count += pDescr->i; /* Adjusted by offset */
-
-        if (count > 0)
-        {
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          pui8 = pui8DATA(data, pDescr->offset);
-
-          while (count > 0)
-          {
-	    bitvec_write_field(vector, writeIndex, *pui8, 8);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
-            pui8++;
-            bit_offset += 8;
-            remaining_bits_len -= 8;
-            count--;
-          }
-        }
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_ARRAY:
-      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
-         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
-         *  where <element> ::= bit(value)
-         *        <tag>     ::= 0 | 1
-         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
-         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
-         * REMARK: recursive way to specify an array but an iterative implementation!
-         */
-        gint16 no_of_bits        = pDescr->i;
-        guint8  ElementCount = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-        ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
-        while (ElementCount > 0)
-        { /* tag control shows existence of next list elements */
-	  bitvec_write_field(vector, writeIndex, Tag, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
-          bit_offset++;
-          remaining_bits_len--;
-
-          /* extract and store no_of_bits long element from bitstream */
-	  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
-          pui8++;
-          ElementCount--;
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-          bit_offset += no_of_bits;
-          remaining_bits_len -= no_of_bits;
-        }
-
-	bitvec_write_field(vector, writeIndex, !Tag, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
-        bit_offset++;
-        remaining_bits_len--;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY:
-      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
-         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
-         */
-        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
-        guint8  ElementCount = 0;
-        pui8  = pui8DATA(data, pDescr->offset);
-        /* Store the counted number of elements of the array */
-        ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
-
-        while (ElementCount > 0)
-        { /* tag control shows existence of next list elements */
-	  bitvec_write_field(vector, writeIndex, Tag, 1);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
-          bit_offset++;
-
-          remaining_bits_len--;
-          ElementCount--;
-
-          { /* unpack the following data structure */
-            csnStream_t arT = *ar;
-            gint16      Status;
-            csnStreamInit(&arT, bit_offset, remaining_bits_len);
-            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-
-            if (Status >= 0)
-            { /* successful completion */
-              pui8    += nSizeElement;  /* -> to next data element */
-              remaining_bits_len = arT.remaining_bits_len;
-              bit_offset         = arT.bit_offset;
-            }
-            else
-            { /* something went awry */
-              return Status;
-            }
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-        }
-
-	bitvec_write_field(vector, writeIndex, !Tag, 1);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
-        bit_offset++;
-
-        pDescr++;
-        break;
-      }
-
-      case CSN_RECURSIVE_TARRAY_2:
-      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
-
-        Tag = REVERSED_TAG;
-
-        /* NO break -
-         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
-         */
-      }
-      /* FALL THROUGH */
-      case CSN_RECURSIVE_TARRAY_1:
-      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
-         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
-         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
-         */
-        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
-        guint8      ElementCount = 0;
-        guint8      ElementNum   = 0;
-        csnStream_t arT          = *ar;
-        gint16      Status;
-
-        pui8  = pui8DATA(data, pDescr->offset);
-        /* Store the count of the array */
-        ElementCount = *pui8DATA(data, pDescr->i);
-        ElementNum = ElementCount;
-
-        while (ElementCount > 0)
-        { /* get data element */
-          if (ElementCount != ElementNum)
-          {
-	    bitvec_write_field(vector, writeIndex, Tag, 1);
-            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
-            bit_offset++;
-            remaining_bits_len--;
-          }
-          ElementCount--;
-          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
-          csnStreamInit(&arT, bit_offset, remaining_bits_len);
-          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
-          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
-          if (Status >= 0)
-          { /* successful completion */
-            pui8    += nSizeElement;  /* -> to next */
-            remaining_bits_len = arT.remaining_bits_len;
-            bit_offset         = arT.bit_offset;
-          }
-          else
-          { /* something went awry */
-            return Status;
-          }
-
-          if (remaining_bits_len < 0)
-          {
-            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-          }
-
-        }
-	bitvec_write_field(vector, writeIndex, !Tag, 1);
-        bit_offset++;
-        remaining_bits_len--;
-        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
-        pDescr++;
-        break;
-      }
-
-      case CSN_FIXED:
-      { /* Verify the fixed bits */
-        guint8  no_of_bits = (guint8) pDescr->i;
-	bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
-        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
-        remaining_bits_len   -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_CALLBACK:
-      {
-        guint16  no_of_bits;
-        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
-        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
-        no_of_bits = callback(vector, writeIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
-        remaining_bits_len -= no_of_bits;
-        bit_offset += no_of_bits;
-        pDescr++;
-        break;
-      }
-
-      case CSN_TRAP_ERROR:
-      {
-        return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
-      }
-
-      case CSN_END:
-      {
-        ar->remaining_bits_len  = remaining_bits_len;
-        ar->bit_offset = bit_offset;
-        return remaining_bits_len;
-      }
-
-      default:
-      {
-        assert(0);
-      }
-
-    }
-
-  } while (remaining_bits_len >= 0);
-
-  return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
-}
diff --git a/src/csn1.h b/src/csn1.h
index 761293d..d470228 100644
--- a/src/csn1.h
+++ b/src/csn1.h
@@ -592,4 +592,18 @@
 
 #define CSNDESCR(_FuncType) CSNDESCR_##_FuncType
 
+#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
+#define pui8DATA(_pv, _offset) ((guint8*) pvDATA(_pv, _offset))
+#define pui16DATA(_pv, _offset) ((guint16*) pvDATA(_pv, _offset))
+#define pui32DATA(_pv, _offset) ((guint32*) pvDATA(_pv, _offset))
+#define pui64DATA(_pv, _offset) ((guint64*) pvDATA(_pv, _offset))
+/* used to tag existence of next element in variable length lists */
+#define STANDARD_TAG 1
+#define REVERSED_TAG 0
+
+gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
+                                const char* sz, gint16 err, const CSN_DESCR* pDescr);
+#define ProcessError(readIndex, sz, err, pDescr) \
+        ProcessError_impl(__FILE__, __LINE__, readIndex, sz, err, pDescr)
+
 #endif /*_PACKET_CSN1_H_*/
diff --git a/src/csn1_dec.c b/src/csn1_dec.c
new file mode 100644
index 0000000..2d3f242
--- /dev/null
+++ b/src/csn1_dec.c
@@ -0,0 +1,1390 @@
+/* csn1_dec.c
+ * Routines for CSN1 dissection in wireshark.
+ *
+ * Copyright (C) 2011 Ivan Klyuchnikov
+ *
+ * By Vincent Helfre, based on original code by Jari Sassi
+ * with the gracious authorization of STE
+ * Copyright (c) 2011 ST-Ericsson
+ *
+ * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald at wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <string.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include "csn1.h"
+#include <gprs_debug.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+
+extern const unsigned char ixBitsTab[];
+guint8 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits);
+
+/**
+ * ================================================================================================
+ * Return TRUE if tag in bit stream indicates existence of next list element,
+ * otherwise return FALSE.
+ * Will work for tag values equal to both 0 and 1.
+ * ================================================================================================
+ */
+
+static gboolean
+existNextElement(struct bitvec *vector, unsigned *readIndex, guint8 Tag)
+{
+  int res = bitvec_get_bit_pos(vector, (*readIndex)++);
+  if (Tag == STANDARD_TAG)
+  {
+    return (res > 0);
+  }
+  return (res == 0);
+}
+
+
+gint16
+csnStreamDecoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *readIndex, void* data)
+{
+  gint  remaining_bits_len = ar->remaining_bits_len;
+  gint  bit_offset         = ar->bit_offset;
+  guint8*  pui8 = NULL;
+  guint16* pui16;
+  guint32* pui32;
+  guint64* pui64;
+  guint8 Tag = STANDARD_TAG;
+  unsigned ib;
+
+  if (remaining_bits_len < 0)
+  {
+    return ProcessError(readIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+  }
+
+  do
+  {
+    switch (pDescr->type)
+    {
+      case CSN_BIT:
+      {
+        if (remaining_bits_len > 0)
+        {
+          pui8  = pui8DATA(data, pDescr->offset);
+	  *pui8 = bitvec_read_field(vector, readIndex, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          /* end add the bit value to protocol tree */
+        }
+        else if (pDescr->may_be_null)
+        {
+           pui8  = pui8DATA(data, pDescr->offset);
+           *pui8 = 0;
+           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        remaining_bits_len--;
+        bit_offset++;
+        break;
+      }
+
+      case CSN_NULL:
+      { /* Empty member! */
+        bit_offset += pDescr->i;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = ui8;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else if (no_of_bits <= 16)
+          {
+	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui16       = pui16DATA(data, pDescr->offset);
+            *pui16      = ui16;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+          }
+          else if (no_of_bits <= 32)
+          {
+	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui32       = pui32DATA(data, pDescr->offset);
+            *pui32      = ui32;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%08x | ", pDescr->sz , *pui32);
+          }
+          else
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        else if (pDescr->may_be_null)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = 0;
+          }
+          else if (no_of_bits <= 16)
+          {
+            pui16      = pui16DATA(data, pDescr->offset);
+            *pui16     = 0;
+          }
+          else if (no_of_bits <= 32)
+          {
+            pui32      = pui32DATA(data, pDescr->offset);
+            *pui32     = 0;
+          }
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_OFFSET:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+	    guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = ui8 + (guint8)pDescr->descr.value;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else if (no_of_bits <= 16)
+          {
+	    guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui16       = pui16DATA(data, pDescr->offset);
+            *pui16      = ui16 + (guint16)pDescr->descr.value;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+          }
+          else if (no_of_bits <= 32)
+          {
+	    guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+            pui32       = pui32DATA(data, pDescr->offset);
+            *pui32      = ui32 + (guint16)pDescr->descr.value;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+          }
+          else
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_LH:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+	    guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
+            pui8      = pui8DATA(data, pDescr->offset);
+            *pui8     = ui8;
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else
+          {/* Maybe we should support more than 8 bits ? */
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_ARRAY:
+      {
+        guint8  no_of_bits  = (guint8) pDescr->i;
+        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+        if (pDescr->value != 0)
+        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+          nCount = *pui16DATA(data, nCount);
+        }
+
+        if (remaining_bits_len >= (no_of_bits * nCount))
+        {
+          remaining_bits_len -= (no_of_bits*nCount);
+          if (no_of_bits <= 8)
+          {
+            pui8 = pui8DATA(data, pDescr->offset);
+            do
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              bit_offset += no_of_bits;
+            } while (--nCount > 0);
+          }
+          else if (no_of_bits <= 16)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else if (no_of_bits <= 32)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_TARRAY_OFFSET:
+      case CSN_VARIABLE_TARRAY:
+      case CSN_TYPE_ARRAY:
+      {
+        gint16      Status;
+        csnStream_t arT    = *ar;
+        gint16      nCount = pDescr->i;
+        guint16      nSize  = (guint16)(gint32)pDescr->value;
+
+        pui8 = pui8DATA(data, pDescr->offset);
+        if (pDescr->type == CSN_VARIABLE_TARRAY)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+        }
+        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
+        }
+
+        while (nCount > 0)
+        { /* resulting array of length 0 is possible
+           * but no bits shall be read from bitstream
+           */
+
+          LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+          if (Status >= 0)
+          {
+            pui8    += nSize;
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+          else
+          {
+            return Status;
+          }
+          nCount--;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_BITMAP:
+      { /* bitmap with given length. The result is left aligned! */
+        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+        if (no_of_bits > 0)
+        {
+          if (no_of_bits > remaining_bits_len)
+          {
+            return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          if (no_of_bits <= 32)
+          {
+            for(ib = 0; ib < 4; ib++)
+            {
+	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+              *pui8      = ui8;
+               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else if (no_of_bits <= 64)
+          {
+            for(ib = 0; ib < 8; ib++)
+            {
+	      guint8 ui8 = bitvec_read_field(vector, readIndex, 8);
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+              *pui8      = ui8;
+               LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else
+          {
+          	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
+          }
+
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        /* bitmap was successfully extracted or it was empty */
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_TYPE:
+      {
+        gint16      Status;
+        csnStream_t arT = *ar;
+        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
+        LOGPC(DCSN1, LOGL_DEBUG, ": End %s | ", pDescr->sz);
+        if (Status >= 0)
+        {
+          remaining_bits_len  = arT.remaining_bits_len;
+          bit_offset          = arT.bit_offset;
+          pDescr++;
+        }
+        else
+        {
+          /* Has already been processed: ProcessError("csnStreamDecoder", Status, pDescr);  */
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_CHOICE:
+      {
+        gint16 count = pDescr->i;
+        guint8 i     = 0;
+        CSN_ChoiceElement_t* pChoice = (CSN_ChoiceElement_t*) pDescr->descr.ptr;
+
+        /* Make sure that the list of choice items is not empty */
+        if (!count)
+          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
+        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
+          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
+
+        while (count > 0)
+        {
+          guint8 no_of_bits = pChoice->bits;
+	  guint8 value = bitvec_read_field(vector, readIndex, no_of_bits);
+          if (value == pChoice->value)
+          {
+            CSN_DESCR   descr[2];
+            gint16      Status;
+            csnStream_t arT = *ar;
+
+            descr[0]      = pChoice->descr;
+            memset(&descr[1], 0x00, sizeof(CSN_DESCR));
+            descr[1].type = CSN_END;
+            pui8          = pui8DATA(data, pDescr->offset);
+            *pui8         = i;
+            LOGPC(DCSN1, LOGL_DEBUG, "Choice %s = %u | ", pDescr->sz , (unsigned)value);
+            if (!pChoice->keep_bits) {
+              bit_offset += no_of_bits;
+              remaining_bits_len -= no_of_bits;
+            }
+
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	    Status = csnStreamDecoder(&arT, descr, vector, readIndex, data);
+
+            if (Status >= 0)
+            {
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+            }
+            else
+            {
+              return Status;
+            }
+            break;
+          }
+
+          *readIndex -= no_of_bits;
+          count--;
+          pChoice++;
+          i++;
+        }
+
+        /* Neither of the choice items matched => unknown value */
+        if (!count)
+          return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_SERIALIZE:
+      {
+        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
+        csnStream_t          arT       = *ar;
+        guint8 length_len              = pDescr->i;
+        gint16               Status    = -1;
+
+	guint8 length = bitvec_read_field(vector, readIndex, length_len);
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , length);
+        bit_offset += length_len;
+        remaining_bits_len -= length_len;
+
+        csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len);
+        arT.direction = 1;
+        LOGPC(DCSN1, LOGL_DEBUG, "offset = %u | ", pDescr->offset);
+	Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset));
+
+        if (Status >= 0)
+        {
+          if (length > 0) {
+            remaining_bits_len -= length;
+            bit_offset         += length;
+          } else {
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+
+          /* Skip bits not handled by serialize(), if any */
+          if (Status > 0) {
+            LOGPC(DCSN1, LOGL_DEBUG, "skipped = %d | ", Status);
+            *readIndex += Status;
+          }
+
+          pDescr++;
+        }
+        else
+        {
+          /* Has already been processed: */
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_UNION_LH:
+      case CSN_UNION:
+      {
+        gint16           Bits;
+        guint8           index;
+        gint16           count      = pDescr->i;
+        const CSN_DESCR* pDescrNext = pDescr;
+
+        pDescrNext += count + 1; /* now this is next after the union */
+        if ((count <= 0) || (count > 16))
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
+        }
+
+        /* Now get the bits to extract the index */
+        Bits = ixBitsTab[count];
+        index = 0;
+
+        while (Bits > 0)
+        {
+          index <<= 1;
+
+          if (CSN_UNION_LH == pDescr->type)
+          {
+            index |= get_masked_bits8(vector, readIndex, bit_offset, 1);
+          }
+          else
+          {
+	    index |= bitvec_read_field(vector, readIndex, 1);
+          }
+          remaining_bits_len--;
+          bit_offset++;
+          Bits--;
+        }
+
+        /* Assign UnionType */
+        pui8  = pui8DATA(data, pDescr->offset);
+        *pui8 = index;
+
+
+        /* script index to continue on, limited in case we do not have a power of 2 */
+        pDescr += (MIN(index + 1, count));
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+        switch (pDescr->type)
+        { /* get the right element of the union based on computed index */
+
+          case CSN_BIT:
+          {
+            pui8  = pui8DATA(data, pDescr->offset);
+            *pui8 = 0x00;
+	    if (bitvec_read_field(vector, readIndex, 1) > 0)
+            {
+              *pui8 = 0x01;
+            }
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+            remaining_bits_len -= 1;
+            bit_offset++;
+            pDescr++;
+            break;
+          }
+
+          case CSN_NULL:
+          { /* Empty member! */
+            bit_offset += pDescr->i;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui8       = pui8DATA(data, pDescr->offset);
+                *pui8      = ui8;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else if (no_of_bits <= 16)
+              {
+		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui16        = pui16DATA(data, pDescr->offset);
+                *pui16       = ui16;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+              }
+              else if (no_of_bits <= 32)
+              {
+		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui32       = pui32DATA(data, pDescr->offset);
+                *pui32      = ui32;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else
+              {
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_OFFSET:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+		guint8 ui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui8      = pui8DATA(data, pDescr->offset);
+                *pui8     = ui8 + (guint8)pDescr->descr.value;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else if (no_of_bits <= 16)
+              {
+		guint16 ui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui16       = pui16DATA(data, pDescr->offset);
+                *pui16      = ui16 + (guint16)pDescr->descr.value;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+              }
+              else if (no_of_bits <= 32)
+              {
+		guint32 ui32 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                pui32       = pui32DATA(data, pDescr->offset);
+                *pui32      = ui32 + (guint16)pDescr->descr.value;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else
+              {
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_LH:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+		guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits);
+                pui8      = pui8DATA(data, pDescr->offset);
+                *pui8     = ui8;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else
+              { /* Maybe we should support more than 8 bits ? */
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_ARRAY:
+          {
+            guint8  no_of_bits  = (guint8) pDescr->i;
+            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+            if (pDescr->value != 0)
+            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+              nCount = *pui16DATA(data, nCount);
+            }
+
+            if (remaining_bits_len >= (no_of_bits * nCount))
+            {
+              remaining_bits_len -= (no_of_bits * nCount);
+              if (no_of_bits <= 8)
+              {
+                pui8 = pui8DATA(data, pDescr->offset);
+
+                while (nCount > 0)
+                {
+		  *pui8 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+                  pui8++;
+                  bit_offset += no_of_bits;
+                  nCount--;
+                }
+              }
+              else if (no_of_bits <= 16)
+              {
+                pui16 = pui16DATA(data, pDescr->offset);
+
+                while (nCount > 0)
+                {
+		 *pui16 = bitvec_read_field(vector, readIndex,  no_of_bits);
+                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+                  pui16++;
+                  bit_offset += no_of_bits;
+                  nCount--;
+                }
+              }
+              else if (no_of_bits <= 32)
+              { /* not supported */
+                return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
+              }
+              else
+              {
+                return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_VARIABLE_TARRAY_OFFSET:
+          case CSN_VARIABLE_TARRAY:
+          case CSN_TYPE_ARRAY:
+          {
+            gint16      Status;
+            csnStream_t arT    = *ar;
+            guint16      nCount = (guint16) pDescr->i;
+            guint16      nSize  = (guint16)(guint32)pDescr->value;
+
+            pui8  = pui8DATA(data, pDescr->offset);
+
+            if (CSN_VARIABLE_TARRAY == pDescr->type)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+            }
+            else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+              nCount--; /* Offset 1 */
+            }
+
+            while (nCount--)    /* Changed to handle length = 0.  */
+            {
+              LOGPC(DCSN1, LOGL_DEBUG, "%s | ", pDescr->sz);
+              csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	      Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+              if (Status >= 0)
+              {
+                pui8    += nSize;
+                remaining_bits_len = arT.remaining_bits_len;
+                bit_offset         = arT.bit_offset;
+              }
+              else
+              {
+                return Status;
+              }
+            }
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_BITMAP:
+          { /* bitmap with given length. The result is left aligned! */
+            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+            if (no_of_bits > 0)
+            {
+              if (no_of_bits > remaining_bits_len)
+              {
+                return ProcessError(readIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+              }
+
+              if (no_of_bits <= 32)
+              {
+		guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+                pui32       = pui32DATA(data, pDescr->offset);
+                *pui32      = ui32;
+              }
+              else if (no_of_bits <= 64)
+              {
+		guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits);
+                pui64       = pui64DATA(data, pDescr->offset);
+                *pui64      = ui64;
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
+              }
+              else
+              {
+              	return ProcessError(readIndex,"csnStreamDecoder NOT IMPLEMENTED", 999, pDescr);
+              }
+
+              remaining_bits_len -= no_of_bits;
+              bit_offset += no_of_bits;
+            }
+            /* bitmap was successfully extracted or it was empty */
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_TYPE:
+          {
+            gint16      Status;
+            csnStream_t arT = *ar;
+            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset));
+            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
+            if (Status >= 0)
+            {
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+              pDescr++;
+            }
+            else
+            { /* return error code Has already been processed:  */
+              return Status;
+            }
+
+            break;
+          }
+
+          default:
+          { /* descriptions of union elements other than above are illegal */
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_IN_SCRIPT, pDescr);
+          }
+        }
+
+        pDescr = pDescrNext;
+        break;
+      }
+
+      case CSN_EXIST:
+      case CSN_EXIST_LH:
+      {
+        guint8 fExist;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        if (CSN_EXIST_LH == pDescr->type)
+        {
+	  fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
+        }
+        else
+        {
+	  fExist = bitvec_read_field(vector, readIndex, 1);
+        }
+
+        *pui8 = fExist;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+        pDescr++;
+        bit_offset++;
+        remaining_bits_len -= 1;
+
+        if (!fExist)
+        {
+          ar->remaining_bits_len  = remaining_bits_len;
+          ar->bit_offset          = bit_offset;
+          return remaining_bits_len;
+        }
+
+        break;
+      }
+
+      case CSN_NEXT_EXIST:
+      {
+        guint8 fExist;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
+        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* Skip i entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          /* Set the data member to "not exist" */
+          *pui8 = 0;
+          break;
+        }
+
+        /* the "regular" M_NEXT_EXIST description element */
+
+        fExist = 0x00;
+	if (bitvec_read_field(vector, readIndex, 1))
+        {
+          fExist = 0x01;
+        }
+
+        *pui8     = fExist;
+        remaining_bits_len -= 1;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+        ++bit_offset;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_NEXT_EXIST_LH:
+      {
+        guint8 fExist;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
+        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* skip 'i' entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          /* set the data member to "not exist" */
+          *pui8 = 0;
+          break;
+        }
+
+        /* the "regular" M_NEXT_EXIST_LH description element */
+        fExist = get_masked_bits8(vector, readIndex, bit_offset, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)fExist);
+        *pui8++   = fExist;
+        remaining_bits_len -= 1;
+
+        bit_offset++;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+        pDescr++;
+
+        break;
+      }
+
+      case CSN_VARIABLE_BITMAP_1:
+      { /* Bitmap from here and to the end of message */
+
+        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /*no break -
+         * with a length set we have a regular variable length bitmap so we continue */
+      }
+      /* FALL THROUGH */
+      case CSN_VARIABLE_BITMAP:
+      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * Bit array with length (in bits) specified in parameter (pDescr->descr)
+         * The result is right aligned!
+         */
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        no_of_bits += pDescr->i; /* adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+          remaining_bits_len -= no_of_bits;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
+
+            if (nB1 > 0)
+            { /* take care of the first byte - it will be right aligned */
+	      *pui8 = bitvec_read_field(vector, readIndex, nB1);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits  -= nB1;
+              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
+            }
+
+            /* remaining no_of_bits is a multiple of 8 or 0 */
+            while (no_of_bits > 0)
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+            }
+          }
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_LEFT_ALIGNED_VAR_BMP_1:
+      { /* Bitmap from here and to the end of message */
+
+        *pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /* no break -
+         * with a length set we have a regular left aligned variable length bitmap so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_LEFT_ALIGNED_VAR_BMP:
+      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * bit array with length (in bits) specified in parameter (pDescr->descr)
+         */
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
+
+        no_of_bits += pDescr->i;/* size adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+          remaining_bits_len -= no_of_bits;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+
+            while (no_of_bits >= 8)
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+            }
+            if (no_of_bits > 0)
+            {
+	      *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              bit_offset += no_of_bits;
+              no_of_bits = 0;
+            }
+          }
+        }
+
+        /* bitmap was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_PADDING_BITS:
+      { /* Padding from here and to the end of message */
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
+        if (remaining_bits_len > 0)
+        {
+          while (remaining_bits_len > 0)
+          {
+            guint bits_to_handle = remaining_bits_len%8;
+            if (bits_to_handle > 0)
+            {
+              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, bits_to_handle));
+              remaining_bits_len -= bits_to_handle;
+              bit_offset += bits_to_handle;
+            }
+            else if (bits_to_handle == 0)
+            {
+              LOGPC(DCSN1, LOGL_DEBUG, "%d|", bitvec_get_uint(vector, 8));
+              remaining_bits_len -= 8;
+              bit_offset += 8;
+            }
+          }
+        }
+        if (remaining_bits_len < 0)
+        {
+          return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        /* Padding was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_ARRAY:
+      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
+         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * Array with length specified in parameter:
+         *  <count: bit (x)>
+         *  <list: octet(count + offset)>
+         */
+        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        count += pDescr->i; /* Adjusted by offset */
+
+        if (count > 0)
+        {
+          remaining_bits_len -= count * 8;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          pui8 = pui8DATA(data, pDescr->offset);
+
+          while (count > 0)
+          {
+	    *pui8 = bitvec_read_field(vector, readIndex, 8);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
+            pui8++;
+            bit_offset += 8;
+            count--;
+          }
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_ARRAY:
+      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
+         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
+         *  where <element> ::= bit(value)
+         *        <tag>     ::= 0 | 1
+         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
+         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * REMARK: recursive way to specify an array but an iterative implementation!
+         */
+        gint16 no_of_bits        = pDescr->i;
+        guint8  ElementCount = 0;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+	while (existNextElement(vector, readIndex, Tag))
+        { /* tag control shows existence of next list elements */
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
+          bit_offset++;
+          remaining_bits_len--;
+
+          /* extract and store no_of_bits long element from bitstream */
+	  *pui8 = bitvec_read_field(vector, readIndex, no_of_bits);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          pui8++;
+          remaining_bits_len -= no_of_bits;
+          ElementCount++;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          bit_offset += no_of_bits;
+        }
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
+        /* existNextElement() returned FALSE, 1 bit consumed */
+        bit_offset++;
+        remaining_bits_len--;
+
+        /* Store the counted number of elements of the array */
+        *pui8DATA(data, (gint16)pDescr->descr.value) = ElementCount;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY:
+      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
+         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
+         */
+        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
+        guint32 nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
+        guint8  ElementCount = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+	while (existNextElement(vector, readIndex, Tag))
+        { /* tag control shows existence of next list elements */
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = Exist | ", pDescr->sz);
+          /* existNextElement() returned TRUE, 1 bit consumed */
+          bit_offset++;
+          remaining_bits_len--;
+          ElementCount++;
+
+          if (ElementCount > nSizeArray)
+          {
+            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
+          }
+
+          { /* unpack the following data structure */
+            csnStream_t arT = *ar;
+            gint16      Status;
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	    Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+
+            if (Status >= 0)
+            { /* successful completion */
+              pui8    += nSizeElement;  /* -> to next data element */
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+            }
+            else
+            { /* something went awry */
+              return Status;
+            }
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+        }
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %d | ", pDescr->sz , bitvec_get_uint(vector, 1));
+
+        /* existNextElement() returned FALSE, 1 bit consumed */
+        remaining_bits_len--;
+        bit_offset++;
+
+        /* Store the counted number of elements of the array */
+        *pui8DATA(data, (gint16)(gint32)pDescr->i) = ElementCount;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY_2:
+      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
+
+        Tag = REVERSED_TAG;
+
+        /* NO break -
+         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_RECURSIVE_TARRAY_1:
+      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
+         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), (void_fn_t)ElementsOf(((_STRUCT*)0)->_MEMBER)}
+         */
+        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
+        guint32     nSizeArray = (guint32)((uintptr_t)pDescr->aux_fn);
+        guint8       ElementCount = 0;
+        csnStream_t arT          = *ar;
+        gboolean     EndOfList    = FALSE;
+        gint16      Status;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        do
+        { /* get data element */
+          ElementCount++;
+
+          if (ElementCount > nSizeArray)
+          {
+            LOGPC(DCSN1, LOGL_ERROR, "error: %s: too many elements (>%u) in recursive array. Increase its size! } |", pDescr->sz, nSizeArray);
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_STREAM_NOT_SUPPORTED, pDescr);
+          }
+
+          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
+
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+	  Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8);
+
+          if (Status >= 0)
+          { /* successful completion */
+            pui8    += nSizeElement;  /* -> to next */
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+          else
+          { /* something went awry */
+            return Status;
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          /* control of next element's tag */
+          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
+	  EndOfList         = !(existNextElement(vector, readIndex, Tag));
+
+          bit_offset++;
+          remaining_bits_len--; /* 1 bit consumed (tag) */
+        } while (!EndOfList);
+
+
+        /* Store the count of the array */
+        *pui8DATA(data, pDescr->i) = ElementCount;
+        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
+        pDescr++;
+        break;
+      }
+
+      case CSN_FIXED:
+      { /* Verify the fixed bits */
+        guint8  no_of_bits = (guint8) pDescr->i;
+        guint32 ui32;
+
+        if (no_of_bits <= 32)
+        {
+	  ui32 = bitvec_read_field(vector, readIndex, no_of_bits);
+        }
+        else
+        {
+          return ProcessError(readIndex,"no_of_bits > 32", -1, pDescr);
+        }
+        if (ui32 != (unsigned)(gint32)pDescr->offset)
+        {
+          return ProcessError(readIndex,"csnStreamDecoder FIXED value does not match", -1, pDescr);
+        }
+
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)ui32);
+        remaining_bits_len   -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_CALLBACK:
+      {
+        guint16  no_of_bits;
+        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
+        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
+        no_of_bits = callback(vector, readIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_TRAP_ERROR:
+      {
+        return ProcessError(readIndex,"csnStreamDecoder", pDescr->i, pDescr);
+      }
+
+      case CSN_END:
+      {
+        ar->remaining_bits_len  = remaining_bits_len;
+        ar->bit_offset = bit_offset;
+        return remaining_bits_len;
+      }
+
+      default:
+      {
+        assert(0);
+      }
+
+
+    }
+
+  } while (remaining_bits_len >= 0);
+
+  return ProcessError(readIndex,"csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+}
diff --git a/src/csn1_enc.c b/src/csn1_enc.c
new file mode 100644
index 0000000..5518d06
--- /dev/null
+++ b/src/csn1_enc.c
@@ -0,0 +1,1305 @@
+/* csn1_enc.c
+ * Routines for CSN1 dissection in wireshark.
+ *
+ * Copyright (C) 2011 Ivan Klyuchnikov
+ *
+ * By Vincent Helfre, based on original code by Jari Sassi
+ * with the gracious authorization of STE
+ * Copyright (c) 2011 ST-Ericsson
+ *
+ * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald at wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <string.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include "csn1.h"
+#include <gprs_debug.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+
+extern const unsigned char ixBitsTab[];
+guint8 get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits);
+
+/**
+ * ================================================================================================
+ * set initial/start values in help data structure used for packing/unpacking operation
+ * ================================================================================================
+ */
+
+gint16 csnStreamEncoder(csnStream_t* ar, const CSN_DESCR* pDescr, struct bitvec *vector, unsigned *writeIndex, void* data)
+{
+  gint  remaining_bits_len = ar->remaining_bits_len;
+  gint  bit_offset         = ar->bit_offset;
+  guint8*  pui8;
+  guint16* pui16;
+  guint32* pui32;
+  guint64* pui64;
+  unsigned ib;
+
+  guint8 Tag = STANDARD_TAG;
+
+  if (remaining_bits_len < 0)
+  {
+    return ProcessError(writeIndex, __func__, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+  }
+
+  do
+  {
+    switch (pDescr->type)
+    {
+      case CSN_BIT:
+      {
+        if (remaining_bits_len > 0)
+        {
+          pui8  = pui8DATA(data, pDescr->offset);
+	  bitvec_write_field(vector, writeIndex, *pui8, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          /* end add the bit value to protocol tree */
+        }
+        else if (pDescr->may_be_null)
+        {
+           LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        remaining_bits_len--;
+        bit_offset++;
+        break;
+      }
+
+      case CSN_NULL:
+      { /* Empty member! */
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          }
+          else if (no_of_bits <= 16)
+          {
+            pui16       = pui16DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+          }
+          else if (no_of_bits <= 32)
+          {
+            pui32       = pui32DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+          }
+          else
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        else if (pDescr->may_be_null)
+        {
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = NULL | ", pDescr->sz);
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_OFFSET:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
+          }
+          else if (no_of_bits <= 16)
+          {
+            pui16       = pui16DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
+          }
+          else if (no_of_bits <= 32)
+          {
+            pui32       = pui32DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
+          }
+          else
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_LH:
+      {
+        guint8 no_of_bits = (guint8) pDescr->i;
+
+        if (remaining_bits_len >= no_of_bits)
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8      = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+            // TODO : Change get_masked_bits8()
+            *writeIndex -= no_of_bits;
+            guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
+            *writeIndex -= no_of_bits;
+	    bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+          }
+          else
+          {/* Maybe we should support more than 8 bits ? */
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_UINT_ARRAY:
+      {
+        guint8  no_of_bits  = (guint8) pDescr->i;
+        guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+        if (pDescr->value != 0)
+        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+          nCount = *pui16DATA(data, nCount);
+        }
+
+        if (remaining_bits_len >= (no_of_bits * nCount))
+        {
+          if (no_of_bits <= 8)
+          {
+            pui8 = pui8DATA(data, pDescr->offset);
+            do
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              remaining_bits_len -= no_of_bits;
+              bit_offset += no_of_bits;
+            } while (--nCount > 0);
+          }
+          else if (no_of_bits <= 16)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else if (no_of_bits <= 32)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+          }
+          else
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+          }
+        }
+        else
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_TARRAY_OFFSET:
+      case CSN_VARIABLE_TARRAY:
+      case CSN_TYPE_ARRAY:
+      {
+        gint16      Status;
+        csnStream_t arT    = *ar;
+        gint16      nCount = pDescr->i;
+        guint16     nSize  = (guint16)(gint32)pDescr->value;
+
+        pui8 = pui8DATA(data, pDescr->offset);
+        if (pDescr->type == CSN_VARIABLE_TARRAY)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+        }
+        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
+        { /* Count specified in field */
+          nCount = *pui8DATA(data, pDescr->i);
+	  /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
+        }
+
+        while (nCount > 0)
+        { /* resulting array of length 0 is possible
+           * but no bits shall be read from bitstream
+           */
+
+          LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+          if (Status >= 0)
+          {
+            pui8    += nSize;
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+
+          }
+          else
+          {
+            return Status;
+          }
+          nCount--;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_BITMAP:
+      { /* bitmap with given length. The result is left aligned! */
+        guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+        if (no_of_bits > 0)
+        {
+          if (no_of_bits > remaining_bits_len)
+          {
+            return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          if (no_of_bits <= 32)
+          {
+            for(ib = 0; ib < 4; ib++)
+            {
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else if (no_of_bits <= 64)
+          {
+            for(ib = 0; ib < 8; ib++)
+            {
+              pui8      = pui8DATA(data, pDescr->offset+ib);
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8);
+            }
+          }
+          else
+          {
+          	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
+          }
+
+          remaining_bits_len -= no_of_bits;
+          bit_offset += no_of_bits;
+        }
+        /* bitmap was successfully extracted or it was empty */
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_TYPE:
+      {
+        gint16      Status;
+        csnStream_t arT = *ar;
+        LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+        Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
+        LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
+        if (Status >= 0)
+        {
+
+          remaining_bits_len  = arT.remaining_bits_len;
+          bit_offset          = arT.bit_offset;
+          pDescr++;
+        }
+        else
+        {
+          /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_CHOICE:
+      {
+        gint16 count = pDescr->i;
+        const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
+
+        /* Make sure that the list of choice items is not empty */
+        if (!count)
+          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
+        else if (count > 255) /* We can handle up to 256 (UCHAR_MAX) selectors */
+          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
+
+        /* Make sure that choice index is not out of range */
+        pui8 = pui8DATA(data, pDescr->offset);
+        if (*pui8 >= count)
+          return ProcessError(writeIndex, "csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
+
+        pChoice += *pui8;
+        guint8 no_of_bits = pChoice->bits;
+        guint8 value = pChoice->value;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pChoice->descr.sz , (unsigned)value);
+	bitvec_write_field(vector, writeIndex, value, no_of_bits);
+
+        CSN_DESCR   descr[2];
+        gint16      Status;
+        csnStream_t arT = *ar;
+
+        descr[0]      = pChoice->descr;
+        memset(&descr[1], 0x00, sizeof(CSN_DESCR));
+        descr[1].type = CSN_END;
+        bit_offset += no_of_bits;
+        remaining_bits_len -= no_of_bits;
+
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+        Status = csnStreamEncoder(&arT, descr, vector, writeIndex, data);
+
+        if (Status >= 0)
+        {
+          remaining_bits_len = arT.remaining_bits_len;
+          bit_offset         = arT.bit_offset;
+        }
+        else
+        {
+          return Status;
+        }
+
+        pDescr++;
+        break;
+      }
+
+   case CSN_SERIALIZE:
+      {
+        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
+        csnStream_t          arT       = *ar;
+        guint8 length_len              = pDescr->i;
+        gint16               Status = -1;
+        unsigned lengthIndex;
+
+        // store writeIndex for length value (7 bit)
+        lengthIndex = *writeIndex;
+        *writeIndex += length_len;
+        bit_offset += length_len;
+        remaining_bits_len -= length_len;
+        arT.direction = 0;
+        csnStreamInit(&arT, bit_offset, remaining_bits_len);
+        Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset));
+
+	bitvec_write_field(vector, &lengthIndex, *writeIndex - lengthIndex - length_len, length_len);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s length = %u | ", pDescr->sz , (unsigned)(*writeIndex - lengthIndex));
+
+        if (Status >= 0)
+        {
+          remaining_bits_len = arT.remaining_bits_len;
+          bit_offset         = arT.bit_offset;
+          pDescr++;
+        }
+        else
+        {
+          // Has already been processed:
+          return Status;
+        }
+
+        break;
+      }
+
+      case CSN_UNION_LH:
+      case CSN_UNION:
+      {
+        gint16           Bits;
+        guint8           index;
+        gint16           count      = pDescr->i;
+        const CSN_DESCR* pDescrNext = pDescr;
+
+        pDescrNext += count + 1; /* now this is next after the union */
+        if ((count <= 0) || (count > 16))
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_INVALID_UNION_INDEX, pDescr);
+        }
+
+        /* Now get the bits to extract the index */
+        Bits = ixBitsTab[count];
+        index = 0;
+
+        /* Assign UnionType */
+        pui8  = pui8DATA(data, pDescr->offset);
+	//read index from data and write to vector
+	bitvec_write_field(vector, writeIndex, *pui8, Bits);
+
+	//decode index
+        *writeIndex -= Bits;
+
+        while (Bits > 0)
+        {
+          index <<= 1;
+
+          if (CSN_UNION_LH == pDescr->type)
+          {
+            index |= get_masked_bits8(vector, writeIndex, bit_offset, 1);
+          }
+          else
+          {
+	    index |= bitvec_read_field(vector, writeIndex, 1);
+          }
+
+          remaining_bits_len--;
+          bit_offset++;
+          Bits--;
+        }
+
+        *writeIndex -= Bits;
+	bitvec_write_field(vector, writeIndex, index, Bits);
+
+
+        /* script index to continue on, limited in case we do not have a power of 2 */
+        pDescr += (MIN(index + 1, count));
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)index);
+
+        switch (pDescr->type)
+        { /* get the right element of the union based on computed index */
+
+          case CSN_BIT:
+          {
+            pui8  = pui8DATA(data, pDescr->offset);
+	    bitvec_write_field(vector, writeIndex, *pui8, 1);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+            remaining_bits_len--;
+            bit_offset++;
+            pDescr++;
+            break;
+          }
+
+          case CSN_NULL:
+          { /* Empty member! */
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+                pui8      = pui8DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              }
+              else if (no_of_bits <= 16)
+              {
+                pui16       = pui16DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui16, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui16);
+              }
+              else if (no_of_bits <= 32)
+              {
+                pui32       = pui32DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_OFFSET:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              if (no_of_bits <= 8)
+              {
+                pui8      = pui8DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value));
+              }
+              else if (no_of_bits <= 16)
+              {
+                pui16       = pui16DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value));
+              }
+              else if (no_of_bits <= 32)
+              {
+                pui32       = pui32DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value));
+              }
+              else
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_LH:
+          {
+            guint8 no_of_bits = (guint8) pDescr->i;
+
+            if (remaining_bits_len >= no_of_bits)
+            {
+              remaining_bits_len -= no_of_bits;
+              if (no_of_bits <= 8)
+              {
+                pui8      = pui8DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+                // TODO : Change get_masked_bits8()
+                *writeIndex -= no_of_bits;
+                guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits);
+                *writeIndex -= no_of_bits;
+		bitvec_write_field(vector, writeIndex, ui8, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+              }
+              else
+              {/* Maybe we should support more than 8 bits ? */
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+
+            remaining_bits_len -= no_of_bits;
+            bit_offset += no_of_bits;
+            pDescr++;
+            break;
+          }
+
+          case CSN_UINT_ARRAY:
+          {
+            guint8  no_of_bits  = (guint8) pDescr->i;
+            guint16 nCount = (guint16)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
+
+            if (pDescr->value != 0)
+            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
+              nCount = *pui16DATA(data, nCount);
+            }
+
+            if (remaining_bits_len >= (no_of_bits * nCount))
+            {
+              if (no_of_bits <= 8)
+              {
+                pui8 = pui8DATA(data, pDescr->offset);
+                do
+                {
+		  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+                  LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+                  pui8++;
+                  remaining_bits_len -= no_of_bits;
+                  bit_offset += no_of_bits;
+                } while (--nCount > 0);
+              }
+              else if (no_of_bits <= 16)
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+              }
+              else if (no_of_bits <= 32)
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder NOTIMPLEMENTED", 999, pDescr);
+              }
+              else
+              {
+                return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_GENERAL, pDescr);
+              }
+            }
+            else
+            {
+              return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+            }
+            pDescr++;
+            break;
+          }
+
+          case CSN_VARIABLE_TARRAY_OFFSET:
+          case CSN_VARIABLE_TARRAY:
+          case CSN_TYPE_ARRAY:
+          {
+            gint16      Status;
+            csnStream_t arT    = *ar;
+            gint16      nCount = pDescr->i;
+            guint16     nSize  = (guint16)(gint32)pDescr->value;
+
+            pui8 = pui8DATA(data, pDescr->offset);
+            if (pDescr->type == CSN_VARIABLE_TARRAY)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+            }
+            else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
+            { /* Count specified in field */
+              nCount = *pui8DATA(data, pDescr->i);
+              /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
+            }
+
+            while (nCount > 0)
+            { /* resulting array of length 0 is possible
+               * but no bits shall be read from bitstream
+               */
+
+              LOGPC(DCSN1, LOGL_DEBUG, "%s : | ", pDescr->sz);
+              csnStreamInit(&arT, bit_offset, remaining_bits_len);
+              Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+              if (Status >= 0)
+              {
+                pui8    += nSize;
+                remaining_bits_len = arT.remaining_bits_len;
+                bit_offset         = arT.bit_offset;
+              }
+              else
+              {
+                return Status;
+              }
+              nCount--;
+            }
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_BITMAP:
+          { /* bitmap with given length. The result is left aligned! */
+            guint8 no_of_bits = (guint8) pDescr->i; /* length of bitmap */
+
+            if (no_of_bits > 0)
+            {
+              if (no_of_bits > remaining_bits_len)
+              {
+                return ProcessError(writeIndex, "csnStreamDecoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+              }
+
+              if (no_of_bits <= 32)
+              {
+                pui32 = pui32DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui32, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , *pui32);
+              }
+              else if (no_of_bits <= 64)
+              {
+                pui64 = pui64DATA(data, pDescr->offset);
+		bitvec_write_field(vector, writeIndex, *pui64, no_of_bits);
+                LOGPC(DCSN1, LOGL_DEBUG, "%s = %lu | ", pDescr->sz , *pui64);
+              }
+              else
+              {
+              	return ProcessError(writeIndex,"csnStreamEncoder NOT IMPLEMENTED", 999, pDescr);
+              }
+
+              remaining_bits_len -= no_of_bits;
+              bit_offset += no_of_bits;
+            }
+            /* bitmap was successfully extracted or it was empty */
+
+            pDescr++;
+            break;
+          }
+
+          case CSN_TYPE:
+          {
+            gint16      Status;
+            csnStream_t arT = *ar;
+            LOGPC(DCSN1, LOGL_DEBUG, " : %s | ", pDescr->sz);
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pvDATA(data, pDescr->offset));
+            LOGPC(DCSN1, LOGL_DEBUG, " : End %s | ", pDescr->sz);
+            if (Status >= 0)
+            {
+              remaining_bits_len  = arT.remaining_bits_len;
+              bit_offset          = arT.bit_offset;
+              pDescr++;
+            }
+            else
+            {
+              /* Has already been processed: ProcessError("csnStreamEncoder", Status, pDescr);  */
+              return Status;
+            }
+
+            break;
+          }
+
+          default:
+          { /* descriptions of union elements other than above are illegal */
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_IN_SCRIPT, pDescr);
+          }
+        }
+
+        pDescr = pDescrNext;
+        break;
+      }
+
+      case CSN_EXIST:
+      case CSN_EXIST_LH:
+      {
+        guint8 fExist;
+        unsigned exist = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+        exist = *pui8;
+	bitvec_write_field(vector, writeIndex, *pui8, 1);
+        writeIndex--;
+        if (CSN_EXIST_LH == pDescr->type)
+        {
+          fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
+        }
+        else
+        {
+	  fExist = bitvec_read_field(vector, writeIndex, 1);
+        }
+        writeIndex--;
+	bitvec_write_field(vector, writeIndex, fExist, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz, (unsigned)fExist);
+        remaining_bits_len--;
+        bit_offset++;
+        pDescr++;
+
+        if (!exist)
+        {
+          ar->remaining_bits_len  = remaining_bits_len;
+          ar->bit_offset          = bit_offset;
+          return remaining_bits_len;
+        }
+        break;
+      }
+
+      case CSN_NEXT_EXIST:
+      {
+        guint8 fExist;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
+        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* Skip i entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          break;
+        }
+
+	bitvec_write_field(vector, writeIndex, *pui8, 1);
+        fExist = *pui8;
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+
+        remaining_bits_len--;
+        bit_offset++;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_NEXT_EXIST_LH:
+      {
+        guint8 fExist;
+        pui8  = pui8DATA(data, pDescr->offset);
+
+        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
+        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
+        { /* no more bits to decode is fine here - end of message detected and allowed */
+
+          /* skip 'i' entries + this entry */
+          pDescr += pDescr->i + 1;
+
+          /* set the data member to "not exist" */
+          //*pui8 = 0;
+          break;
+        }
+
+        /* the "regular" M_NEXT_EXIST_LH description element */
+	bitvec_write_field(vector, writeIndex, *pui8, 1);
+        writeIndex--;
+        fExist = get_masked_bits8(vector, writeIndex, bit_offset, 1);
+        writeIndex--;
+	bitvec_write_field(vector, writeIndex, fExist, 1);
+        pui8++;
+
+        remaining_bits_len--;
+        bit_offset++;
+
+        if (fExist == 0)
+        { /* Skip 'i' entries */
+          pDescr += pDescr->i;
+        }
+        pDescr++;
+
+        break;
+      }
+
+      case CSN_VARIABLE_BITMAP_1:
+      { /* Bitmap from here and to the end of message */
+
+        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /*no break -
+         * with a length set we have a regular variable length bitmap so we continue */
+      }
+      /* FALL THROUGH */
+      case CSN_VARIABLE_BITMAP:
+      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * Bit array with length (in bits) specified in parameter (pDescr->descr)
+         * The result is right aligned!
+         */
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        no_of_bits += pDescr->i; /* adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
+
+            if (nB1 > 0)
+            { /* take care of the first byte - it will be right aligned */
+	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits  -= nB1;
+              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
+              remaining_bits_len -= nB1;
+            }
+
+            /* remaining no_of_bits is a multiple of 8 or 0 */
+            while (no_of_bits > 0)
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+              remaining_bits_len -= 8;
+            }
+          }
+        }
+        pDescr++;
+        break;
+      }
+
+      case CSN_LEFT_ALIGNED_VAR_BMP_1:
+      { /* Bitmap from here and to the end of message */
+
+        //*pui8DATA(data, (gint16)pDescr->descr.value) = (guint8) remaining_bits_len; /* length of bitmap == remaining bits */
+
+        /* no break -
+         * with a length set we have a regular left aligned variable length bitmap so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_LEFT_ALIGNED_VAR_BMP:
+      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * <N: bit (5)> <bitmap: bit(N + offset)>
+         * bit array with length (in bits) specified in parameter (pDescr->descr)
+         */
+
+        gint16 no_of_bits = *pui8DATA(data, (gint16)pDescr->descr.value);/* Size of bitmap */
+
+        no_of_bits += pDescr->i;/* size adjusted by offset */
+
+        if (no_of_bits > 0)
+        {
+          remaining_bits_len -= no_of_bits;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          { /* extract bits */
+            guint8* pui8 = pui8DATA(data, pDescr->offset);
+            gint16 nB1  = no_of_bits & 0x07;/* no_of_bits Mod 8 */
+
+            while (no_of_bits > 0)
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits -= 8;
+            }
+            if (nB1 > 0)
+            {
+	      bitvec_write_field(vector, writeIndex, *pui8, nB1);
+              LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+              pui8++;
+              no_of_bits  -= nB1;
+              bit_offset += nB1; /* (nB1 is no_of_bits Mod 8) */
+            }
+          }
+
+        }
+
+        /* bitmap was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_PADDING_BITS:
+      { /* Padding from here and to the end of message */
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = ", pDescr->sz);
+        guint8 filler = 0x2b;
+        if (remaining_bits_len > 0)
+        {
+          while (remaining_bits_len > 0)
+          {
+            guint8 bits_to_handle = remaining_bits_len%8;
+            if (bits_to_handle > 0)
+            {
+              /* section 11 of 44.060
+               * The padding bits may be the 'null' string. Otherwise, the
+               * padding bits starts with bit '0', followed by 'spare padding'
+               * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ;
+              */
+              guint8 fl = filler&(0xff>>(8-bits_to_handle + 1));
+	      bitvec_write_field(vector, writeIndex, fl, bits_to_handle);
+              LOGPC(DCSN1, LOGL_DEBUG, "%u|", fl);
+              remaining_bits_len -= bits_to_handle;
+              bit_offset += bits_to_handle;
+            }
+            else if (bits_to_handle == 0)
+            {
+	      bitvec_write_field(vector, writeIndex, filler, 8);
+              LOGPC(DCSN1, LOGL_DEBUG, "%u|", filler);
+              remaining_bits_len -= 8;
+              bit_offset += 8;
+            }
+          }
+        }
+        if (remaining_bits_len < 0)
+        {
+          return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+        }
+
+        /* Padding was successfully extracted or it was empty */
+        pDescr++;
+        break;
+      }
+
+      case CSN_VARIABLE_ARRAY:
+      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
+         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * Array with length specified in parameter:
+         *  <count: bit (x)>
+         *  <list: octet(count + offset)>
+         */
+        gint16 count = *pui8DATA(data, (gint16)pDescr->descr.value);
+
+        count += pDescr->i; /* Adjusted by offset */
+
+        if (count > 0)
+        {
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          pui8 = pui8DATA(data, pDescr->offset);
+
+          while (count > 0)
+          {
+	    bitvec_write_field(vector, writeIndex, *pui8, 8);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = 0x%x | ", pDescr->sz , (unsigned)*pui8);
+            pui8++;
+            bit_offset += 8;
+            remaining_bits_len -= 8;
+            count--;
+          }
+        }
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_ARRAY:
+      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
+         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
+         *  where <element> ::= bit(value)
+         *        <tag>     ::= 0 | 1
+         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
+         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
+         * REMARK: recursive way to specify an array but an iterative implementation!
+         */
+        gint16 no_of_bits        = pDescr->i;
+        guint8  ElementCount = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+        ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value);
+        while (ElementCount > 0)
+        { /* tag control shows existence of next list elements */
+	  bitvec_write_field(vector, writeIndex, Tag, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
+          bit_offset++;
+          remaining_bits_len--;
+
+          /* extract and store no_of_bits long element from bitstream */
+	  bitvec_write_field(vector, writeIndex, *pui8, no_of_bits);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)*pui8);
+          pui8++;
+          ElementCount--;
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+          bit_offset += no_of_bits;
+          remaining_bits_len -= no_of_bits;
+        }
+
+	bitvec_write_field(vector, writeIndex, !Tag, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
+        bit_offset++;
+        remaining_bits_len--;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY:
+      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
+         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
+         */
+        gint16 nSizeElement = (gint16)(gint32)pDescr->value;
+        guint8  ElementCount = 0;
+        pui8  = pui8DATA(data, pDescr->offset);
+        /* Store the counted number of elements of the array */
+        ElementCount = *pui8DATA(data, (gint16)(gint32)pDescr->i);
+
+        while (ElementCount > 0)
+        { /* tag control shows existence of next list elements */
+	  bitvec_write_field(vector, writeIndex, Tag, 1);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
+          bit_offset++;
+
+          remaining_bits_len--;
+          ElementCount--;
+
+          { /* unpack the following data structure */
+            csnStream_t arT = *ar;
+            gint16      Status;
+            csnStreamInit(&arT, bit_offset, remaining_bits_len);
+            Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+
+            if (Status >= 0)
+            { /* successful completion */
+              pui8    += nSizeElement;  /* -> to next data element */
+              remaining_bits_len = arT.remaining_bits_len;
+              bit_offset         = arT.bit_offset;
+            }
+            else
+            { /* something went awry */
+              return Status;
+            }
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+        }
+
+	bitvec_write_field(vector, writeIndex, !Tag, 1);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)(!Tag));
+        bit_offset++;
+
+        pDescr++;
+        break;
+      }
+
+      case CSN_RECURSIVE_TARRAY_2:
+      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
+
+        Tag = REVERSED_TAG;
+
+        /* NO break -
+         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
+         */
+      }
+      /* FALL THROUGH */
+      case CSN_RECURSIVE_TARRAY_1:
+      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
+         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
+         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE)}
+         */
+        gint16      nSizeElement = (gint16)(gint32)pDescr->value;
+        guint8      ElementCount = 0;
+        guint8      ElementNum   = 0;
+        csnStream_t arT          = *ar;
+        gint16      Status;
+
+        pui8  = pui8DATA(data, pDescr->offset);
+        /* Store the count of the array */
+        ElementCount = *pui8DATA(data, pDescr->i);
+        ElementNum = ElementCount;
+
+        while (ElementCount > 0)
+        { /* get data element */
+          if (ElementCount != ElementNum)
+          {
+	    bitvec_write_field(vector, writeIndex, Tag, 1);
+            LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)Tag);
+            bit_offset++;
+            remaining_bits_len--;
+          }
+          ElementCount--;
+          LOGPC(DCSN1, LOGL_DEBUG, "%s { | ", pDescr->sz);
+          csnStreamInit(&arT, bit_offset, remaining_bits_len);
+          Status = csnStreamEncoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, writeIndex, pui8);
+          LOGPC(DCSN1, LOGL_DEBUG, "%s } | ", pDescr->sz);
+          if (Status >= 0)
+          { /* successful completion */
+            pui8    += nSizeElement;  /* -> to next */
+            remaining_bits_len = arT.remaining_bits_len;
+            bit_offset         = arT.bit_offset;
+          }
+          else
+          { /* something went awry */
+            return Status;
+          }
+
+          if (remaining_bits_len < 0)
+          {
+            return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+          }
+
+        }
+	bitvec_write_field(vector, writeIndex, !Tag, 1);
+        bit_offset++;
+        remaining_bits_len--;
+        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
+        pDescr++;
+        break;
+      }
+
+      case CSN_FIXED:
+      { /* Verify the fixed bits */
+        guint8  no_of_bits = (guint8) pDescr->i;
+	bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits);
+        LOGPC(DCSN1, LOGL_DEBUG, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset);
+        remaining_bits_len   -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_CALLBACK:
+      {
+        guint16  no_of_bits;
+        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
+        LOGPC(DCSN1, LOGL_DEBUG, "CSN_CALLBACK(%s) | ", pDescr->sz);
+        no_of_bits = callback(vector, writeIndex, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset));
+        remaining_bits_len -= no_of_bits;
+        bit_offset += no_of_bits;
+        pDescr++;
+        break;
+      }
+
+      case CSN_TRAP_ERROR:
+      {
+        return ProcessError(writeIndex,"csnStreamEncoder", pDescr->i, pDescr);
+      }
+
+      case CSN_END:
+      {
+        ar->remaining_bits_len  = remaining_bits_len;
+        ar->bit_offset = bit_offset;
+        return remaining_bits_len;
+      }
+
+      default:
+      {
+        assert(0);
+      }
+
+    }
+
+  } while (remaining_bits_len >= 0);
+
+  return ProcessError(writeIndex,"csnStreamEncoder", CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, pDescr);
+}

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-pcu/+/25827
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: I7d1b1f7e6d7f89b052b3fd73a960419bb2673020
Gerrit-Change-Number: 25827
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211019/c277b4ef/attachment.htm>


More information about the gerrit-log mailing list