/* 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 "FIELDORDER(msb)" };

	template LapdmLengthIndicator t_LapdmLengthIndicator(template uint6_t len, boolean m := false) := {
		len := len,
		m := m,
		el := 1
	};

	/* TS 44.006 Figure 4 */
	type record LapdmAddressField {
		BIT1		spare,
		uint2_t		lpd,
		LapdmSapi	sapi,
		boolean		c_r,
		boolean		ea
	} with { variant "FIELDORDER(msb)" };

	template LapdmAddressField tr_LapdmAddr(template LapdmSapi sapi, template boolean c_r) := {
		spare := '0'B,
		lpd := 0,
		sapi := sapi,
		c_r := c_r,
		ea := true
	};

	type record LapdmCtrlI {
		BIT1	spare,
		uint3_t	n_s,
		boolean	p,
		uint3_t n_r
	} with { variant "FIELDORDER(lsb)" };

	type record LapdmCtrlS {
		BIT2		spare,
		LapdmSBits	s,
		boolean		p_f,
		uint3_t		n_r
	} with { variant "FIELDORDER(lsb)" };

	type record LapdmCtrlU {
		BIT2		spare,
		LapdmU2Bits	u2,
		boolean		p_f,
		LapdmUBits	u
	} with { variant "FIELDORDER(lsb)" };

	/* TS 44.006 Table 3 */
	type union LapdmCtrl {
		LapdmCtrlS	s,
		LapdmCtrlU	u,
		LapdmCtrlI	i,
		uint8_t		other
	} with { variant "TAG(u, spare = '11'B;
			      s, spare = '01'B;
			      i, spare = '0'B;
			      other, OTHERWISE)" };
			/*      )" }; */

	/* TS 44.006 Table 4 */

	template LapdmCtrl t_LapdmCtrlS := {
		s := { spare := '01'B, s := ?, p_f := ?, n_r := ? }
	};

	template LapdmCtrl t_LapdmCtrlU := {
		u := { spare := '11'B, u2 := ?, p_f := ?, u := ? }
	};

	/* TS 44.006 Table 4 */
	template LapdmCtrl t_LapdmCtrlI(template uint3_t nr, template uint3_t ns, template boolean p) := {
		i := { spare := '0'B, n_s := ns, p := p, n_r := nr }
	};

	template LapdmCtrl t_LapdmCtrlRR(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := {
		s := { s:= '00'B, p_f := pf, n_r := nr }
	};

	template LapdmCtrl t_LapdmCtrlRNR(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := {
		s := { s:= '01'B, p_f := pf, n_r := nr }
	};

	template LapdmCtrl t_LapdmCtrlREJ(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := {
		s := { s:= '10'B, p_f := pf, n_r := nr }
	};

	template LapdmCtrl t_LapdmCtrlSABM(template boolean p) modifies t_LapdmCtrlU := {
		u := { u2 := '11'B, p_f := p, u := '001'B }
	};

	template LapdmCtrl t_LapdmCtrlDM(template boolean f) modifies t_LapdmCtrlU := {
		u := { u2 := '11'B, p_f := f, u := '000'B }
	};

	template LapdmCtrl t_LapdmCtrlUI(template boolean p) modifies t_LapdmCtrlU := {
		u := { u2 := '00'B, p_f := p, u := '000'B }
	};

	template LapdmCtrl t_LapdmCtrlDISC(template boolean p) modifies t_LapdmCtrlU := {
		u := { u2 := '00'B, p_f := p, u := '010'B }
	};

	template LapdmCtrl t_LapdmCtrlUA(template boolean f) modifies t_LapdmCtrlU := {
		u := { u2 := '01'B, p_f := f, u := '011'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)" };

	type record LapdmFrameBbis {
		octetstring		payload
	} with { variant "" };

	external function enc_LapdmFrameBbis(in LapdmFrameBbis si) return octetstring
		with { extension "prototype(convert) encode(RAW)" };
	external function dec_LapdmFrameBbis(in octetstring stream) return LapdmFrameBbis
		with { extension "prototype(convert) decode(RAW)" };

	type union LapdmFrame {
		LapdmFrameA	a,
		LapdmFrameB	b,
		LapdmFrameBbis	bbis,
		LapdmFrameB4	b4
	} with { variant "" };

	external function enc_LapdmFrame(in LapdmFrame si) return octetstring
		with { extension "prototype(convert) encode(RAW)" };
	/* automatic decoding to the generic LapdmFrame will not work, you have to call one of the
	 * type-specific decoder routines above */

} with { encode "RAW"; /*variant "FIELDORDER(msb)" */}
