/* 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 := '00'B, p_f := f, u := '011'B }
	};

	external function dec_LapdmAddressField(in octetstring stream) return LapdmAddressField
		with { extension "prototype(convert) decode(RAW)" };

	external function dec_LapdmCtrl(in octetstring stream) return LapdmCtrl
		with { extension "prototype(convert) decode(RAW)" };

	external function dec_LapdmCtrlU(in octetstring stream) return LapdmCtrlU
		with { extension "prototype(convert) decode(RAW)" };

	external function dec_LapdmLengthIndicator(in octetstring stream) return LapdmLengthIndicator
		with { extension "prototype(convert) decode(RAW)" };

	/* 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,
		uint6_t			len,
		boolean			m,
		uint1_t			el (1),
		octetstring		payload
	} with { variant (len) "LENGTHTO(payload)"
		 variant "FIELDORDER(msb)" };

	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)" */}
