Split templates in RLCMAC_{CSN1_}Types into their own _Templates file

RLCMAC blocks have a lot of fields and we will potentially require lots
of different templates, as well as functions to handle related structs.

Change-Id: I9c6597178168aa3848b21930f33be698dd2ce545
diff --git a/library/RLCMAC_CSN1_Templates.ttcn b/library/RLCMAC_CSN1_Templates.ttcn
new file mode 100644
index 0000000..07f70b4
--- /dev/null
+++ b/library/RLCMAC_CSN1_Templates.ttcn
@@ -0,0 +1,163 @@
+/* GPRS RLC/MAC Control Messages as per 3GPP TS 44.060 manually transcribed from the CSN.1 syntax, as no CSN.1
+ * tool for Eclipse TITAN could be found.  Implements only the minimum necessary messages for Osmocom teseting
+ * purposes. */
+
+/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
+ * contributions by sysmocom - s.f.m.c. GmbH
+ * 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
+ */
+
+module RLCMAC_CSN1_Templates {
+	import from General_Types all;
+	import from Osmocom_Types all;
+	import from GSM_Types all;
+	import from MobileL3_GMM_SM_Types all;
+	import from RLCMAC_CSN1_Types all;
+
+	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_CTRL_ACK(GprsTlli tlli,
+						CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
+		msg_type := PACKET_CONTROL_ACK,
+		u := {
+			ctrl_ack := {
+				tlli := tlli,
+				ctrl_ack := ack
+			}
+		}
+	}
+
+	const ILevel iNone := {
+		presence := '0'B,
+		i_level := omit
+	}
+	const ChannelQualityReport c_ChQualRep_default := {
+		c_value := 0,
+		rxqual := 0,
+		sign_var := 0,
+		i_levels := { iNone, iNone, iNone, iNone, iNone, iNone, iNone, iNone }
+	}
+	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_DL_ACK(uint5_t dl_tfi,
+								    AckNackDescription andesc,
+					ChannelQualityReport qual_rep := c_ChQualRep_default) := {
+		msg_type := PACKET_DL_ACK_NACK,
+		u := {
+			dl_ack_nack := {
+				dl_tfi := dl_tfi,
+				ack_nack_desc := andesc,
+				chreq_desc_presence := '0'B,
+				chreq_desc := omit,
+				ch_qual_rep := qual_rep
+			}
+		}
+	}
+
+	private function f_presence_bit_MultislotCap_GPRS(template (omit) MultislotCap_GPRS mscap_gprs) return BIT1 {
+		if (istemplatekind(mscap_gprs, "omit")) {
+			return '0'B;
+		}
+		return '1'B;
+	}
+	private function f_presence_bit_MultislotCap_EGPRS(template (omit) MultislotCap_EGPRS mscap_egprs) return BIT1 {
+		if (istemplatekind(mscap_egprs, "omit")) {
+			return '0'B;
+		}
+		return '1'B;
+	}
+	template (value) MSRACapabilityValuesRecord ts_RaCapRec(BIT4 att := '0001'B /* E-GSM */, template (omit) MultislotCap_GPRS mscap_gprs := omit, template (omit) MultislotCap_EGPRS mscap_egprs := omit) := {
+		mSRACapabilityValues := {
+			mSRACapabilityValuesExclude1111 := {
+				accessTechnType := att, /* E-GSM */
+				accessCapabilities := {
+					lengthIndicator := 0, /* overwritten */
+					accessCapabilities := {
+						rfPowerCapability := '001'B, /* FIXME */
+						presenceBitA5 := '0'B,
+						a5bits := omit,
+						esind := '1'B,
+						psbit := '0'B,
+						vgcs := '0'B,
+						vbs := '0'B,
+						presenceBitMultislot := '1'B,
+						multislotcap := {
+							presenceBitHscsd := '0'B,
+							hscsdmultislotclass := omit,
+							presenceBitGprs := f_presence_bit_MultislotCap_GPRS(mscap_gprs),
+							gprsmultislot := mscap_gprs,
+							presenceBitSms := '0'B,
+							multislotCap_SMS := omit,
+							multislotCapAdditionsAfterRel97 := {
+									presenceBitEcsdmulti := '0'B,
+									ecsdmultislotclass := omit,
+									presenceBitEgprsmulti := f_presence_bit_MultislotCap_EGPRS(mscap_egprs),
+									multislotCap_EGPRS := mscap_egprs,
+									presenceBitDtmGprsmulti := '0'B,
+									multislotCapdtmgprsmultislotsubclass := omit
+							}
+						},
+						accessCapAdditionsAfterRel97 := omit
+					},
+					spare_bits := omit
+				}
+			}
+		},
+		presenceBitMSRACap := '0'B
+	};
+
+	private function f_presence_bit_MSRadioAccessCapabilityV(template (omit) MSRadioAccessCapabilityV ms_rac) return BIT1 {
+		if (istemplatekind(ms_rac, "omit")) {
+			return '0'B;
+		}
+		return '1'B;
+	}
+
+	private function f_template_MSRadioAccessCapabilityV_to_MSRadioAccCap2(template (omit) MSRadioAccessCapabilityV ms_rac) return template (omit) MSRadioAccCap2 {
+		var template (omit) MSRadioAccCap2 ms_rac2 := omit;
+		if (istemplatekind(ms_rac, "omit")) {
+			return ms_rac2;
+		}
+		ms_rac2 := { msRadioAccessCapabilityV := ms_rac };
+		return ms_rac2;
+	}
+
+	private const ChannelReqDescription c_ChReqDesc_default := {
+		peak_tput_class := 0,
+		priority := 0,
+		rlc_mode := RLC_MODE_UNACKNOWLEDGED,
+		llc_pdu_type := LLC_PDU_IS_NOT_SACK_OR_ACK,
+		RlcOctetCount := 0
+	}
+
+	/* TS 44.060 sec 11.2.16 */
+	template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_RES_REQ(GprsTlli tlli,
+						     template (omit) MSRadioAccessCapabilityV ms_rac,
+						     ChannelReqDescription ch_req_desc := c_ChReqDesc_default,
+						     RlcAccessType acc_type := RLC_ACC_TYPE_TWO_PHASE)
+	:= {
+		msg_type := PACKET_RESOURCE_REQUEST,
+		u := {
+			resource_req := {
+				acc_type_presence := '1'B,
+				acc_type := acc_type,
+				id_type := '1'B,
+				id := { tlli := tlli },
+				ms_rac2_presence := f_presence_bit_MSRadioAccessCapabilityV(ms_rac),
+				ms_rac2 := f_template_MSRadioAccessCapabilityV_to_MSRadioAccCap2(ms_rac),
+				ch_req_desc := ch_req_desc,
+				change_mark_presence := '0'B,
+				change_mark := omit,
+				C_val := '000000'B,
+				sign_var_presence := '0'B,
+				sign_var := omit,
+				I_levels := {
+					iNone, iNone, iNone, iNone,
+					iNone, iNone, iNone, iNone
+				}
+			}
+		}
+	}
+
+} with { encode "RAW"; variant "FIELDORDER(msb)" variant "BYTEORDER(last)" };