/* 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@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);
}
