[MERGED] osmo-ttcn3-hacks[master]: Add 3GPP TS 25.415 IuUP encoder/decoder

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/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Sun Dec 24 23:05:01 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: Add 3GPP TS 25.415 IuUP encoder/decoder
......................................................................


Add 3GPP TS 25.415 IuUP encoder/decoder

Change-Id: Ie04438d8ec2b796e9e56b1937fa024a5299457dd
---
A library/IuUP_Emulation.ttcn
A library/IuUP_EncDec.cc
A library/IuUP_Types.ttcn
3 files changed, 725 insertions(+), 0 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/library/IuUP_Emulation.ttcn b/library/IuUP_Emulation.ttcn
new file mode 100644
index 0000000..ec25e49
--- /dev/null
+++ b/library/IuUP_Emulation.ttcn
@@ -0,0 +1,137 @@
+module IuUP_Emulation {
+
+import from Osmocom_Types all;
+import from IuUP_Types all;
+
+
+type record IuUP_RabFlowCombination {
+	IuUP_RFCI rfci,
+	/* number of bits per sub-flow */
+	RecOfU8	sub_flow_bits,
+	/* IPTI value in number of ITIs for the corresponding RFCI */
+	uint8_t ipti
+};
+
+template (value) IuUP_RabFlowCombination t_IuUP_RFC(IuUP_RFCI rfci, RecOfU8 subflow_bits, uint8_t ipti) := {
+	rfci := rfci,
+	sub_flow_bits := subflow_bits,
+	ipti := ipti
+}
+
+template (value) IuUP_RabFlowCombination t_IuUP_RFC_AMR_12_2(IuUP_RFCI rfci) := t_IuUP_RFC(rfci, {81, 103, 60}, 1);
+template (value) IuUP_RabFlowCombination t_IuUP_RFC_AMR_SID(IuUP_RFCI rfci) := t_IuUP_RFC(rfci, {34, 0, 0}, 7);
+
+type record IuUP_Config {
+	/* actively send INIT (true) or only passively respond (false) */
+	boolean active_init,
+	boolean data_pdu_type_0,
+	/* RAB Flow Combinations */
+	record of IuUP_RabFlowCombination rab_flow_combs
+};
+
+type enumerated IuUP_Em_State {
+	ST_INIT,
+	ST_DATA_TRANSFER_READY
+};
+
+
+
+type record IuUP_Entity {
+	IuUP_Config cfg,
+	IuUP_Em_State state,
+	IuUP_FrameNr tx_next_frame_nr,
+	IuUP_FrameNr rx_last_frame_nr optional,
+	IuUP_PDU pending_tx_pdu optional
+};
+
+template (value) IuUP_Entity t_IuUP_Entity(boolean act_init) := {
+	cfg := {
+		active_init := act_init,
+		data_pdu_type_0 := true,
+		rab_flow_combs := { t_IuUP_RFC_AMR_12_2(0), t_IuUP_RFC_AMR_SID(1) }
+	},
+	state := ST_INIT,
+	tx_next_frame_nr := 0,
+	rx_last_frame_nr := omit,
+	pending_tx_pdu := omit
+}
+
+
+function f_IuUP_Em_rx_decaps(inout IuUP_Entity st, octetstring inp) return octetstring {
+	var IuUP_PDU pdu := dec_IuUP_PDU(inp);
+	if (ischosen(pdu.type_0)) {
+		if (st.cfg.data_pdu_type_0) {
+			/* FIXME: check header / CRC */
+			st.rx_last_frame_nr := pdu.type_0.frame_nr;
+			return pdu.type_0.payload;
+		} else {
+			setverdict(fail, "PDU Type 0 received but 1 configured");
+		}
+	} else if (ischosen(pdu.type_1)) {
+		if (st.cfg.data_pdu_type_0 == false) {
+			/* FIXME: check header / CRC */
+			st.rx_last_frame_nr := pdu.type_1.frame_nr;
+			return pdu.type_1.payload;
+		} else {
+			setverdict(fail, "PDU Type 1 received but 0 configured");
+		}
+	} else if (ischosen(pdu.type_14)) {
+		if (match(pdu, tr_IuUP_INIT)) {
+			if (st.cfg.active_init == true) {
+				setverdict(fail, "INIT received in ACTIVE role");
+			} else {
+				/* store an INIT_ACK to be transmitted later */
+				st.pending_tx_pdu := valueof(ts_IuUP_INIT_ACK(pdu.type_14.frame_nr,
+									pdu.type_14.iuup_version));
+			}
+		} else if (match(pdu, tr_IuUP_INIT_ACK)) {
+			if (st.cfg.active_init == true) {
+				log("IuUP INIT_ACK Received");
+				st.state := ST_DATA_TRANSFER_READY;
+			} else {
+				setverdict(fail, "INIT_ACK received in PASSIVE role");
+			}
+		}
+		return ''O;
+	} else {
+		setverdict(fail, "Impossible IuUP PDU decoded from ", inp);
+	}
+	self.stop;
+}
+
+function f_IuUP_Em_tx_encap(inout IuUP_Entity st, in octetstring payload) return octetstring {
+	var IuUP_PDU pdu;
+	select (st.state) {
+		case (ST_INIT) {
+			if (st.cfg.active_init) {
+				/* send INIT */
+				pdu := valueof(ts_IuUP_INIT('160051673C01270000820000001710000100'O));
+			} else {
+				/* wait for INIT */
+				if (isvalue(st.pending_tx_pdu)) {
+					/* we're waiting to transmit the INIT_ACK in response to an
+					 * init (passive) */
+					pdu := st.pending_tx_pdu;
+					st.pending_tx_pdu := omit;
+					st.state := ST_DATA_TRANSFER_READY;
+				}
+			}
+		}
+		case (ST_DATA_TRANSFER_READY) {
+			if (st.cfg.data_pdu_type_0) {
+				pdu := valueof(ts_IuUP_Type0(st.tx_next_frame_nr, 0, payload));
+			} else {
+				pdu := valueof(ts_IuUP_Type1(st.tx_next_frame_nr, 0, payload));
+			}
+			st.tx_next_frame_nr := st.tx_next_frame_nr + 1;
+		}
+	}
+	if (isvalue(pdu)) {
+		return f_enc_IuUP_PDU(pdu);
+	} else {
+		return ''O;
+	}
+}
+
+
+}
diff --git a/library/IuUP_EncDec.cc b/library/IuUP_EncDec.cc
new file mode 100644
index 0000000..81742e8
--- /dev/null
+++ b/library/IuUP_EncDec.cc
@@ -0,0 +1,250 @@
+
+#include "Octetstring.hh"
+#include "Error.hh"
+#include "Logger.hh"
+
+#include "IuUP_Types.hh"
+
+#include <stdint.h>
+
+extern "C" {
+
+typedef uint8_t ubit_t;
+typedef uint8_t pbit_t;
+
+static int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits)
+{
+	unsigned int i;
+	ubit_t *cur = out;
+	ubit_t *limit = out + num_bits;
+
+	for (i = 0; i < (num_bits/8)+1; i++) {
+		pbit_t byte = in[i];
+		*cur++ = (byte >> 7) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 6) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 5) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 4) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 3) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 2) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 1) & 1;
+		if (cur >= limit)
+			break;
+		*cur++ = (byte >> 0) & 1;
+		if (cur >= limit)
+			break;
+	}
+	return cur - out;
+}
+
+
+struct osmo_crc8gen_code {
+	int bits;           /*!< Actual number of bits of the CRC */
+	uint8_t poly;      /*!< Polynom (normal representation, MSB omitted */
+	uint8_t init;      /*!< Initialization value of the CRC state */
+	uint8_t remainder; /*!< Remainder of the CRC (final XOR) */
+};
+
+static uint8_t
+osmo_crc8gen_compute_bits(const struct osmo_crc8gen_code *code,
+                           const ubit_t *in, int len)
+{
+	const uint8_t poly = code->poly;
+	uint8_t crc = code->init;
+	int i, n = code->bits-1;
+
+	for (i=0; i<len; i++) {
+		uint8_t bit = in[i] & 1;
+		crc ^= (bit << n);
+		if (crc & ((uint8_t)1 << n)) {
+			crc <<= 1;
+			crc ^= poly;
+		} else {
+			crc <<= 1;
+		}
+		crc &= ((uint8_t)1 << code->bits) - 1;
+	}
+
+	crc ^= code->remainder;
+
+	return crc;
+}
+
+struct osmo_crc16gen_code {
+	int bits;           /*!< Actual number of bits of the CRC */
+	uint16_t poly;      /*!< Polynom (normal representation, MSB omitted */
+	uint16_t init;      /*!< Initialization value of the CRC state */
+	uint16_t remainder; /*!< Remainder of the CRC (final XOR) */
+};
+
+static uint16_t
+osmo_crc16gen_compute_bits(const struct osmo_crc16gen_code *code,
+                           const ubit_t *in, int len)
+{
+	const uint16_t poly = code->poly;
+	uint16_t crc = code->init;
+	int i, n = code->bits-1;
+
+	for (i=0; i<len; i++) {
+		uint16_t bit = in[i] & 1;
+		crc ^= (bit << n);
+		if (crc & ((uint16_t)1 << n)) {
+			crc <<= 1;
+			crc ^= poly;
+		} else {
+			crc <<= 1;
+		}
+		crc &= ((uint16_t)1 << code->bits) - 1;
+	}
+
+	crc ^= code->remainder;
+
+	return crc;
+}
+
+}
+
+
+static const struct osmo_crc8gen_code iuup_hdr_crc_code = {
+	.bits = 6,
+	.poly = 47,
+	.init = 0,
+	.remainder = 0,
+};
+
+static const struct osmo_crc16gen_code iuup_data_crc_code = {
+	.bits = 10,
+	.poly = 563,
+	.init = 0,
+	.remainder = 0,
+};
+
+static int iuup_get_payload_offset(const uint8_t *iuup_pdu)
+{
+	uint8_t pdu_type = iuup_pdu[0] >> 4;
+	switch (pdu_type) {
+	case 0:
+	case 14:
+		return 4;
+	case 1:
+		return 3;
+	default:
+		return -1;
+	}
+}
+
+int osmo_iuup_compute_payload_crc(const uint8_t *iuup_pdu, unsigned int pdu_len)
+{
+	ubit_t buf[1024*8];
+	uint8_t pdu_type;
+	int offset, payload_len_bytes;
+
+	if (pdu_len < 1)
+		return -1;
+
+	pdu_type = iuup_pdu[0] >> 4;
+
+	/* Type 1 has no CRC */
+	if (pdu_type == 1)
+		return 0;
+
+	offset = iuup_get_payload_offset(iuup_pdu);
+	if (offset < 0)
+		return offset;
+
+	if (pdu_len < (unsigned int)offset)
+		return -1;
+
+	payload_len_bytes = pdu_len - offset;
+	osmo_pbit2ubit(buf, iuup_pdu+offset, payload_len_bytes*8);
+	return osmo_crc16gen_compute_bits(&iuup_data_crc_code, buf, payload_len_bytes*8);
+}
+
+int osmo_iuup_compute_header_crc(const uint8_t *iuup_pdu, unsigned int pdu_len)
+{
+	ubit_t buf[2*8];
+
+	if (pdu_len < 2)
+		return -1;
+
+	osmo_pbit2ubit(buf, iuup_pdu, 2*8);
+	return osmo_crc8gen_compute_bits(&iuup_hdr_crc_code, buf, 2*8);
+}
+/* IuUP CRC Implementation */
+
+/* (C) 2017 by Harald Welte <laforge at gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace IuUP__Types {
+
+
+INTEGER f__IuUP__compute__crc__payload(OCTETSTRING const &in)
+{
+	int crc_calc;
+	const unsigned char *data = (const unsigned char *)in;
+	int len = in.lengthof();
+
+	crc_calc = osmo_iuup_compute_payload_crc(data, len);
+
+	return INTEGER(crc_calc);
+}
+
+INTEGER f__IuUP__compute__crc__header(OCTETSTRING const &in)
+{
+	int crc_calc;
+	const unsigned char *data = (const unsigned char *)in;
+	int len = in.lengthof();
+
+	crc_calc = osmo_iuup_compute_header_crc(data, len);
+
+	return INTEGER(crc_calc);
+}
+
+OCTETSTRING f__enc__IuUP__PDU(const IuUP__PDU& pdu)
+{
+	TTCN_Buffer buf;
+	int crc_hdr, crc_payload;
+	uint8_t in[2];
+	pdu.encode(IuUP__PDU_descr_, buf, TTCN_EncDec::CT_RAW);
+	OCTETSTRING ret_val(buf.get_len(), buf.get_data());
+
+	crc_hdr = osmo_iuup_compute_header_crc(buf.get_data(), buf.get_len());
+	crc_payload = osmo_iuup_compute_payload_crc(buf.get_data(), buf.get_len());
+	in[0] = (crc_hdr & 0x3f) << 2;
+	in[0] |= (crc_payload & 0x3ff) >> 8;
+	in[1] = crc_payload & 0xff;
+	OCTETSTRING CHECKSUM(2, in);
+
+	ret_val = substr(ret_val, 0, 2) + CHECKSUM + substr(ret_val, 4, ret_val.lengthof()-4);
+
+	return ret_val;
+}
+
+}
diff --git a/library/IuUP_Types.ttcn b/library/IuUP_Types.ttcn
new file mode 100644
index 0000000..933b64f
--- /dev/null
+++ b/library/IuUP_Types.ttcn
@@ -0,0 +1,338 @@
+module IuUP_Types {
+
+import from Osmocom_Types all;
+import from General_Types all;
+
+/* See TS 25.415 6.6.3.1 */
+type uint4_t IuUP_PDU_Type;
+
+/* See TS 25.415 6.6.3.2 */
+type enumerated IuUP_AckNack {
+	IuUP_ACKNACK_CTRL	(0),
+	IuUP_ACKNACK_ACK	(1),
+	IuUP_ACKNACK_NACK	(2),
+	IuUP_ACKNACK_RESERVED	(3)
+} with { variant "FIELDLENGTH(2)" };
+
+/* See TS 25.415 6.6.3.3 */
+type uint4_t IuUP_FrameNr;
+
+/* See TS 25.415 6.6.3.5 */
+type enumerated IuUP_FQC {
+	IuUP_FQC_GOOD		(0),
+	IuUP_FQC_BAD		(1),
+	IuUP_FQC_BAD_RADIO	(2),
+	IuUP_FQC_SPARE		(3)
+} with { variant "FIELDLENGTH(2)" };
+
+/* See TS 25.415 6.6.3.6 */
+type uint6_t IuUP_RFCI;
+
+/* See TS 25.415 6.6.3.7 */
+type enumerated IuUP_ProcedureIndicator {
+	IuUP_PRI_INITIALIZATION		(0),
+	IuUP_PRI_RATE_CONTROL		(1),
+	IuUP_PRI_TIME_ALIGNMENT		(2),
+	IuUP_PRI_ERROR_EVENT		(3)
+	/* reserved */
+} with { variant "FIELDLENGTH(4)" };
+
+/* See TS 25.415 6.6.3.13 */
+type uint6_t IuUP_NumOfRfciInd;
+
+/* See TS 25.415 6.6.3.15 */
+type enumerated IuUP_ErrorDistance {
+	IuUP_ERR_DIST_LOCAL		(0),
+	IuUP_ERR_DIST_FIRST_FW		(1),
+	IuUP_ERR_DIST_SECOND_FW		(2),
+	IuUP_ERR_DIST_RESERVED		(3)
+} with { variant "FIELDLENGTH(2)" };
+
+/* See TS 25.415 6.6.3.16 */
+type enumerated IuUP_ErrorCause {
+	/* Syntactical protocol errors */
+	IuUP_CAUSE_CRC_ERROR_HEADER	(0),
+	IuUP_CAUSE_CRC_ERROR_PAYLOAD	(1),
+	IuUP_CAUSE_UNEXP_FRAME_NR	(2),
+	IuUP_CAUSE_FRAME_LOSS		(3),
+	IuUP_CAUSE_PDU_TYPE_UNKNOWN	(4),
+	IuUP_CAUSE_UNKNOWN_PROCEDURE	(5),
+	IuUP_CAUSE_UNKNOWN_RES_VAL	(6),
+	IuUP_CAUSE_UNKNOWN_FIELD	(7),
+	IuUP_CAUSE_FRAME_TOO_SHORT	(8),
+	IuUP_CAUSE_MISSING_FIELD	(9),
+	/* Semantical protocol errors */
+	IuUP_CAUSE_UNEXPECTED_PDU_TYPE	(16),
+	IuUP_CAUSE_UNEXPECTED_PROCEDURE	(18),
+	IuUP_CAUSE_UNEXPECTED_RFCI	(19),
+	IuUP_CAUSE_UNEXPECTED_VALUE	(20),
+	/* Other Errors */
+	IuUP_CAUSE_INIT_FAIL		(42),
+	IuUP_CAUSE_INIT_FAIL_NET_TMR_EXP	(43),
+	IuUP_CAUSE_INIT_FAIL_FERR_REP_NACK	(44),
+	IuUP_CAUSE_RATE_CONTROL_FAIL	(45),
+	IuUP_CAUSE_ERROR_EVENT_FAIL	(46),
+	IuUP_CAUSE_TIME_ALIGN_NOTSUPP	(47),
+	IuUP_CAUSE_REQ_ALIGN_NOTPOSS	(48),
+	IuUP_CAUSE_IU_UP_VERS_NOTSUPP	(49)
+} with { variant "FIELDLENGTH(6)" };
+
+/* See TS 25.415 6.6.3.18 */
+type uint8_t IuUP_TimeAlignment;
+
+
+/* See TS 25.415 6.6.2.1 */
+type record IuUP_PDU_Type_0 {
+	IuUP_PDU_Type	pdu_type,	/* 0 */
+	IuUP_FrameNr	frame_nr,
+	IuUP_FQC	fqc,
+	IuUP_RFCI	rfci,
+	uint6_t		header_crc,
+	uint10_t	payload_crc,
+	octetstring	payload
+};
+
+/* See TS 25.415 6.6.2.2 */
+type record IuUP_PDU_Type_1 {
+	IuUP_PDU_Type	pdu_type,	/* 1 */
+	IuUP_FrameNr	frame_nr,
+	IuUP_FQC	fqc,
+	IuUP_RFCI	rfci,
+	uint6_t		header_crc,
+	BIT2		spare,
+	octetstring	payload
+};
+
+/* See TS 25.415 6.6.6.2.3 */
+type record IuUP_PDU_Type_14 {
+	IuUP_PDU_Type	pdu_type,
+	IuUP_AckNack	ack_nack,
+	uint2_t		frame_nr,
+	uint4_t		iuup_version,
+	IuUP_ProcedureIndicator	procedure_ind,
+	uint6_t		header_crc,
+	uint10_t	payload_crc,
+	IuUP_PDU14_Union u
+} with { variant (u) "CROSSTAG(	proc_sending,	ack_nack=IuUP_ACKNACK_CTRL;
+				ack,		ack_nack=IuUP_ACKNACK_ACK;
+				nack,		ack_nack=IuUP_ACKNACK_NACK)"
+};
+
+/* 6.6.2.3.1 Figure 21 */
+type record IuUP_PDU14_ProcSending {
+	octetstring	payload
+};
+
+/* 6.6.2.3.2 Figure 22 */
+type record IuUP_PDU14_ACK {
+	octetstring	spare_ext optional
+};
+
+/* 6.6.2.3.3 Figure 23 */
+type record IuUP_PDU14_NACK {
+	IuUP_ErrorCause	err_cause,
+	BIT2		spare,
+	octetstring	spare_ext optional
+};
+
+type union IuUP_PDU14_Union {
+	IuUP_PDU14_ProcSending	proc_sending,
+	IuUP_PDU14_ACK		ack,
+	IuUP_PDU14_NACK		nack
+};
+
+type union IuUP_PDU14_ProcSendingUnion {
+	IuUP_PDU14_ProcSending_INIT		init,
+	IuUP_PDU14_ProcSending_RATE_CTRL	rate_ctrl,
+	IuUP_PDU14_ProcSending_RATE_CTRL	rate_ctrl_ack,
+	IuUP_PDU14_ProcSending_TIME_ALIGNMENT	time_alignment,
+	IuUP_PDU14_ProcSending_ERROR_EVENT	error_event
+};
+
+/* 6.6.2.3.4.1 Initialisation */
+type record IuUP_PDU14_ProcSending_INIT {
+	BIT3		spare,
+	boolean		ti,
+	uint3_t		subflows_per_rfci,
+	boolean		chain_ind,
+
+	/* FIXME: Further decode */
+	octetstring	payload
+};
+type record IuUP_InitRfci {
+	boolean		lri,
+	boolean		li,
+	IuUP_RFCI	rfci,
+	RecOfU8		len8 optional,
+	RecOfU16	len16 optional
+} with { variant (len8)		"PRESENCE(li=false)";
+	 variant (len16)	"PRESENCE(li=true)"
+};
+type record of uint8_t RecOfU8;
+type record of uint16_t RecOfU16;
+
+/* 6.6.2.3.4.2.1 Rate Control procedure */
+type record IuUP_PDU14_ProcSending_RATE_CTRL {
+	BIT2		spare,
+	uint6_t		nr_of_rfci_ind,
+	bitstring	rfci_ind
+} with { variant (nr_of_rfci_ind) "LENGTHTO(rfci_ind)"
+	 variant (nr_of_rfci_ind) "UNIT(bits)"
+};
+
+/* 6.6.2.3.4.3 Time Alignment */
+type record IuUP_PDU14_ProcSending_TIME_ALIGNMENT {
+	uint8_t		time_alignment,
+	octetstring	spare optional
+};
+
+/* 6.6.2.3.4.4 Error Event */
+type record IuUP_PDU14_ProcSending_ERROR_EVENT {
+	IuUP_ErrorDistance	distance,
+	IuUP_ErrorCause		cause
+};
+
+
+type union IuUP_PDU {
+	IuUP_PDU_Type_0		type_0,
+	IuUP_PDU_Type_1		type_1,
+	IuUP_PDU_Type_14	type_14
+} with { variant "TAG(	type_0,		pdu_type = 0;
+			type_1,		pdu_type = 1;
+			type_14,	pdu_type = 14;)" };
+
+/* hand-written C++ functions */
+external function f_enc_IuUP_PDU(in IuUP_PDU msg) return octetstring;
+external function f_IuUP_compute_crc_header(in octetstring inp) return uint6_t;
+external function f_IuUP_compute_crc_payload(in octetstring inp) return uint10_t;
+
+/* auto-generated */
+external function dec_IuUP_PDU(in octetstring stream) return IuUP_PDU
+	with { extension "prototype(convert) decode(RAW)" };
+
+template IuUP_PDU ts_IuUP_INIT_ACK(uint2_t frame_nr, uint4_t version) := {
+	type_14 := {
+		pdu_type := 14,
+		ack_nack := IuUP_ACKNACK_ACK,
+		frame_nr := frame_nr,
+		iuup_version := version,
+		procedure_ind := IuUP_PRI_INITIALIZATION,
+		header_crc := 0,
+		payload_crc := 0,
+		u := {
+			ack := {
+				spare_ext := omit
+			}
+		}
+	}
+};
+
+template IuUP_PDU tr_IuUP_INIT_ACK(template uint2_t frame_nr := ?, template uint4_t version := ?) := {
+	type_14 := {
+		pdu_type := 14,
+		ack_nack := IuUP_ACKNACK_ACK,
+		frame_nr := frame_nr,
+		iuup_version := version,
+		procedure_ind := IuUP_PRI_INITIALIZATION,
+		header_crc := ?,
+		payload_crc := ?,
+		u := {
+			ack := {
+				spare_ext := omit
+			}
+		}
+	}
+};
+
+template IuUP_PDU ts_IuUP_INIT(octetstring payload, uint2_t frame_nr := 0, uint4_t version := 0) := {
+	type_14 := {
+		pdu_type := 14,
+		ack_nack := IuUP_ACKNACK_CTRL,
+		frame_nr := frame_nr,
+		iuup_version := version,
+		procedure_ind := IuUP_PRI_INITIALIZATION,
+		header_crc := 0,
+		payload_crc := 0,
+		u := {
+			proc_sending := {
+				payload := payload
+			}
+		}
+	}
+};
+
+template IuUP_PDU tr_IuUP_INIT(template octetstring payload := ?, template uint2_t frame_nr := ?,
+				template uint4_t version := ?) := {
+	type_14 := {
+		pdu_type := 14,
+		ack_nack := IuUP_ACKNACK_CTRL,
+		frame_nr := frame_nr,
+		iuup_version := version,
+		procedure_ind := IuUP_PRI_INITIALIZATION,
+		header_crc := ?,
+		payload_crc := ?,
+		u := {
+			proc_sending := {
+				payload := payload
+			}
+		}
+	}
+};
+
+
+template IuUP_PDU ts_IuUP_Type0(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload,
+				IuUP_FQC fqc := IuUP_FQC_GOOD) := {
+	type_0 := {
+		pdu_type := 0,
+		frame_nr := frame_nr,
+		fqc := fqc,
+		rfci := rfci,
+		header_crc := 0,
+		payload_crc := 0,
+		payload := payload
+	}
+};
+
+template IuUP_PDU tr_IuUP_Type0(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?,
+				template IuUP_FQC fqc := ?) := {
+	type_0 := {
+		pdu_type := 0,
+		frame_nr := frame_nr,
+		fqc := fqc,
+		rfci := rfci,
+		header_crc := ?,
+		payload_crc := ?,
+		payload := ?
+	}
+};
+
+template IuUP_PDU ts_IuUP_Type1(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload,
+				IuUP_FQC fqc := IuUP_FQC_GOOD) := {
+	type_1 := {
+		pdu_type := 1,
+		frame_nr := frame_nr,
+		fqc := fqc,
+		rfci := rfci,
+		header_crc := 0,
+		spare := '00'B,
+		payload := payload
+	}
+};
+
+
+template IuUP_PDU tr_IuUP_Type1(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?,
+				template IuUP_FQC fqc := ?) := {
+	type_1 := {
+		pdu_type := 1,
+		frame_nr := frame_nr,
+		fqc := fqc,
+		rfci := rfci,
+		header_crc := ?,
+		spare := ?,
+		payload := ?
+	}
+};
+
+
+
+} with { encode "RAW" ; variant "FIELDORDER(msb)" }

-- 
To view, visit https://gerrit.osmocom.org/5562
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie04438d8ec2b796e9e56b1937fa024a5299457dd
Gerrit-PatchSet: 1
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list