bts: Add RLL tests

This adds a series of test cases to BTS_Tests.ttcn implementing testing
of the RLL sub-layr of RSL, i.e. the translation between LAPDm frames
on the Um interface and the RLL frames on the Abis side (and vice vrsa).

Related: OS#3174
Change-Id: I336378de6106e5369600cbb49e0c47cc59864630
diff --git a/library/L1CTL_PortType.ttcn b/library/L1CTL_PortType.ttcn
index 77b2494..f8bc670 100644
--- a/library/L1CTL_PortType.ttcn
+++ b/library/L1CTL_PortType.ttcn
@@ -97,7 +97,7 @@
 		alt {
 			[] pt.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
 				rr := dec_GsmRrMessage(dl.payload.data_ind.payload);
-				log("PCH/AGCN DL RR: ", rr);
+				log("PCH/AGCH DL RR: ", rr);
 				if (match(rr, t_RR_IMM_ASS(ra, rach_fn))) {
 					log("Received IMM.ASS for our RACH!");
 				} else {
diff --git a/library/LAPDm_Types.ttcn b/library/LAPDm_Types.ttcn
index 91f55fa..487748d 100644
--- a/library/LAPDm_Types.ttcn
+++ b/library/LAPDm_Types.ttcn
@@ -10,6 +10,12 @@
 	type BIT3 LapdmUBits;
 	type BIT2 LapdmU2Bits;
 
+	/* 44.006 6.3.2 */
+	const boolean cr_MO_CMD := false;
+	const boolean cr_MO_RSP := true;
+	const boolean cr_MT_CMD := true;
+	const boolean cr_MT_RSP := false;
+
 	/* TS 44.006 Figure 4 */
 	type record LapdmAddressField {
 		BIT1		spare,
@@ -193,4 +199,113 @@
 	/* automatic decoding to the generic LapdmFrame will not work, you have to call one of the
 	 * type-specific decoder routines above */
 
+	/* SABM frame with L3 payload */
+	template (value) LapdmFrame ts_LAPDm_SABM(LapdmSapi sapi, boolean c_r, boolean p,
+						  octetstring l3) := {
+		ab := {
+			addr := ts_LapdmAddr(sapi, c_r),
+			ctrl := ts_LapdmCtrlSABM(p),
+			len := 0, /* overwritten in encoder */
+			m := false,
+			el := 1,
+			payload := l3
+		}
+	}
+	template LapdmFrame tr_LAPDm_SABM(template LapdmSapi sapi, template boolean c_r,
+					  template boolean p, template octetstring l3) := {
+		ab := {
+			addr := tr_LapdmAddr(sapi, c_r),
+			ctrl := tr_LapdmCtrlSABM(p),
+			len := ?,
+			m := false,
+			el := 1,
+			payload := l3
+		}
+	}
+
+	template (value) LapdmFrame ts_LAPDm_UA(LapdmSapi sapi, boolean c_r, boolean f,
+						octetstring l3) := {
+		ab := {
+			addr := ts_LapdmAddr(sapi, c_r),
+			ctrl := ts_LapdmCtrlUA(f),
+			len := 0, /* overwritten in encoder */
+			m := false,
+			el := 1,
+			payload := l3
+		}
+	}
+	template LapdmFrame tr_LAPDm_UA(template LapdmSapi sapi, template boolean c_r,
+					template boolean f, template octetstring l3) := {
+		ab := {
+			addr := tr_LapdmAddr(sapi, c_r),
+			ctrl := tr_LapdmCtrlUA(f),
+			len := ?,
+			m := false,
+			el := 1,
+			payload := l3
+		}
+	}
+
+	template LapdmFrame ts_LAPDm_DISC(LapdmSapi sapi, boolean c_r, boolean p) := {
+		ab := {
+			addr := ts_LapdmAddr(sapi, c_r),
+			ctrl := ts_LapdmCtrlDISC(p),
+			len := 0,
+			m := false,
+			el := 1,
+			payload := ''O
+		}
+	}
+	template LapdmFrame tr_LAPDm_DISC(template LapdmSapi sapi, template boolean c_r,
+					  template boolean p) := {
+		ab := {
+			addr := tr_LapdmAddr(sapi, c_r),
+			ctrl := tr_LapdmCtrlDISC(p),
+			len := ?,
+			m := false,
+			el := 1,
+			payload := ''O
+		}
+	}
+
+	template LapdmFrame ts_LAPDm_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := {
+		ab := {
+			addr := ts_LapdmAddr(sapi, c_r),
+			ctrl := ts_LapdmCtrlUI(p),
+			len := 0,
+			m := false,
+			el := 1,
+			payload := l3
+		}
+	}
+	template LapdmFrame tr_LAPDm_UI(template LapdmSapi sapi, template boolean c_r,
+					  template boolean p, template octetstring l3) := {
+		ab := {
+			addr := tr_LapdmAddr(sapi, c_r),
+			ctrl := tr_LapdmCtrlUI(p),
+			len := ?,
+			m := false,
+			el := 1,
+			payload := l3
+		}
+	}
+
+	template LapdmFrame ts_LAPDm_B4_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := {
+		b4 := {
+			addr := ts_LapdmAddr(sapi, c_r),
+			ctrl := ts_LapdmCtrlUI(p),
+			payload := l3
+		}
+	}
+	template LapdmFrame tr_LAPDm_B4_UI(template LapdmSapi sapi, template boolean c_r,
+					  template boolean p, template octetstring l3) := {
+		b4 := {
+			addr := tr_LapdmAddr(sapi, c_r),
+			ctrl := tr_LapdmCtrlUI(p),
+			payload := l3
+		}
+	}
+
+
+
 } with { encode "RAW"; /*variant "FIELDORDER(msb)" */}
diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn
index 246ea3f..2d9c92e 100644
--- a/library/RSL_Types.ttcn
+++ b/library/RSL_Types.ttcn
@@ -625,13 +625,19 @@
 		RSL_IPA_Codec		codec
 	}
 
+	/* 9.3.20 */
+	type enumerated RSL_IE_ReleaseMode {
+		RSL_REL_MODE_NORMAL	('00'B),
+		REL_REL_MODE_LOCAL	('01'B)
+	}
+
 	/* union of all IE bodies */
 	type union RSL_IE_Body {
 		RslChannelNr		chan_nr,
 		RslLinkId		link_id,
 		RSL_L16V		l3_info,
 		RSL_LV			rlm_cause,
-		uint8_t			release_mode,
+		RSL_IE_ReleaseMode	release_mode,
 		RSL_IE_ActivationType	act_type,
 		RSL_IE_ChannelMode	chan_mode,
 		uint8_t			handover_ref,
@@ -926,25 +932,38 @@
 			tr_RSL_IE(RSL_IE_Body:{l3_info := tr_RSL_L16V(l3_info)})
 		}
 	}
+	template RSL_Message tr_RSL_EST_IND_NOL3(template RslChannelNr chan_nr, template RslLinkId link_id) :=
+{
+		msg_disc := tr_RSL_MsgDisc(RSL_MDISC_RLL, false),
+		msg_type := RSL_MT_EST_IND,
+		ies := {
+			tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}),
+			tr_RSL_IE(RSL_IE_Body:{link_id := link_id})
+		}
+	}
+
 
 	/* 8.3.7 BSC -> BTS */
 	template (value) RSL_Message ts_RSL_REL_REQ(template (value) RslChannelNr chan_nr,
-						    template (value) RslLinkId link_id) := {
+						    template (value) RslLinkId link_id,
+						    template (value) RSL_IE_ReleaseMode rel_mode := RSL_REL_MODE_NORMAL) := {
 		msg_disc := ts_RSL_MsgDisc(RSL_MDISC_RLL, false),
 		msg_type := RSL_MT_REL_REQ,
 		ies :={
 			t_RSL_IE(RSL_IE_CHAN_NR, RSL_IE_Body:{chan_nr := chan_nr}),
-			t_RSL_IE(RSL_IE_LINK_IDENT, RSL_IE_Body:{link_id := link_id})
+			t_RSL_IE(RSL_IE_LINK_IDENT, RSL_IE_Body:{link_id := link_id}),
+			t_RSL_IE(RSL_IE_RELEASE_MODE, RSL_IE_Body:{release_mode := rel_mode})
 		}
 	}
 	template RSL_Message tr_RSL_REL_REQ(template RslChannelNr chan_nr,
-					    template RslLinkId link_id) := {
+					    template RslLinkId link_id,
+					    template RSL_IE_ReleaseMode rel_mode := ?) := {
 		msg_disc := tr_RSL_MsgDisc(RSL_MDISC_RLL, false),
 		msg_type := RSL_MT_REL_REQ,
 		ies :={
 			tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}),
 			tr_RSL_IE(RSL_IE_Body:{link_id := link_id}),
-			*
+			tr_RSL_IE(RSL_IE_Body:{release_mode := rel_mode})
 		}
 	}
 
@@ -993,6 +1012,13 @@
 	modifies ts_RSL_DATA_REQ := {
 		msg_type := RSL_MT_UNIT_DATA_REQ
 	}
+	template RSL_Message tr_RSL_UNITDATA_REQ(template RslChannelNr chan_nr,
+						 template RslLinkId link_id,
+						 template octetstring l3_info)
+	modifies tr_RSL_DATA_REQ := {
+		msg_type := RSL_MT_UNIT_DATA_REQ
+	}
+
 
 	/* 8.3.11 BTS -> BSC */
 	template (value) RSL_Message ts_RSL_UNITDATA_IND(template (value) RslChannelNr chan_nr,
@@ -1001,6 +1027,14 @@
 	modifies ts_RSL_DATA_IND := {
 		msg_type := RSL_MT_UNIT_DATA_IND
 	}
+	template RSL_Message tr_RSL_UNITDATA_IND(template RslChannelNr chan_nr,
+						 template (value) RslLinkId link_id,
+						 template octetstring l3_info)
+	modifies tr_RSL_DATA_IND := {
+		msg_type := RSL_MT_UNIT_DATA_IND
+	}
+
+
 
 
 	/* DEDICATED CANNEL MANAGEMENT MESSAGES */