first steps towards a L1CTL / LAPD test

The idea here is to implement the L1CTL protocol in TTCN-3 so we can
speak it over a unix domain socket (test port) for simple tasks such as
activating dedicated mode.

This can then subsequently be used for LAPDm testing
diff --git a/lapd/LAPDm_Types.ttcn b/lapd/LAPDm_Types.ttcn
new file mode 100644
index 0000000..c52b96c
--- /dev/null
+++ b/lapd/LAPDm_Types.ttcn
@@ -0,0 +1,156 @@
+/* LAPDm definitiona according to 3GPP TS 44.006 */
+/* (C) 2017 bh Harald Welte <laforge@gnumonks.org> */
+module LAPDm_Types {
+
+	import from General_Types all;
+	import from Osmocom_Types all;
+
+	type uint3_t LapdmSapi;
+	type BIT2 LapdmSBits;
+	type BIT3 LapdmUBits;
+	type BIT2 LapdmU2Bits;
+
+	type record LapdmLengthIndicator {
+		uint6_t len,
+		boolean m,
+		uint1_t el
+	} with { variant "" };
+
+	/* TS 44.006 Figure 4 */
+	type record LapdmAddressField {
+		BIT1		spare,
+		uint2_t		lpd (0),
+		LapdmSapi	sapi,
+		boolean		c_r,
+		boolean		ea
+	} with { variant "" };
+
+	template LapdmAddressField tr_LapdmAddr(LapdmSapi sapi, boolean c_r) := {
+		spare := '0'B,
+		lpd := 0,
+		sapi := sapi,
+		c_r := c_r,
+		ea := true
+	};
+
+	type record LapdmCtrlI {
+		uint3_t n_r,
+		boolean	p,
+		uint3_t	n_s,
+		BIT1	spare ('0'B)
+	} with { variant "" };
+
+	type record LapdmCtrlS {
+		uint3_t		n_r,
+		boolean		p_f,
+		LapdmSBits	s,
+		BIT2	spare ('01'B)
+	} with { variant "" };
+
+	type record LapdmCtrlU {
+		LapdmUBits	u,
+		boolean		p_f,
+		LapdmU2Bits	u2,
+		BIT2	spare ('11'B)
+	} with { variant "" };
+
+	/* TS 44.006 Table 3 */
+	type union LapdmCtrl {
+		LapdmCtrlI	i,
+		LapdmCtrlS	s,
+		LapdmCtrlU	u
+	} with { variant "TAG(i, spare = '0'B;
+			      s, spare = '01'B;
+			      u, spare = '11'B)" };
+
+	template LapdmCtrl t_LapdmCtrlS := {
+		s := { n_r := ?, p_f := ?, s:= ?, spare := '01'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlU := {
+		u := { u := ?, p_f := ?, u2 := ?, spare := '11'B }
+	};
+
+	/* TS 44.006 Table 4 */
+	template LapdmCtrl t_LapdmCtrlI(template uint3_t nr, template uint3_t ns, template boolean p) := {
+		i := { n_r := nr, p := p, n_s := ns, spare := '0'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlRR(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := {
+		s := { n_r := nr, p_f := pf, s := '00'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlRNR(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := {
+		s := { n_r := nr, p_f := pf, s := '01'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlREJ(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := {
+		s := { n_r := nr, p_f := pf, s := '10'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlSABM(template boolean p) modifies t_LapdmCtrlU := {
+		u := { u := '001'B, p_f := p, u2 := '11'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlDM(template boolean f) modifies t_LapdmCtrlU := {
+		u := { u := '000'B, p_f := f, u2 := '11'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlUI(template boolean p) modifies t_LapdmCtrlU := {
+		u := { u := '000'B, p_f := p, u2 := '00'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlDISC(template boolean p) modifies t_LapdmCtrlU := {
+		u := { u := '010'B, p_f := p, u2 := '00'B }
+	};
+
+	template LapdmCtrl t_LapdmCtrlUA(template boolean f) modifies t_LapdmCtrlU := {
+		u := { u := '011'B, p_f := f, u2 := '00'B }
+	};
+
+	/* Format A is used on DCCHs for frames where there is no information field */
+	type record LapdmFrameA {
+		LapdmAddressField	addr,
+		LapdmCtrl		ctrl,
+		LapdmLengthIndicator	len
+	} with { variant "" };
+
+	external function enc_LapdmFrameA(in LapdmFrameA si) return octetstring
+		with { extension "prototype(convert) encode(RAW)" };
+	external function dec_LapdmFrameA(in octetstring stream) return LapdmFrameA
+		with { extension "prototype(convert) decode(RAW)" };
+
+	/* Formats B, Bter and B4 are used on DCCHs for frames containing an information field: 
+	/* - format Bter is used on request of higher layers if and only if short L2 header type 1 is
+	 *   supported and a UI command is to be transmitted on SAPI 0 */
+	/* - format B4 is used for UI frames transmitted by the network on SACCH; */
+	/* - format B is applied in all other cases. */
+	/* Format Bbis is used only on BCCH, PCH, NCH, and AGCH.
+
+	/* Format B */
+	type record LapdmFrameB {
+		LapdmAddressField	addr,
+		LapdmCtrl		ctrl,
+		LapdmLengthIndicator	len,
+		octetstring		payload
+	} with { variant "" };
+
+	external function enc_LapdmFrameB(in LapdmFrameB si) return octetstring
+		with { extension "prototype(convert) encode(RAW)" };
+	external function dec_LapdmFrameB(in octetstring stream) return LapdmFrameB
+		with { extension "prototype(convert) decode(RAW)" };
+
+
+	/* Format B4 */
+	type record LapdmFrameB4 {
+		LapdmAddressField	addr,
+		LapdmCtrl		ctrl,
+		octetstring		payload
+	} with { variant "" };
+
+	external function enc_LapdmFrameB4(in LapdmFrameB4 si) return octetstring
+		with { extension "prototype(convert) encode(RAW)" };
+	external function dec_LapdmFrameB4(in octetstring stream) return LapdmFrameB4
+		with { extension "prototype(convert) decode(RAW)" };
+
+} with { encode "RAW" };