IuUP: Improve enc/dec of PDU Type 14

Related: SYS#5969
Change-Id: I33e8a82e654b5afef8bc468cf6b1fff8fa9637ce
diff --git a/library/IuUP_Types.ttcn b/library/IuUP_Types.ttcn
index b822ddf..e99dfef 100644
--- a/library/IuUP_Types.ttcn
+++ b/library/IuUP_Types.ttcn
@@ -91,6 +91,8 @@
 /* See TS 25.415 6.6.3.18 */
 type uint8_t IuUP_TimeAlignment;
 
+/* See TS 25.415 6.6.3.24 */
+type uint4_t IuUP_IPTI;
 
 /* See TS 25.415 6.6.2.1 */
 type record IuUP_PDU_Type_0 {
@@ -119,45 +121,57 @@
 	IuUP_PDU_Type	pdu_type,
 	IuUP_AckNack	ack_nack,
 	uint2_t		frame_nr,
+	IuUP_PDU14_Union u
+} with { variant (u) "CROSSTAG(proc,	ack_nack=IuUP_ACKNACK_CTRL;
+			       ack,	ack_nack=IuUP_ACKNACK_ACK;
+			       nack,	ack_nack=IuUP_ACKNACK_NACK)"
+};
+
+type record IuUP_PDU_Type_14_Common_Hdr {
 	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)"
+	uint10_t	payload_crc
+};
+
+type union IuUP_PDU14_Union {
+	IuUP_PDU14_ProcSending	proc,
+	IuUP_PDU14_ACK		ack,
+	IuUP_PDU14_NACK		nack
 };
 
 /* 6.6.2.3.1 Figure 21 */
 type record IuUP_PDU14_ProcSending {
-	octetstring	payload
+	IuUP_PDU_Type_14_Common_Hdr hdr,
+	IuUP_PDU14_ProcSendingUnion u
+} with {
+	variant (u) "CROSSTAG(init,      hdr.procedure_ind=IuUP_PRI_INITIALIZATION;
+			      rate_ctrl, hdr.procedure_ind=IuUP_PRI_RATE_CONTROL;
+			      time_alignment, hdr.procedure_ind=IuUP_PRI_TIME_ALIGNMENT;
+			      error_event, hdr.procedure_ind=IuUP_PRI_ERROR_EVENT;
+			      other,     OTHERWISE)"
 };
 
 /* 6.6.2.3.2 Figure 22 */
 type record IuUP_PDU14_ACK {
+	IuUP_PDU_Type_14_Common_Hdr hdr,
 	octetstring	spare_ext optional
 };
 
 /* 6.6.2.3.3 Figure 23 */
 type record IuUP_PDU14_NACK {
+	IuUP_PDU_Type_14_Common_Hdr hdr,
 	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
+	IuUP_PDU14_ProcSending_ERROR_EVENT	error_event,
+	octetstring 				other
 };
 
 /* 6.6.2.3.4.1 Initialisation */
@@ -166,21 +180,35 @@
 	boolean		ti,
 	uint3_t		subflows_per_rfci,
 	boolean		chain_ind,
-
-	/* FIXME: Further decode */
-	octetstring	payload
+	IuUP_InitRfci	rfci,
+	IuUP_IPTI_List	IPTIs optional,
+	BIT16		versions_supported,
+	uint4_t		data_pdu_type,
+	BIT4		spare2
+} with {
+	variant (IPTIs) "PRESENCE(ti=true)"
+	variant (versions_supported) "BITORDER(lsb)"
+	variant (versions_supported) "BYTEORDER(last)"
 };
 type record IuUP_InitRfci {
 	boolean		lri,
 	boolean		li,
-	IuUP_RFCI	rfci,
+	IuUP_RFCI	rfci_id,
 	RecOfU8		len8 optional,
-	RecOfU16	len16 optional
-} with { variant (len8)		"PRESENCE(li=false)";
-	 variant (len16)	"PRESENCE(li=true)"
+	RecOfU16	len16 optional,
+	IuUP_InitRfci	rfci optional
+} with {
+	variant (len8)	"PRESENCE(li=false)";
+	variant (len16)	"PRESENCE(li=true)"
+	variant (rfci)	"PRESENCE(lri=false)"
 };
-type record of uint8_t RecOfU8;
-type record of uint16_t RecOfU16;
+type record of IuUP_IPTI IuUP_IPTI_List with {
+	variant "FIELDLENGTH(3)"
+	variant "PADDING(yes)"
+	};
+type record of uint8_t RecOfU8 with { variant "FIELDLENGTH(3)" };
+type record of uint16_t RecOfU16 with { variant "FIELDLENGTH(3)" };
+type record of IuUP_InitRfci IuUP_InitRfciList;
 
 /* 6.6.2.3.4.2.1 Rate Control procedure */
 type record IuUP_PDU14_ProcSending_RATE_CTRL {
@@ -226,12 +254,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 := {
+				hdr := {
+					iuup_version := version,
+					procedure_ind := IuUP_PRI_INITIALIZATION,
+					header_crc := 0,
+					payload_crc := 0
+				},
 				spare_ext := omit
 			}
 		}
@@ -243,48 +273,113 @@
 		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 := {
+				hdr := {
+					iuup_version := version,
+					procedure_ind := IuUP_PRI_INITIALIZATION,
+					header_crc := ?,
+					payload_crc := ?
+				},
 				spare_ext := omit
 			}
 		}
 	}
 };
 
-template IuUP_PDU ts_IuUP_INIT(octetstring payload, uint2_t frame_nr := 0, uint4_t version := 0) := {
+template (value) IuUP_InitRfci ts_IuUP_InitRfci(
+			template (value) boolean lri,
+			template (value) boolean li,
+			template (value) IuUP_RFCI rfci_id,
+			template (omit) RecOfU8 len8,
+			template (omit) RecOfU16 len16,
+			template (omit) IuUP_InitRfci rfci := omit) := {
+	lri := lri,
+	li := li,
+	rfci_id := rfci_id,
+	len8 := len8,
+	len16 := len16,
+	rfci := rfci
+}
+
+template (value) IuUP_PDU14_ProcSending_INIT ts_IuUP_PDU14_ProcSending_INIT(
+			template (value) boolean ti := true,
+			template (value) uint3_t subflows_per_rfci := 3,
+			template (value) boolean chain_ind := false,
+			template (value) IuUP_InitRfci rfci := ts_IuUP_InitRfci(false, false, 0, {81, 103, 60}, omit,
+									ts_IuUP_InitRfci(false, false, 1, {39, 0, 0}, omit,
+										ts_IuUP_InitRfci(true, false, 2, {0, 0, 0}, omit, omit))),
+			template (omit) IuUP_IPTI_List IPTIs := {1, 7, 1},
+			template (value) BIT16 versions_supported := '0000000000000001'B,
+			template (value) uint4_t data_pdu_type := 0) := {
+	spare := '000'B,
+	ti := ti,
+	subflows_per_rfci := subflows_per_rfci,
+	chain_ind := chain_ind,
+	rfci := rfci,
+	IPTIs := IPTIs,
+	versions_supported := versions_supported,
+	data_pdu_type := data_pdu_type,
+	spare2 := '0000'B
+}
+
+template (present) IuUP_PDU14_ProcSending_INIT tr_IuUP_PDU14_ProcSending_INIT(
+			template (present) boolean ti := ?,
+			template (present) uint3_t subflows_per_rfci := ?,
+			template (present) boolean chain_ind := ?,
+			template (present) IuUP_InitRfci rfci := ?,
+			template IuUP_IPTI_List IPTIs := *,
+			template (present) BIT16 versions_supported := ?,
+			template (present) uint4_t data_pdu_type := ?) := {
+	spare := '000'B,
+	ti := ti,
+	subflows_per_rfci := subflows_per_rfci,
+	chain_ind := chain_ind,
+	rfci := rfci,
+	IPTIs := IPTIs,
+	versions_supported := versions_supported,
+	data_pdu_type := data_pdu_type,
+	spare2 := '0000'B
+}
+
+template (value) IuUP_PDU ts_IuUP_INIT(template (value) IuUP_PDU14_ProcSending_INIT init, 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
+			proc := {
+				hdr := {
+					iuup_version := version,
+					procedure_ind := IuUP_PRI_INITIALIZATION,
+					header_crc := 0,
+					payload_crc := 0
+				},
+				u := {
+					init := init
+				}
 			}
 		}
 	}
 };
 
-template IuUP_PDU tr_IuUP_INIT(template octetstring payload := ?, template uint2_t frame_nr := ?,
+template IuUP_PDU tr_IuUP_INIT(template (present) IuUP_PDU14_ProcSending_INIT 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
+			proc := {
+				hdr := {
+					iuup_version := version,
+					procedure_ind := IuUP_PRI_INITIALIZATION,
+					header_crc := ?,
+					payload_crc := ?
+				},
+				u := {
+					init := init
+				}
 			}
 		}
 	}