/* 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 ('0'B),
		uint3_t	n_s,
		boolean	p,
		uint3_t n_r
	} with { variant "FIELDORDER(lsb)" };

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

	type record LapdmCtrlU {
		BIT2		spare ('11'B),
		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)" */}
