#include <stdint.h>
#include <endian.h>

#include "RLCMAC_Types.hh"
#include "RLCMAC_Templates.hh"
#include "GSM_Types.hh"
/* Decoding of TS 44.060 GPRS RLC/MAC blocks, portions requiring manual functions
 * beyond what TITAN RAW coder can handle internally.
 *
 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

namespace RLCMAC__Types {

/////////////////////
// INTENRAL HELPERS
/////////////////////

/* TS 04.60  10.3a.4.1.1 */
struct gprs_rlc_ul_header_egprs_1 {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t r:1,
		 si:1,
		 cv:4,
		 tfi_hi:2;
	uint8_t tfi_lo:3,
		 bsn1_hi:5;
	uint8_t bsn1_lo:6,
		 bsn2_hi:2;
	uint8_t bsn2_lo:8;
	uint8_t cps:5,
		 rsb:1,
		 pi:1,
		 spare_hi:1;
	uint8_t spare_lo:6,
		 dummy:2;
#else
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t tfi_hi:2, cv:4, si:1, r:1;
	uint8_t bsn1_hi:5, tfi_lo:3;
	uint8_t bsn2_hi:2, bsn1_lo:6;
	uint8_t bsn2_lo:8;
	uint8_t spare_hi:1, pi:1, rsb:1, cps:5;
	uint8_t dummy:2, spare_lo:6;
#endif
} __attribute__ ((packed));

/* TS 04.60  10.3a.4.2.1 */
struct gprs_rlc_ul_header_egprs_2 {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t r:1,
		 si:1,
		 cv:4,
		 tfi_hi:2;
	uint8_t tfi_lo:3,
		 bsn1_hi:5;
	uint8_t bsn1_lo:6,
		 cps_hi:2;
	uint8_t cps_lo:1,
		 rsb:1,
		 pi:1,
		 spare_hi:5;
	uint8_t spare_lo:5,
		 dummy:3;
#else
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t tfi_hi:2, cv:4, si:1, r:1;
	uint8_t bsn1_hi:5, tfi_lo:3;
	uint8_t cps_hi:2, bsn1_lo:6;
	uint8_t spare_hi:5, pi:1, rsb:1, cps_lo:1;
	uint8_t dummy:3, spare_lo:5;
#endif
} __attribute__ ((packed));

/* TS 04.60  10.3a.4.3.1 */
struct gprs_rlc_ul_header_egprs_3 {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t r:1,
		 si:1,
		 cv:4,
		 tfi_hi:2;
	uint8_t tfi_lo:3,
		 bsn1_hi:5;
	uint8_t bsn1_lo:6,
		 cps_hi:2;
	uint8_t cps_lo:2,
		 spb:2,
		 rsb:1,
		 pi:1,
		 spare:1,
		 dummy:1;
#else
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t tfi_hi:2, cv:4, si:1, r:1;
	uint8_t bsn1_hi:5, tfi_lo:3;
	uint8_t cps_hi:2, bsn1_lo:6;
	uint8_t dummy:1, spare:1, pi:1, rsb:1, spb:2, cps_lo:2;
#endif
} __attribute__ ((packed));

struct gprs_rlc_dl_header_egprs_1 {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t usf:3,
		 es_p:2,
		 rrbp:2,
		 tfi_hi:1;
	uint8_t tfi_lo:4,
		 pr:2,
		 bsn1_hi:2;
	uint8_t bsn1_mid:8;
	uint8_t bsn1_lo:1,
		 bsn2_hi:7;
	uint8_t bsn2_lo:3,
		 cps:5;
#else
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t tfi_hi:1, rrbp:2, es_p:2, usf:3;
	uint8_t bsn1_hi:2, pr:2, tfi_lo:4;
	uint8_t bsn1_mid:8;
	uint8_t bsn2_hi:7, bsn1_lo:1;
	uint8_t cps:5, bsn2_lo:3;
#endif
} __attribute__ ((packed));

struct gprs_rlc_dl_header_egprs_2 {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t usf:3,
		 es_p:2,
		 rrbp:2,
		 tfi_hi:1;
	uint8_t tfi_lo:4,
		 pr:2,
		 bsn1_hi:2;
	uint8_t bsn1_mid:8;
	uint8_t bsn1_lo:1,
		 cps:3,
		 dummy:4;
#else
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t tfi_hi:1, rrbp:2, es_p:2, usf:3;
	uint8_t bsn1_hi:2, pr:2, tfi_lo:4;
	uint8_t bsn1_mid:8;
	uint8_t dummy:4, cps:3, bsn1_lo:1;
#endif
} __attribute__ ((packed));

struct gprs_rlc_dl_header_egprs_3 {
#if __BYTE_ORDER == __LITTLE_ENDIAN
	uint8_t usf:3,
		 es_p:2,
		 rrbp:2,
		 tfi_hi:1;
	uint8_t tfi_lo:4,
		 pr:2,
		 bsn1_hi:2;
	uint8_t bsn1_mid:8;
	uint8_t bsn1_lo:1,
		 cps:4,
		 spb:2,
		 dummy:1;
#else
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
	uint8_t tfi_hi:1, rrbp:2, es_p:2, usf:3;
	uint8_t bsn1_hi:2, pr:2, tfi_lo:4;
	uint8_t bsn1_mid:8;
	uint8_t dummy:1, spb:2, cps:4, bsn1_lo:1;
#endif
} __attribute__ ((packed));

/*
static const char hex_chars[] = "0123456789abcdef";
void printbuffer(const char* ptr, TTCN_Buffer& buf) {
	int len = buf.get_len();
	const unsigned char* cbuf = buf.get_data();

	fprintf(stderr, "printbuffer %s (len=%d): [", ptr, len);

	for (int i = 0; i < len; i++) {
		fprintf(stderr, " %c%c", hex_chars[cbuf[i] >> 4], hex_chars[cbuf[i] & 0xf]);
	}

	fprintf(stderr, " ]\n");
}
*/

static CodingScheme::enum_type payload_len_2_coding_scheme(size_t payload_len) {
	switch (payload_len) {
	case 23:
		return CodingScheme::CS__1;
	case 34:
		return CodingScheme::CS__2;
	case 40:
		return CodingScheme::CS__3;
	case 54:
		return CodingScheme::CS__4;
	case 27:
		return CodingScheme::MCS__1;
	case 33:
		return CodingScheme::MCS__2;
	case 42:
		return CodingScheme::MCS__3;
	case 49:
		return CodingScheme::MCS__4;
	case 60: /* fall through */
	case 61:
		return CodingScheme::MCS__5;
	case 78: /* fall through */
	case 79:
		return CodingScheme::MCS__6;
	case 118: /* fall through */
	case 119:
		return CodingScheme::MCS__7;
	case 142: /* fall through */
	case 143:
		return CodingScheme::MCS__8;
	case 154: /* fall through */
	case 155:
		return CodingScheme::MCS__9;
	default:
		fprintf(stderr, "ERROR: Unknown CodingSCheme for payload_len=%zu\n", payload_len);
		return CodingScheme::CS__1;
	}
}

static unsigned int coding_scheme_2_data_block_len(CodingScheme::enum_type mcs) {
	switch (mcs) {
	case CodingScheme::MCS__0:
		return 0;
	case CodingScheme::MCS__1:
		return 22;
	case CodingScheme::MCS__2:
		return 28;
	case CodingScheme::MCS__3:
		return 37;
	case CodingScheme::MCS__4:
		return 44;
	case CodingScheme::MCS__5:
		return 56;
	case CodingScheme::MCS__6:
		return 74;
	case CodingScheme::MCS__7:
		return 56;
	case CodingScheme::MCS__8:
		return 68;
	case CodingScheme::MCS__9:
		return 74;
	default:
		return 22; /* MCS1*/
	}
}

static uint8_t bs2uint8(const BITSTRING& bs)
{
	int len = bs.lengthof();
	int i;
	uint8_t res = 0;
	for (i = 0; i < len; i++) {
		res = res << 1;
		res |= (bs[i].get_bit() ? 1 : 0);
	}
	return res;
}

/* determine the number of rlc data blocks and their size / offsets */
static void
setup_rlc_mac_priv(CodingScheme::enum_type mcs, EgprsHeaderType::enum_type hdrtype, boolean is_uplink,
	unsigned int *n_calls, unsigned int *data_block_bits, unsigned int *data_block_offsets)
{
	unsigned int nc, dbl = 0, dbo[2] = {0,0};

	dbl = coding_scheme_2_data_block_len(mcs);

	switch (hdrtype) {
	case EgprsHeaderType::RLCMAC__HDR__TYPE__1:
		nc = 3;
		dbo[0] = is_uplink ? 5*8 + 6 : 5*8 + 0;
		dbo[1] = dbo[0] + dbl * 8 + 2;
		break;
	case EgprsHeaderType::RLCMAC__HDR__TYPE__2:
		nc = 2;
		dbo[0] = is_uplink ? 4*8 + 5 : 3*8 + 4;
		break;
	case EgprsHeaderType::RLCMAC__HDR__TYPE__3:
		nc = 2;
		dbo[0] = 3*8 + 7;
		break;
	default:
		nc = 1;
		break;
	}

	*n_calls = nc;
	*data_block_bits = dbl * 8 + 2;
	data_block_offsets[0] = dbo[0];
	data_block_offsets[1] = dbo[1];
}

/* bit-shift the entire 'src' of length 'length_bytes' by 'offset_bits'
 * and store the result to caller-allocated 'buffer'.  The shifting is
 * done lsb-first. */
static void clone_aligned_buffer_lsbf(unsigned int offset_bits, unsigned int length_bytes,
	const uint8_t *src, uint8_t *buffer)
{
	unsigned int hdr_bytes;
	unsigned int extra_bits;
	unsigned int i;

	uint8_t c, last_c;
	uint8_t *dst;

	hdr_bytes = offset_bits / 8;
	extra_bits = offset_bits % 8;

	//fprintf(stderr, "RLMAC: clone: hdr_bytes=%u extra_bits=%u (length_bytes=%u)\n", hdr_bytes, extra_bits, length_bytes);

	if (extra_bits == 0) {
		/* It is aligned already */
		memcpy(buffer, src + hdr_bytes, length_bytes);
		return;
	}

	dst = buffer;
	src = src + hdr_bytes;
	last_c = *(src++);

	for (i = 0; i < length_bytes; i++) {
		c = src[i];
		*(dst++) = (last_c >> extra_bits) | (c << (8 - extra_bits));
		last_c = c;
	}
}

/* obtain an (aligned) EGPRS data block with given bit-offset and
 * bit-length from the parent buffer */
static void get_egprs_data_block(const TTCN_Buffer& orig_ttcn_buffer, unsigned int offset_bits,
	unsigned int length_bits, TTCN_Buffer& dst_ttcn_buffer)
{
	const unsigned int initial_spare_bits = 6;
	unsigned char *aligned_buf = NULL;
	size_t min_src_length_bytes = (offset_bits + length_bits + 7) / 8;
	size_t length_bytes = (initial_spare_bits + length_bits + 7) / 8;
	size_t accepted_len = length_bytes;

	//fprintf(stderr, "RLMAC: trying to allocate %u bytes (orig is %zu bytes long with read pos %zu)\n", length_bytes, orig_ttcn_buffer.get_len(), orig_ttcn_buffer.get_pos());
	dst_ttcn_buffer.get_end(aligned_buf, accepted_len);
	if (accepted_len < length_bytes) {
		fprintf(stderr, "RLMAC: ERROR! asked for %zu bytes but got %zu\n", length_bytes, accepted_len);
	}

	/* Copy the data out of the tvb to an aligned buffer */
	clone_aligned_buffer_lsbf(
		offset_bits - initial_spare_bits, length_bytes,
		orig_ttcn_buffer.get_data(),
		aligned_buf);

	/* clear spare bits and move block header bits to the right */
	aligned_buf[0] = aligned_buf[0] >> initial_spare_bits;

	dst_ttcn_buffer.increase_length(length_bytes);
}

/* bit-shift the entire 'src' of length 'length_bytes'
 * and store the result to caller-allocated 'buffer'  by 'offset_bits'.  The shifting is
 * done lsb-first. */
static void clone_unaligned_buffer_lsbf(unsigned int offset_bits, unsigned int length_bytes,
	const uint8_t *src, uint8_t *buffer)
{
	unsigned int hdr_bytes;
	unsigned int extra_bits;
	unsigned int i;

	uint8_t c, last_hdr_c, last_c;
	uint8_t *dst;

	hdr_bytes = offset_bits / 8;
	extra_bits = offset_bits % 8;

	//fprintf(stderr, "RLMAC: clone: hdr_bytes=%u extra_bits=%u (length_bytes=%u)\n", hdr_bytes, extra_bits, length_bytes);

	if (extra_bits == 0) {
		/* It is aligned already */
		memcpy(buffer, src + hdr_bytes, length_bytes);
		return;
	}

	/* Copy first header+data byte, it's not handled correctly by loop */
	dst = buffer + hdr_bytes;
	last_hdr_c = *dst;
	last_c = *dst << (8 - extra_bits);

	for (i = 0; i < length_bytes; i++) {
		c = src[i];
		*(dst++) = (last_c >> (8 - extra_bits)) | (c << extra_bits);
		last_c = c;
	}
	/* overwrite the lower extra_bits */
	*dst = (*dst & (0xff << extra_bits)) | (last_c >> (8 - extra_bits));

	/* Copy back first header+data byte */
	dst = buffer + hdr_bytes;
	*(dst++) = last_hdr_c | (src[0] << (8 - extra_bits));
	*dst |= (src[0] >> (extra_bits)) & (0xff >> (8 - extra_bits));
}

/* put an (aligned) EGPRS data block with given bit-offset and
 * bit-length into parent buffer */
static void put_egprs_data_block(const TTCN_Buffer& aligned_data_block_buffer, unsigned int offset_bits,
	unsigned int length_bits, TTCN_Buffer& dst_ttcn_buffer)
{
	const unsigned int initial_spare_bits = 6;
	unsigned char *unaligned_buf = NULL;
	char tmpbuf[120];
	int tmplen = dst_ttcn_buffer.get_len();
	//size_t max_length_bytes = (initial_spare_bits + length_bits + 7) / 8;
	size_t length_bytes = tmplen + aligned_data_block_buffer.get_len();
	size_t accepted_len = length_bytes;

	//fprintf(stderr, "RLMAC: trying to allocate %u bytes\n", length_bytes);

	/* API .get_end() is the only one I could find to access writeable
	   memory in the buffer. It points to the end. Hence, we first copy
	   (readonly) data to tmpbuf and later clear() so that .get_end()
	   provides us with a pointer to the start of the buffer. */
	memcpy(tmpbuf, dst_ttcn_buffer.get_data(), tmplen);
	dst_ttcn_buffer.clear();
	dst_ttcn_buffer.get_end(unaligned_buf, accepted_len);
	if (accepted_len < tmplen) {
		fprintf(stderr, "RLMAC: ERROR! asked for %zu bytes but got %zu\n", length_bytes, accepted_len);
	}
	memcpy(unaligned_buf, tmpbuf, tmplen);

	/* Copy the data out of the tvb to an aligned buffer */
	clone_unaligned_buffer_lsbf(
		offset_bits - initial_spare_bits, length_bytes,
		aligned_data_block_buffer.get_data(),
		unaligned_buf);

	dst_ttcn_buffer.increase_length(length_bytes);
}

/* Append padding bytes and spare bits at the end of ttcn_buffer, based on requested CS */
static void encode_trailing_padding_spb(TTCN_Buffer& ttcn_buffer, CodingScheme cs)
{
	uint8_t buf[256]; /* enough to fit any RLCMAC buffer*/
	uint32_t blk_len = RLCMAC__Templates::f__rlcmac__cs__mcs2block__len(cs);
	uint32_t blk_len_no_spb = RLCMAC__Templates::f__rlcmac__cs__mcs2block__len__no__spare__bits(cs);
	uint32_t data_len = ttcn_buffer.get_len();

	if (data_len > blk_len_no_spb) {
		fprintf(stderr, "Buffer too large for requested CS! %s (%s:%u)\n", __func__, __FILE__, __LINE__);
		// TODO: throw exception?
	}

	for (int i = 0; i < blk_len_no_spb - data_len; i++)
		buf[i] = 0x2b; /* Padding bits if needed */
	for (int i = blk_len_no_spb - data_len; i < blk_len - data_len; i++)
		buf[i] = 0x00;  /* Spare bits if needed */

	const OCTETSTRING& pad_octstr = OCTETSTRING(blk_len - data_len, buf);
	ttcn_buffer.put_string(pad_octstr);
}

/////////////////////
// DECODE
/////////////////////

/* DECODE DOWNLINK */

RlcmacDlDataBlock dec__RlcmacDlDataBlock(const OCTETSTRING& stream)
{
	RlcmacDlDataBlock ret_val;
	TTCN_Buffer ttcn_buffer(stream);
	int num_llc_blocks = 0;

	ret_val.cs() = payload_len_2_coding_scheme(stream.lengthof());

	/* use automatic/generated decoder for header */
	ret_val.mac__hdr().decode(DlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);

	/* optional extension octets, containing LI+M+E of Llc blocks */
	if (ret_val.mac__hdr().hdr__ext().e() == false) {
		/* extension octet follows, i.e. optional Llc length octets */
		while (1) {
			/* decode one more extension octet with LlcBlocHdr inside */
			LlcBlock lb;
			lb.hdr()().decode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
			ret_val.blocks()[num_llc_blocks++] = lb;

			/* if E == '1'B, we can proceed further */
			if (lb.hdr()().e() == true)
				break;
		}
	}

	/* RLC blocks at end */
	if (ret_val.mac__hdr().hdr__ext().e() == true) {
		LlcBlock lb;
		unsigned int length = ttcn_buffer.get_read_len();
		/* LI not present: The Upper Layer PDU that starts with the current RLC data block either
		 * fills the current RLC data block precisely or continues in the following in-sequence RLC
		 * data block */
		lb.hdr() = OMIT_VALUE;
		lb.payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());
		ttcn_buffer.increase_pos(length);
		ret_val.blocks()[0] = lb;
	} else {
		if (ret_val.blocks().is_bound()) {
			for (int i = 0; i < ret_val.blocks().size_of(); i++) {
				unsigned int length = ret_val.blocks()[i].hdr()().length__ind();

				/* LI[0]=0 indicates: The current LLC PDU would fit within
				   current RLC data block but the addition of the length
				   indicator octet (to indicate the LLC PDU boundary) causes the
				   LLC PDU to extend into another RLC data block */
				if (i == 0 && length == 0)
					length = ttcn_buffer.get_read_len();

				if (length > ttcn_buffer.get_read_len())
					length = ttcn_buffer.get_read_len();

				ret_val.blocks()[i].payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());
				ttcn_buffer.increase_pos(length);
			}
		}
	}

	return ret_val;
}

static
EgprsDlMacDataHeader dec__EgprsDlMacDataHeader_type1(const OCTETSTRING& stream)
{
	TTCN_Buffer ttcn_buffer(stream);
	EgprsDlMacDataHeader ret_val;
	const struct gprs_rlc_dl_header_egprs_1 *egprs1;
	uint8_t tmp;

	egprs1 = static_cast<const struct gprs_rlc_dl_header_egprs_1 *>
		((const void *)ttcn_buffer.get_data());

	ret_val.header__type() = EgprsHeaderType::RLCMAC__HDR__TYPE__1;
	ret_val.tfi() = egprs1->tfi_lo << 1 | egprs1->tfi_hi << 0;
	ret_val.rrbp() = egprs1->rrbp;
	tmp = egprs1->es_p;
	ret_val.esp() = BITSTRING(2, &tmp);
	ret_val.usf() = egprs1->usf;
	ret_val.bsn1() = egprs1->bsn1_lo << 10 | egprs1->bsn1_mid << 2 | egprs1->bsn1_hi;
	ret_val.bsn2__offset() = egprs1->bsn2_lo << 7 | egprs1->bsn2_hi;
	ret_val.pr() = egprs1->pr;
	ret_val.cps() = egprs1->cps;
	ret_val.spb() = OMIT_VALUE;

	ttcn_buffer.increase_pos(sizeof(*egprs1));
	return ret_val;
}

static
EgprsDlMacDataHeader dec__EgprsDlMacDataHeader_type2(const OCTETSTRING& stream)
{
	TTCN_Buffer ttcn_buffer(stream);
	EgprsDlMacDataHeader ret_val;
	const struct gprs_rlc_dl_header_egprs_2 *egprs2;
	uint8_t tmp;

	egprs2 = static_cast<const struct gprs_rlc_dl_header_egprs_2 *>
		((const void *)ttcn_buffer.get_data());

	ret_val.header__type() = EgprsHeaderType::RLCMAC__HDR__TYPE__2;
	ret_val.tfi() = egprs2->tfi_lo << 1 | egprs2->tfi_hi << 0;
	ret_val.rrbp() = egprs2->rrbp;
	tmp = egprs2->es_p;
	ret_val.esp() = BITSTRING(2, &tmp);
	ret_val.usf() = egprs2->usf;
	ret_val.bsn1() = egprs2->bsn1_lo << 10 | egprs2->bsn1_mid << 2 | egprs2->bsn1_hi;
	ret_val.bsn2__offset() = 0; /*TODO: mark optional and not set ? */
	ret_val.pr() = egprs2->pr;
	ret_val.cps() = egprs2->cps;
	ret_val.spb() = OMIT_VALUE;

	ttcn_buffer.increase_pos(sizeof(*egprs2));
	return ret_val;
}

static
EgprsDlMacDataHeader dec__EgprsDlMacDataHeader_type3(const OCTETSTRING& stream)
{
	TTCN_Buffer ttcn_buffer(stream);
	EgprsDlMacDataHeader ret_val;
	const struct gprs_rlc_dl_header_egprs_3 *egprs3;
	uint8_t tmp;

	egprs3 = static_cast<const struct gprs_rlc_dl_header_egprs_3 *>
		((const void *)ttcn_buffer.get_data());

	ret_val.header__type() = EgprsHeaderType::RLCMAC__HDR__TYPE__3;
	ret_val.tfi() = egprs3->tfi_lo << 1 | egprs3->tfi_hi << 0;
	ret_val.rrbp() = egprs3->rrbp;
	tmp = egprs3->es_p;
	ret_val.esp() = BITSTRING(2, &tmp);
	ret_val.usf() = egprs3->usf;
	ret_val.bsn1() = egprs3->bsn1_lo << 10 | egprs3->bsn1_mid << 2 | egprs3->bsn1_hi;
	ret_val.bsn2__offset() = 0; /*TODO: mark optional and not set ? */
	ret_val.pr() = egprs3->pr;
	ret_val.spb() = egprs3->spb;
	ret_val.cps() = egprs3->cps;

	ttcn_buffer.increase_pos(sizeof(*egprs3));
	return ret_val;
}

static
RlcmacDlEgprsDataBlock dec__RlcmacDlEgprsDataBlock(const OCTETSTRING& stream)
{
	RlcmacDlEgprsDataBlock ret_val;
	TTCN_Buffer ttcn_buffer(stream);
	TTCN_Buffer aligned_buffer;
	int num_llc_blocks = 0;
	unsigned int data_block_bits, data_block_offsets[2];
	unsigned int num_calls;
	const uint8_t *ti_e;

	ret_val.mcs() = payload_len_2_coding_scheme(stream.lengthof());
	switch (ret_val.mcs()) {
	case CodingScheme::MCS__0:
	case CodingScheme::MCS__1:
	case CodingScheme::MCS__2:
	case CodingScheme::MCS__3:
	case CodingScheme::MCS__4:
		ret_val.mac__hdr() = dec__EgprsDlMacDataHeader_type3(stream);
		break;
	case CodingScheme::MCS__5:
	case CodingScheme::MCS__6:
		ret_val.mac__hdr() = dec__EgprsDlMacDataHeader_type2(stream);
		break;
	case CodingScheme::MCS__7:
	case CodingScheme::MCS__8:
	case CodingScheme::MCS__9:
		ret_val.mac__hdr() = dec__EgprsDlMacDataHeader_type1(stream);
		break;
	}
	setup_rlc_mac_priv(ret_val.mcs(), ret_val.mac__hdr().header__type(), false,
			   &num_calls, &data_block_bits, data_block_offsets);
	get_egprs_data_block(ttcn_buffer, data_block_offsets[0], data_block_bits, aligned_buffer);

	ti_e = aligned_buffer.get_read_data();
	ret_val.fbi() = *ti_e & 0x02 ? true : false;
	ret_val.e() = *ti_e & 0x01 ? true : false;
	aligned_buffer.increase_pos(1);

	/* optional extension octets, containing LI+E of Llc blocks */
	if (ret_val.e() == false) {
		/* extension octet follows, i.e. optional Llc length octets */
		while (1) {
			/* decode one more extension octet with LlcBlocHdr inside */
			EgprsLlcBlock lb;
			lb.hdr()().decode(EgprsLlcBlockHdr_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);
			ret_val.blocks()[num_llc_blocks++] = lb;

			/* if E == '1'B, we can proceed further */
			if (lb.hdr()().e() == true)
				break;
		}
	}

	/* RLC blocks at end */
	if (ret_val.e() == true) {
		EgprsLlcBlock lb;
		unsigned int length = aligned_buffer.get_read_len();
		/* LI not present: The Upper Layer PDU that starts with the current RLC data block either
		 * fills the current RLC data block precisely or continues in the following in-sequence RLC
		 * data block */
		lb.hdr() = OMIT_VALUE;
		lb.payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());
		aligned_buffer.increase_pos(length);
		ret_val.blocks()[0] = lb;
	} else {
		/* RLC blocks at end */
		if (ret_val.blocks().is_bound()) {
			for (int i = 0; i < ret_val.blocks().size_of(); i++) {
				unsigned int length = ret_val.blocks()[i].hdr()().length__ind();
				if (length > aligned_buffer.get_read_len())
					length = aligned_buffer.get_read_len();
				ret_val.blocks()[i].payload() = OCTETSTRING(length, aligned_buffer.get_read_data());
				aligned_buffer.increase_pos(length);
			}
		}
	}

	return ret_val;
}

RlcmacDlBlock dec__RlcmacDlBlock(const OCTETSTRING& stream)
{
	RlcmacDlBlock ret_val;
	size_t stream_len = stream.lengthof();
	CodingScheme::enum_type cs_mcs = payload_len_2_coding_scheme(stream_len);
	unsigned char pt;

	switch (cs_mcs) {
	case CodingScheme::CS__1:
	case CodingScheme::CS__2:
	case CodingScheme::CS__3:
	case CodingScheme::CS__4:
		pt = stream[0].get_octet() >> 6;
		if (pt == MacPayloadType::MAC__PT__RLC__DATA)
			ret_val.data() = dec__RlcmacDlDataBlock(stream);
		else
			ret_val.ctrl() = dec__RlcmacDlCtrlBlock(stream);
		break;
	case CodingScheme::MCS__0:
	case CodingScheme::MCS__1:
	case CodingScheme::MCS__2:
	case CodingScheme::MCS__3:
	case CodingScheme::MCS__4:
	case CodingScheme::MCS__5:
	case CodingScheme::MCS__6:
	case CodingScheme::MCS__7:
	case CodingScheme::MCS__8:
	case CodingScheme::MCS__9:
		ret_val.data__egprs() = dec__RlcmacDlEgprsDataBlock(stream);
		break;
	}
	return ret_val;
}

/* DECODE UPLINK */

RlcmacUlDataBlock dec__RlcmacUlDataBlock(const OCTETSTRING& stream)
{
	RlcmacUlDataBlock ret_val;
	TTCN_Buffer ttcn_buffer(stream);
	int num_llc_blocks = 0;

	TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
	TTCN_Logger::log_event_str("==================================\n"
				"dec_RlcmacUlDataBlock(): Stream before decoding: ");
	stream.log();
	TTCN_Logger::end_event();

	ret_val.cs() = payload_len_2_coding_scheme(stream.lengthof());

	/* use automatic/generated decoder for header */
	ret_val.mac__hdr().decode(UlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);

	TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
	TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream after decoding hdr: ");
	ttcn_buffer.log();
	TTCN_Logger::end_event();
	TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
	TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val after decoding hdr: ");
	ret_val.log();
	TTCN_Logger::end_event();

	/* Manually decoder remainder of ttcn_buffer, containing optional header octets,
	 * optional tlli, optional pfi and LLC Blocks */

	/* optional extension octets, containing LI+M+E of Llc blocks */
	if (ret_val.mac__hdr().e() == false) {
		/* extension octet follows, i.e. optional Llc length octets */
		while (1) {
			/* decode one more extension octet with LlcBlocHdr inside */
			LlcBlock lb;
			lb.hdr()().decode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
			ret_val.blocks()[num_llc_blocks++] = lb;

			TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
			TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream after decoding ExtOct: ");
			ttcn_buffer.log();
			TTCN_Logger::end_event();
			TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
			TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val after decoding ExtOct: ");
			ret_val.log();
			TTCN_Logger::end_event();

			/* if E == '1'B, we can proceed further */
			if (lb.hdr()().e() == true)
				break;
		}
	}

	/* parse optional TLLI */
	if (ret_val.mac__hdr().tlli__ind()) {
		ret_val.tlli() = OCTETSTRING(4, ttcn_buffer.get_read_data());
		ttcn_buffer.increase_pos(4);
	} else {
		ret_val.tlli() = OMIT_VALUE;
	}
	/* parse optional PFI */
	if (ret_val.mac__hdr().pfi__ind()) {
		ret_val.pfi().decode(RlcmacUlDataBlock_pfi_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
	} else {
		ret_val.pfi() = OMIT_VALUE;
	}

	/* RLC blocks at end */
	if (ret_val.mac__hdr().e() == true) {
		LlcBlock lb;
		unsigned int length = ttcn_buffer.get_read_len();
		/* LI not present: The Upper Layer PDU that starts with the current RLC data block either
		 * fills the current RLC data block precisely or continues in the following in-sequence RLC
		 * data block */
		lb.hdr() = OMIT_VALUE;
		lb.payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());
		ttcn_buffer.increase_pos(length);
		ret_val.blocks()[0] = lb;
	} else {
		if (ret_val.blocks().is_bound()) {
			for (int i = 0; i < ret_val.blocks().size_of(); i++) {
				unsigned int length = ret_val.blocks()[i].hdr()().length__ind();
				if (length > ttcn_buffer.get_read_len())
					length = ttcn_buffer.get_read_len();
				ret_val.blocks()[i].payload() = OCTETSTRING(length, ttcn_buffer.get_read_data());
				ttcn_buffer.increase_pos(length);
			}
		}
	}

	TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
	TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): Stream before return: ");
	ttcn_buffer.log();
	TTCN_Logger::end_event();
	TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
	TTCN_Logger::log_event_str("dec_RlcmacUlDataBlock(): ret_val before return: ");
	ret_val.log();
	TTCN_Logger::end_event();

	return ret_val;
}

static
EgprsUlMacDataHeader dec__EgprsUlMacDataHeader_type1(const OCTETSTRING& stream)
{
	EgprsUlMacDataHeader ret_val;

	fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);

	return ret_val;
}

static
EgprsUlMacDataHeader dec__EgprsUlMacDataHeader_type2(const OCTETSTRING& stream)
{
	EgprsUlMacDataHeader ret_val;

	fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);

	return ret_val;
}

static
EgprsUlMacDataHeader dec__EgprsUlMacDataHeader_type3(const OCTETSTRING& stream)
{
	TTCN_Buffer ttcn_buffer(stream);
	EgprsUlMacDataHeader ret_val;
	const struct gprs_rlc_ul_header_egprs_3 *egprs3;
	uint8_t tmp;

	egprs3 = static_cast<const struct gprs_rlc_ul_header_egprs_3 *>
		((const void *)ttcn_buffer.get_data());

	ret_val.header__type() = EgprsHeaderType::RLCMAC__HDR__TYPE__3;
	ret_val.tfi() = egprs3->tfi_lo << 2 | egprs3->tfi_hi << 0;
	ret_val.countdown() = egprs3->cv;
	tmp = egprs3->si;
	ret_val.foi__si() = BITSTRING(1, &tmp);
	tmp = egprs3->r;
	ret_val.r__ri() = BITSTRING(1, &tmp);
	ret_val.bsn1() = egprs3->bsn1_lo << 5 | egprs3->bsn1_hi << 0;
	ret_val.cps() = egprs3->cps_lo << 2 | egprs3->cps_hi << 0;
	ret_val.pfi__ind() = egprs3->pi;
	tmp = egprs3->rsb;
	ret_val.rsb() = BITSTRING(1, &tmp);
	tmp = egprs3->spb;
	ret_val.spb() = BITSTRING(2, &tmp);

	ttcn_buffer.increase_pos(sizeof(*egprs3));
	return ret_val;
}

RlcmacUlEgprsDataBlock dec__RlcmacUlEgprsDataBlock(const OCTETSTRING& stream)
{
	RlcmacUlEgprsDataBlock ret_val;
	TTCN_Buffer ttcn_buffer(stream);
	TTCN_Buffer aligned_buffer;
	int num_llc_blocks = 0;
	unsigned int data_block_bits, data_block_offsets[2];
	unsigned int num_calls;
	const uint8_t *ti_e;

	ret_val.mcs() = payload_len_2_coding_scheme(stream.lengthof());
	switch (ret_val.mcs()) {
	case CodingScheme::MCS__1:
	case CodingScheme::MCS__2:
	case CodingScheme::MCS__3:
	case CodingScheme::MCS__4:
		ret_val.mac__hdr() = dec__EgprsUlMacDataHeader_type3(stream);
		break;
	case CodingScheme::MCS__5:
	case CodingScheme::MCS__6:
		ret_val.mac__hdr() = dec__EgprsUlMacDataHeader_type2(stream);
		break;
	case CodingScheme::MCS__7:
	case CodingScheme::MCS__8:
	case CodingScheme::MCS__9:
		ret_val.mac__hdr() = dec__EgprsUlMacDataHeader_type1(stream);
		break;
	}
	setup_rlc_mac_priv(ret_val.mcs(), ret_val.mac__hdr().header__type(), true,
			   &num_calls, &data_block_bits, data_block_offsets);
	get_egprs_data_block(ttcn_buffer, data_block_offsets[0], data_block_bits, aligned_buffer);

	ti_e = aligned_buffer.get_read_data();
	ret_val.tlli__ind() = *ti_e & 0x02 ? true : false;
	ret_val.e() = *ti_e & 0x01 ? true : false;
	aligned_buffer.increase_pos(1);

	/* Manually decoder remainder of aligned_buffer, containing optional header octets,
	 * optional tlli, optional pfi and LLC Blocks */

	/* optional extension octets, containing LI+M+E of Llc blocks */
	if (ret_val.e() == false) {
		/* extension octet follows, i.e. optional Llc length octets */
		while (1) {
			/* decode one more extension octet with LlcBlocHdr inside */
			EgprsLlcBlock lb;
			lb.hdr()().decode(EgprsLlcBlockHdr_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);
			ret_val.blocks()[num_llc_blocks++] = lb;

			/* if E == '1'B, we can proceed further */
			if (lb.hdr()().e() == true)
				break;
		}
	}

	/* parse optional TLLI */
	if (ret_val.tlli__ind()) {
		ret_val.tlli() = OCTETSTRING(4, aligned_buffer.get_read_data());
		aligned_buffer.increase_pos(4);
	} else {
		ret_val.tlli() = OMIT_VALUE;
	}
	/* parse optional PFI */
	if (ret_val.mac__hdr().pfi__ind()) {
		ret_val.pfi().decode(RlcmacUlEgprsDataBlock_pfi_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);
	} else {
		ret_val.pfi() = OMIT_VALUE;
	}

	/* RLC blocks at end */
	if (ret_val.e() == true) {
		EgprsLlcBlock lb;
		unsigned int length = aligned_buffer.get_read_len();
		/* LI not present: The Upper Layer PDU that starts with the current RLC data block either
		 * fills the current RLC data block precisely or continues in the following in-sequence RLC
		 * data block */
		lb.hdr() = OMIT_VALUE;
		lb.payload() = OCTETSTRING(length, aligned_buffer.get_read_data());
		aligned_buffer.increase_pos(length);
		ret_val.blocks()[0] = lb;
	} else {
		if (ret_val.blocks().is_bound()) {
			for (int i = 0; i < ret_val.blocks().size_of(); i++) {
				unsigned int length = ret_val.blocks()[i].hdr()().length__ind();
				if (length > aligned_buffer.get_read_len())
					length = aligned_buffer.get_read_len();
				ret_val.blocks()[i].payload() = OCTETSTRING(length, aligned_buffer.get_read_data());
				aligned_buffer.increase_pos(length);
			}
		}
	}

	return ret_val;
}

RlcmacUlBlock dec__RlcmacUlBlock(const OCTETSTRING& stream)
{
	RlcmacUlBlock ret_val;
	size_t stream_len = stream.lengthof();
	CodingScheme::enum_type cs_mcs = payload_len_2_coding_scheme(stream_len);
	unsigned char pt;

	switch (cs_mcs) {
	case CodingScheme::CS__1:
	case CodingScheme::CS__2:
	case CodingScheme::CS__3:
	case CodingScheme::CS__4:
		pt = stream[0].get_octet() >> 6;
		if (pt == MacPayloadType::MAC__PT__RLC__DATA)
			ret_val.data() = dec__RlcmacUlDataBlock(stream);
		else
			ret_val.ctrl() = dec__RlcmacUlCtrlBlock(stream);
		break;
	case CodingScheme::MCS__1:
	case CodingScheme::MCS__2:
	case CodingScheme::MCS__3:
	case CodingScheme::MCS__4:
	case CodingScheme::MCS__5:
	case CodingScheme::MCS__6:
	case CodingScheme::MCS__7:
	case CodingScheme::MCS__8:
	case CodingScheme::MCS__9:
		ret_val.data__egprs() = dec__RlcmacUlEgprsDataBlock(stream);
		break;
	}

	return ret_val;
}


/////////////////////
// ENCODE
/////////////////////

/* ENCODE DOWNLINK */

OCTETSTRING enc__RlcmacDlDataBlock(const RlcmacDlDataBlock& si)
{
	RlcmacDlDataBlock in = si;
	OCTETSTRING ret_val;
	TTCN_Buffer ttcn_buffer;
	int i;

	/* Fix 'e' bit of initial header based on following blocks */
	if (!in.blocks().is_bound() ||
	    (in.blocks().size_of() == 1 && !in.blocks()[0].hdr().is_bound()))
		in.mac__hdr().hdr__ext().e() = true;
	else
		in.mac__hdr().hdr__ext().e() = false;

	/* use automatic/generated decoder for header */
	in.mac__hdr().encode(DlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);

	/* Add LI octets, if any */
	if (in.blocks().is_bound() &&
	    (in.blocks().size_of() != 1 || in.blocks()[0].hdr().is_bound())) {
		/* first write LI octets */
		for (i = 0; i < in.blocks().size_of(); i++) {
			/* fix the 'E' bit in case it is not clear */
			if (i < in.blocks().size_of()-1)
				in.blocks()[i].hdr()().e() = false;
			else
				in.blocks()[i].hdr()().e() = true;
			in.blocks()[i].hdr()().encode(LlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
		}
	}
	if (in.blocks().is_bound()) {
		for (i = 0; i < in.blocks().size_of(); i++) {
			if (!in.blocks()[i].is_bound())
				continue;
			ttcn_buffer.put_string(in.blocks()[i].payload());
		}
	}

	encode_trailing_padding_spb(ttcn_buffer, in.cs());

	ttcn_buffer.get_string(ret_val);
	return ret_val;
}

static
void enc__RlcmacDlEgprsDataHeader_type1(const EgprsDlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)
{
	fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);
}

static
void enc__RlcmacDlEgprsDataHeader_type2(const EgprsDlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)
{
	fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);
}

static
void enc__RlcmacDlEgprsDataHeader_type3(const EgprsDlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)
{
	fprintf(stderr, "FIXME: Not implemented! %s (%s:%u)\n", __func__, __FILE__, __LINE__);
}

OCTETSTRING enc__RlcmacDlEgprsDataBlock(const RlcmacDlEgprsDataBlock& si)
{
	RlcmacDlEgprsDataBlock in = si;
	OCTETSTRING ret_val;
	TTCN_Buffer ttcn_buffer;
	int i;

	/* Fix 'e' bit of initial header based on following blocks */
	if (!in.blocks().is_bound() ||
	    (in.blocks().size_of() == 1 && !in.blocks()[0].hdr().is_bound()))
		in.e() = true;
	else
		in.e() = false;

	switch (in.mac__hdr().header__type()) {
	case EgprsHeaderType::RLCMAC__HDR__TYPE__1:
		enc__RlcmacDlEgprsDataHeader_type1(si.mac__hdr(), ttcn_buffer);
		break;
	case EgprsHeaderType::RLCMAC__HDR__TYPE__2:
		enc__RlcmacDlEgprsDataHeader_type2(si.mac__hdr(), ttcn_buffer);
		break;
	case EgprsHeaderType::RLCMAC__HDR__TYPE__3:
		enc__RlcmacDlEgprsDataHeader_type3(si.mac__hdr(), ttcn_buffer);
	default:
		break; /* TODO: error */
	}

	/* Add LI octets, if any */
	if (in.blocks().is_bound() &&
	    (in.blocks().size_of() != 1 || in.blocks()[0].hdr().is_bound())) {
		/* first write LI octets */
		for (i = 0; i < in.blocks().size_of(); i++) {
			/* fix the 'E' bit in case it is not clear */
			if (i < in.blocks().size_of()-1)
				in.blocks()[i].hdr()().e() = false;
			else
				in.blocks()[i].hdr()().e() = true;
			in.blocks()[i].hdr()().encode(EgprsLlcBlockHdr_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
		}
	}
	if (in.blocks().is_bound()) {
		for (i = 0; i < in.blocks().size_of(); i++) {
			if (!in.blocks()[i].is_bound())
				continue;
			ttcn_buffer.put_string(in.blocks()[i].payload());
		}
	}

	encode_trailing_padding_spb(ttcn_buffer, in.mcs());

	ttcn_buffer.get_string(ret_val);
	return ret_val;
}

OCTETSTRING enc__RlcmacDlBlock(const RlcmacDlBlock& si)
{
	if (si.ischosen(RlcmacDlBlock::ALT_data__egprs))
		return enc__RlcmacDlEgprsDataBlock(si.data__egprs());
	else if (si.ischosen(RlcmacDlBlock::ALT_data))
		return enc__RlcmacDlDataBlock(si.data());
	else
		return enc__RlcmacDlCtrlBlock(si.ctrl());
}

/* ENCODE UPLINK */

OCTETSTRING enc__RlcmacUlDataBlock(const RlcmacUlDataBlock& si)
{
	RlcmacUlDataBlock in = si;
	OCTETSTRING ret_val;
	TTCN_Buffer ttcn_buffer;
	int i;

	if (!in.blocks().is_bound()) {
		/* we don't have any blocks: Add length value (zero) */
		in.mac__hdr().e() = false; /* E=0: extension octet follows */
	} else if (in.blocks().size_of() == 1 && in.blocks()[0].hdr() == OMIT_VALUE) {
		/* If there's only a single block, and that block has no HDR value defined, */
		in.mac__hdr().e() = true; /* E=0: extension octet follows */
	} else {
		/* Length value */
		in.mac__hdr().e() = false;
	}

	/* Fix other presence indications */
	in.mac__hdr().tlli__ind() = in.tlli().is_bound() && in.tlli() != OMIT_VALUE;
	in.mac__hdr().pfi__ind() = in.pfi().is_bound() && in.pfi() != OMIT_VALUE;

	/* use automatic/generated encoder for header */
	in.mac__hdr().encode(UlMacDataHeader_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);

	if (in.mac__hdr().e() == false) {
		/* Add LI octets, if any */
		if (!in.blocks().is_bound()) {
			ttcn_buffer.put_c(0x01); /* M=0, E=1 LEN=0 */
		} else {
			for (i = 0; i < in.blocks().size_of(); i++) {
#if 0
				/* check for penultimate block */
				if (i == in.blocks().size_of()-2) {
					/* if last block has no header, no more LI */
					if (in.blocks()[i+1].hdr() == OMIT_VALUE) {
						in.blocks()[i].hdr()().more() = true;
					} else {
						/* header present, we have to encode LI */
						in.blocks()[i].hdr()().more() = false;
						in.blocks()[i].hdr()().length__ind() =
								in.blocks()[i+1].payload().lengthof();
					}
				} else if (i < in.blocks().size_of()-2) {
					/* one of the first blocks, before the penultimate or last */
					in.blocks()[i].hdr()().e() = false; /* LI present */
					/* re-compute length */
					in.blocks()[i].hdr()().length__ind() =
								in.blocks()[i+1].payload().lengthof();
				}
				/* Encode LI octet if E=0 */
				}
#endif
				if (in.blocks()[i].hdr() != OMIT_VALUE) {
					in.blocks()[i].hdr()().encode(LlcBlockHdr_descr_, ttcn_buffer,
									TTCN_EncDec::CT_RAW);
				}
			}
		}
	}

	if (in.mac__hdr().tlli__ind()) {
		ttcn_buffer.put_string(in.tlli());
	}

	if (in.mac__hdr().pfi__ind()) {
		in.pfi().encode(RlcmacUlDataBlock_pfi_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
	}

	if (in.blocks().is_bound()) {
		for (i = 0; i < in.blocks().size_of(); i++) {
			if (!in.blocks()[i].is_bound())
				continue;
			ttcn_buffer.put_string(in.blocks()[i].payload());
		}
	}

	encode_trailing_padding_spb(ttcn_buffer, in.cs());

	ttcn_buffer.get_string(ret_val);
	return ret_val;
}

static
void enc__RlcmacUlEgprsDataHeader_type1(const EgprsUlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)
{
	struct gprs_rlc_ul_header_egprs_1 egprs1;

	egprs1.r = bs2uint8(si.r__ri());
	egprs1.si = bs2uint8(si.foi__si());
	egprs1.cv = si.countdown();
	egprs1.tfi_hi = si.tfi() >> 0;
	egprs1.tfi_lo = si.tfi() >> 2;
	egprs1.bsn1_hi = si.bsn1() >> 0;
	egprs1.bsn1_lo = si.bsn1() >> 5;
	egprs1.bsn2_hi = si.bsn2__offset() >> 0;
	egprs1.bsn2_lo = si.bsn2__offset() >> 2;
	egprs1.cps = si.cps();
	egprs1.rsb = bs2uint8(si.rsb());
	egprs1.pi = si.pfi__ind();
	egprs1.spare_hi = 0;
	egprs1.spare_lo = 0;
	egprs1.dummy = 0;

	ttcn_buffer.put_s(sizeof(egprs1), (const unsigned char *)&egprs1);
}

static
void enc__RlcmacUlEgprsDataHeader_type2(const EgprsUlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)
{
	struct gprs_rlc_ul_header_egprs_2 egprs2;

	egprs2.r = bs2uint8(si.r__ri());
	egprs2.si = bs2uint8(si.foi__si());
	egprs2.cv = si.countdown();
	egprs2.tfi_hi = si.tfi() >> 0;
	egprs2.tfi_lo = si.tfi() >> 2;
	egprs2.bsn1_hi = si.bsn1() >> 0;
	egprs2.bsn1_lo = si.bsn1() >> 5;
	egprs2.cps_hi = si.cps() >> 0;
	egprs2.cps_lo = si.cps() >> 2;
	egprs2.rsb = bs2uint8(si.rsb());
	egprs2.pi = si.pfi__ind();
	egprs2.spare_hi = 0;
	egprs2.spare_lo = 0;
	egprs2.dummy = 0;

	ttcn_buffer.put_s(sizeof(egprs2), (const unsigned char *)&egprs2);
}

static
void enc__RlcmacUlEgprsDataHeader_type3(const EgprsUlMacDataHeader& si, TTCN_Buffer& ttcn_buffer)
{
	struct gprs_rlc_ul_header_egprs_3 egprs3;

	egprs3.r = bs2uint8(si.r__ri());
	egprs3.si = bs2uint8(si.foi__si());
	egprs3.cv = si.countdown();
	egprs3.tfi_hi = si.tfi() >> 0;
	egprs3.tfi_lo = si.tfi() >> 2;
	egprs3.bsn1_hi = si.bsn1() >> 0;
	egprs3.bsn1_lo = si.bsn1() >> 5;
	egprs3.cps_hi = si.cps() >> 0;
	egprs3.cps_lo = si.cps() >> 2;
	egprs3.spb = bs2uint8(si.spb());
	egprs3.rsb = bs2uint8(si.rsb());
	egprs3.pi = si.pfi__ind();
	egprs3.spare = 0;
	egprs3.dummy = 0;

	ttcn_buffer.put_s(sizeof(egprs3), (const unsigned char *)&egprs3);
}

OCTETSTRING enc__RlcmacUlEgprsDataBlock(const RlcmacUlEgprsDataBlock& si)
{
	RlcmacUlEgprsDataBlock in = si;
	OCTETSTRING ret_val;
	TTCN_Buffer ttcn_buffer, aligned_buffer;
	int i;
	unsigned int data_block_bits, data_block_offsets[2];
	unsigned int num_calls;
	CodingScheme mcs;

	mcs = RLCMAC__Templates::f__rlcmac__cps__htype__to__mcs(in.mac__hdr().cps(), in.mac__hdr().header__type());
	//fprintf(stderr, "RLCMAC: infered MCS %s (%d)\n", mcs.enum_to_str(static_cast<CodingScheme::enum_type>(mcs.as_int())), mcs.as_int());

	if (!in.blocks().is_bound()) {
		/* we don't have nay blocks: Add length value (zero) */
		in.e() = false; /* E=0: extension octet follows */
	} else if (in.blocks().size_of() == 1 && in.blocks()[0].hdr() == OMIT_VALUE) {
		/* If there's only a single block, and that block has no HDR value defined, */
		in.e() = true; /* E=0: extension octet follows */
	} else {
		/* Length value */
		in.e() = false;
	}

	/* Fix other presence indications */
	in.tlli__ind() = in.tlli().is_bound() && in.tlli() != OMIT_VALUE;
	in.mac__hdr().pfi__ind() = in.pfi().is_bound() && in.pfi() != OMIT_VALUE;

	switch (in.mac__hdr().header__type()) {
	case EgprsHeaderType::RLCMAC__HDR__TYPE__1:
		enc__RlcmacUlEgprsDataHeader_type1(in.mac__hdr(), ttcn_buffer);
		break;
	case EgprsHeaderType::RLCMAC__HDR__TYPE__2:
		enc__RlcmacUlEgprsDataHeader_type2(in.mac__hdr(), ttcn_buffer);
		break;
	case EgprsHeaderType::RLCMAC__HDR__TYPE__3:
		enc__RlcmacUlEgprsDataHeader_type3(in.mac__hdr(), ttcn_buffer);
	default:
		break; /* TODO: error */
	}

	/* Put first TI + E byte */
	aligned_buffer.put_c((in.tlli__ind() & 0x01) << 1 | (in.e() & 0x01) << 0);
	//printbuffer("After encoding first byte", aligned_buffer);

	if (in.e() == false) {
		/* Add LI octets, if any */
		if (!in.blocks().is_bound()) {
			aligned_buffer.put_c(0x01); /* M=0, E=1 LEN=0 */
		} else {
			for (i = 0; i < in.blocks().size_of(); i++) {
#if 0
				/* check for penultimate block */
				if (i == in.blocks().size_of()-2) {
					/* if last block has no header, no more LI */
					if (in.blocks()[i+1].hdr() == OMIT_VALUE) {
						in.blocks()[i].hdr()().more() = true;
					} else {
						/* header present, we have to encode LI */
						in.blocks()[i].hdr()().more() = false;
						in.blocks()[i].hdr()().length__ind() =
								in.blocks()[i+1].payload().lengthof();
					}
				} else if (i < in.blocks().size_of()-2) {
					/* one of the first blocks, before the penultimate or last */
					in.blocks()[i].hdr()().e() = false; /* LI present */
					/* re-compute length */
					in.blocks()[i].hdr()().length__ind() =
								in.blocks()[i+1].payload().lengthof();
				}
				/* Encode LI octet if E=0 */
				}
#endif
				if (in.blocks()[i].hdr() != OMIT_VALUE) {
					in.blocks()[i].hdr()().encode(EgprsLlcBlockHdr_descr_, aligned_buffer,
									TTCN_EncDec::CT_RAW);
				}
			}
		}
	}



	if (in.tlli__ind()) {
		/* The TLLI is encoded in little endian for EGPRS (see
		 * TS 44.060, figure 10.3a.2.1, note 2) */
		OCTETSTRING tlli = in.tlli();
		aligned_buffer.put_c(tlli[3].get_octet());
		aligned_buffer.put_c(tlli[2].get_octet());
		aligned_buffer.put_c(tlli[1].get_octet());
		aligned_buffer.put_c(tlli[0].get_octet());
	}

	if (in.mac__hdr().pfi__ind()) {
		in.pfi().encode(RlcmacUlEgprsDataBlock_pfi_descr_, aligned_buffer, TTCN_EncDec::CT_RAW);
	}

	//printbuffer("Before encoding EgprsLlc payload", aligned_buffer);
	if (in.blocks().is_bound()) {
		for (i = 0; i < in.blocks().size_of(); i++) {
			if (!in.blocks()[i].is_bound())
				continue;
			aligned_buffer.put_string(in.blocks()[i].payload());
		}
	}
	//printbuffer("After encoding EgprsLlc payload", aligned_buffer);

	setup_rlc_mac_priv(mcs, in.mac__hdr().header__type(), true,
			   &num_calls, &data_block_bits, data_block_offsets);
	//printbuffer("before merging data block", ttcn_buffer);
	put_egprs_data_block(aligned_buffer, data_block_offsets[0], data_block_bits, ttcn_buffer);
	//printbuffer("after merging data block", ttcn_buffer);

	encode_trailing_padding_spb(ttcn_buffer, in.mcs());

	ttcn_buffer.get_string(ret_val);
	return ret_val;
}

OCTETSTRING enc__RlcmacUlBlock(const RlcmacUlBlock& si)
{
	if (si.ischosen(RlcmacUlBlock::ALT_data__egprs))
		return enc__RlcmacUlEgprsDataBlock(si.data__egprs());
	else if (si.ischosen(RlcmacUlBlock::ALT_data))
		return enc__RlcmacUlDataBlock(si.data());
	else
		return enc__RlcmacUlCtrlBlock(si.ctrl());
}

} // namespace
