/* Test Port that stacks on top of L1CTL test port and performs LAPDm encoding/decoding, so the user can send
 * and receive LAPDm frames in decoded TTCN-3 data types.  This is particularly useful for sending/receiving
 * all kinds of hand-crafted LAPDm frames for testing of the remote LAPDm layer */

/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module LAPDm_RAW_PT {
	import from GSM_Types all;
	import from GSM_RR_Types all;
	import from Osmocom_Types all;
	import from L1CTL_Types all;
	import from L1CTL_PortType all;
	import from LAPDm_Types all;
	import from RLCMAC_Types all;

	/* request to tune to a given ARFCN and start BCCH decoding */
	type record BCCH_tune_req {
		Arfcn arfcn,
		boolean combined_ccch
	}

	/* ask for a dedicated channel to be established */
	type record DCCH_establish_req {
		uint8_t ra
	}

	type record DCCH_establish_res {
		ChannelDescription chan_desc optional,
		charstring err optional
	}

	type record length(8) of uint8_t TfiList;
	type record TbfPars {
		GsmArfcn	arfcn optional,
		/* Temporary Flow Identifier for each TN */
		TfiList		tfi
	}
	type record length(8) of TbfPars TbfParsPerTs;

	template TbfPars t_TbfParsInit := {
		arfcn := omit,
		tfi := { 255, 255, 255, 255, 255, 255, 255, 255 }
	}

	type record TBF_UL_establish_res {
		TbfPars pars optional,
		charstring err optional
	}

	type record DCCH_release_req {
	}

	/* PH-DATA.ind / PH-DATA.req */
	type record LAPDm_ph_data {
		boolean sacch,
		GsmSapi sapi,
		LapdmFrame lapdm
	}

	type integer TbfNr (0..7);	/* maximum of 8 concurrent TBF per direction */
	type record TBF_UL_establish_req {
		TbfNr tbf_nr,
		uint8_t ra
	}

	type record TBF_DL_establish_req {
		TbfNr tbf_nr,
		TbfPars pars
	}

	/* PH-DATA.ind / PH-DATA.req */
	type record RLCMAC_ph_data_ind {
		GprsCodingScheme cs,
		uint8_t ts_nr,
		GsmFrameNumber fn,
		RlcmacDlBlock block
	}
	type record RLCMAC_ph_data_req_dyn {
		uint8_t tbf_id,
		GprsCodingScheme cs,
		RlcmacUlBlock block
	}
	type record RLCMAC_ph_data_req_abs {
		uint8_t tbf_id,
		GprsCodingScheme cs,
		uint8_t ts_nr,
		GsmFrameNumber fn,
		Arfcn arfcn,
		RlcmacUlBlock block
	}
	type union RLCMAC_ph_data_req {
		RLCMAC_ph_data_req_dyn	dyn,
		RLCMAC_ph_data_req_abs	abs
	}

	/* port from our (internal) point of view */
	type port LAPDm_SP_PT message {
		in	BCCH_tune_req,
			DCCH_establish_req,
			DCCH_release_req,
			TBF_UL_establish_req,
			TBF_DL_establish_req,
			RLCMAC_ph_data_req,
			LAPDm_ph_data;
		out	DCCH_establish_res,
			TBF_UL_establish_res,
			RLCMAC_ph_data_ind,
			LAPDm_ph_data;
	} with {extension "internal"};

	/* port from user (external) point of view */
	type port LAPDm_PT message {
		in	DCCH_establish_res,
			TBF_UL_establish_res,
			RLCMAC_ph_data_ind,
			LAPDm_ph_data;
		out	BCCH_tune_req,
			DCCH_establish_req,
			DCCH_release_req,
			TBF_UL_establish_req,
			TBF_DL_establish_req,
			RLCMAC_ph_data_req,
			LAPDm_ph_data;
	} with {extension "internal"};

	function LAPDmStart() runs on lapdm_CT {
		f_init();
		ScanEvents();
	}

	/* TS 44.004 Figure 5.1 */
	type enumerated ph_state_enum {
		PH_STATE_NULL,
		PH_STATE_BCH,
		PH_STATE_SEARCHING_BCH,
		PH_STATE_TUNING_DCH,
		PH_STATE_DCH,
		PH_STATE_TBF
	}

	type component lapdm_CT {

		/* L1CTL port towards the bottom */
		port L1CTL_PT L1CTL;
		/* Port towards L2 */
		port LAPDm_SP_PT LAPDM_SP;

		/* physical layer state */
		var ph_state_enum ph_state := PH_STATE_NULL;

		/* channel description of the currently active DCH */
		var ChannelDescription chan_desc;

		var TbfParsPerTs g_tbf_ul;
		var TbfParsPerTs g_tbf_dl;
	};

	/* wrapper function to log state transitions */
	private function set_ph_state(ph_state_enum new_state) runs on lapdm_CT {
		log("PH-STATE ", ph_state, " -> ", new_state);
		ph_state := new_state;
	}

	private function f_init() runs on lapdm_CT {
		f_connect_reset(L1CTL);
		set_ph_state(PH_STATE_NULL);
	}

	/* release the dedicated radio channel */
	private function f_release_dcch() runs on lapdm_CT {
		L1CTL.send(ts_L1CTL_DM_REL_REQ(chan_desc.chan_nr));
		set_ph_state(PH_STATE_BCH);
	}

	/* tune to given ARFCN and start BCCH/CCCH decoding */
	private function f_tune_bcch(Arfcn arfcn, boolean combined) runs on lapdm_CT {
		var L1ctlCcchMode mode := CCCH_MODE_NON_COMBINED;
		if (combined) {
			mode := CCCH_MODE_COMBINED;
		}

		if (ph_state == PH_STATE_DCH) {
			/* release any previous DCH */
			f_release_dcch();
		} else if (ph_state == PH_STATE_TBF) {
			f_release_tbf();
		}

		set_ph_state(PH_STATE_SEARCHING_BCH);

		/* send FB/SB req to sync to cell */
		f_L1CTL_FBSB(L1CTL, arfcn, mode);
		set_ph_state(PH_STATE_BCH);
	}

	/* master function establishing a dedicated radio channel */
	private function f_establish_dcch(uint8_t ra) runs on lapdm_CT {
		var ImmediateAssignment imm_ass;
		var GsmFrameNumber rach_fn;

		/* send RACH request and obtain FN at which it was sent */
		rach_fn := f_L1CTL_RACH(L1CTL, ra);
		//if (not rach_fn) { return; }

		/* wait for receiving matching IMM ASS */
		imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, rach_fn)
		//if (not imm_ass) { return; }
		set_ph_state(PH_STATE_TUNING_DCH);

		/* store/save channel description */
		chan_desc := imm_ass.chan_desc;

		/* send DM_EST_REQ */
		f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass);
		set_ph_state(PH_STATE_DCH);
	}

	/* initialize a tfi_usf array with "not used" value 255 for all TN */
	function f_TfiUsfArrInit() return TfiUsfArr {
		var TfiUsfArr tua := { 255, 255, 255, 255, 255, 255, 255, 255 };
		return tua;
	}

	/* set TFI/USF value for one given timeslot number (index) */
	function f_TfiUsfArrSet(inout TfiUsfArr a, in uint8_t idx, in uint8_t tfi_usf) {
		a[idx] := tfi_usf;
	}

	/* Match an IMM.ASS for an Uplink TBF with a dynamic allocation */
	template ImmediateAssignment t_IMM_ASS_TBF_UL_DYN(uint8_t ra, GsmFrameNumber fn) modifies t_IMM_ASS := {
		ded_or_tbf := { spare := ?, tma := ?, downlink := false, tbf := true},
		chan_desc := omit,
		pkt_chan_desc := ?,
		rest_octets := {
			presence := '11'B,
			ll := omit,
			lh := omit,
			hl := omit,
			hh := {
				presence := '00'B,
				ul := {
					presence := '1'B,
					dynamic := {
						tfi_assignment := ?,
						polling := ?,
						spare := '0'B,
						usf := ?,
						usf_granularity := ?,
						p0_present := ?,
						p0 := *,
						pr_mode := *,
						ch_coding_cmd := ?,
						tlli_block_chan_coding:= ?,
						alpha_present := ?,
						alpha := *,
						gamma := ?,
						ta_index_present := ?,
						ta_index := *,
						tbf_starting_time_present := ?,
						tbf_starting_time := *
					},
					single := omit
				},
				dl := omit
			}
		}
	};

	template (value) RLCMAC_ph_data_req ts_PH_DATA_ABS(uint8_t tbf_id, GprsCodingScheme cs,
							   uint8_t ts, uint32_t fn, Arfcn arfcn,
							   RlcmacUlBlock block) := {
		abs := {
			tbf_id := tbf_id,
			cs := CS1,	/* FIXME */
			ts_nr := ts,
			fn := fn,
			arfcn := arfcn,
			block := block
		}
	}

	private function f_establish_tbf(uint8_t ra) runs on lapdm_CT {
		var ImmediateAssignment imm_ass;
		var GsmFrameNumber rach_fn;
		var TfiUsfArr tua := f_TfiUsfArrInit();

		/* send RACH request and obtain FN at which it was sent */
		rach_fn := f_L1CTL_RACH(L1CTL, ra);

		/* wait for receiving matching IMM ASS */
		imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, rach_fn);

		if (match(imm_ass, t_IMM_ASS_TBF_UL_DYN(ra, rach_fn))) {
			set_ph_state(PH_STATE_TBF);

			/* store/save channel description */
			//chan_desc := imm_ass.chan_desc;

			/* Important: ARFCN, TN, TSC, USF, USF_GRANULARITY, CH_CODING_CMD */
			f_TfiUsfArrSet(tua, imm_ass.pkt_chan_desc.tn, imm_ass.rest_octets.hh.ul.dynamic.usf);
			f_L1CTL_TBF_CFG(L1CTL, true, tua);
		} else {
			/* FIXME: single block uplink allocation */
			log("Failed to match ", t_IMM_ASS_TBF_UL_DYN(ra, rach_fn));
			log("Non-dynamic UL TBF assignment not supported yet");
		}
	}

	private function f_release_tbf() runs on lapdm_CT {
		var TfiUsfArr tua := f_TfiUsfArrInit();
		/* send "all timeslots unused" for both UL and DL */
		f_L1CTL_TBF_CFG(L1CTL, true, tua);
		f_L1CTL_TBF_CFG(L1CTL, false, tua);
		/* L1 will then fall back to BCCH/CCCH */
		set_ph_state(PH_STATE_BCH);
	}

	/* Establish TBF / packet transfer mode */
	private altstep as_tbf_ul_est() runs on lapdm_CT {
		var TBF_UL_establish_req tbf_ul_req;
		[] LAPDM_SP.receive(TBF_UL_establish_req:?) -> value tbf_ul_req {
			var TbfNr tbf_nr := tbf_ul_req.tbf_nr;
			var TBF_UL_establish_res res;
			if (isvalue(g_tbf_ul[tbf_nr].arfcn)) {
				setverdict(fail, "Cannot establish UL TBF ID ", tbf_nr, ": BUSY");
				mtc.stop;
			}
			f_establish_tbf(tbf_ul_req.ra);
			if (ph_state == PH_STATE_TBF) {
				g_tbf_ul[tbf_nr] := valueof(t_TbfParsInit); /* FIXME: Actual TFI[s] */
				log("Established UL TBF ", tbf_nr);
				res := { pars := g_tbf_ul[tbf_nr], err := omit };
			} else {
				res := { pars := omit, err := "Unable to establish UL TBF" };
			}
			LAPDM_SP.send(res);
		}
	}

	private altstep as_tbf_dl_est() runs on lapdm_CT {
		var TBF_DL_establish_req tbf_dl_req;
		[] LAPDM_SP.receive(TBF_DL_establish_req:?) -> value tbf_dl_req {
			var TbfNr tbf_nr := tbf_dl_req.tbf_nr;
			if (isvalue(g_tbf_dl[tbf_nr].arfcn)) {
				setverdict(fail, "Cannot establish DL TBF ID ", tbf_nr, ": BUSY");
				mtc.stop;
			}
			g_tbf_dl[tbf_nr] := tbf_dl_req.pars;
			f_L1CTL_TBF_CFG(L1CTL, false, tbf_dl_req.pars.tfi);
			set_ph_state(PH_STATE_TBF);
			log("Established DL TBF ", tbf_nr, ": ", tbf_dl_req.pars);
		}
	}

	private function f_init_tbf() runs on lapdm_CT {
		var integer i;
		for (i := 0; i < 8; i := i+1) {
			g_tbf_ul[i] := valueof(t_TbfParsInit);
			g_tbf_dl[i] := valueof(t_TbfParsInit);
		}
	}

	function ScanEvents() runs on lapdm_CT {
		var L1ctlDlMessage dl;
		var BCCH_tune_req bt;
		var LAPDm_ph_data lpd;
		var RLCMAC_ph_data_ind rpdi;
		var RLCMAC_ph_data_req rpdr;
		var DCCH_establish_req est_req;
		var DCCH_establish_res est_res;

		f_init_tbf();

		while (true) {
		if (ph_state == PH_STATE_NULL) {
			alt {
			[] LAPDM_SP.receive(BCCH_tune_req:?) -> value bt {
				f_tune_bcch(bt.arfcn, bt.combined_ccch);
			}

			[] LAPDM_SP.receive {}
			[] L1CTL.receive {}

			}
		} else if (ph_state == PH_STATE_BCH or ph_state == PH_STATE_SEARCHING_BCH) {
			alt {
			[] LAPDM_SP.receive(BCCH_tune_req:?) -> value bt {
				f_tune_bcch(bt.arfcn, bt.combined_ccch);
			}

			/* forward CCCH SAPI from L1CTL to User */
			[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0))) -> value dl {
				lpd.sacch := false;
				lpd.sapi := 0;
				lpd.lapdm.bbis := dec_LapdmFrameBbis(dl.payload.data_ind.payload);
				LAPDM_SP.send(lpd);
			}

			/* forward BCCH SAPI from L1CTL to User */
			[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
				lpd.sacch := false;
				lpd.sapi := 0;
				lpd.lapdm.bbis := dec_LapdmFrameBbis(dl.payload.data_ind.payload);
				LAPDM_SP.send(lpd);
			}

			/* Establish dedicated channel */
			[] LAPDM_SP.receive(DCCH_establish_req:?) -> value est_req {
				var DCCH_establish_res res;
				f_establish_dcch(est_req.ra);
				if (ph_state == PH_STATE_DCH) {
					res := { chan_desc, omit };
				} else {
					res := { omit, "Unable to esetablish DCCH" };
				}
				LAPDM_SP.send(res);
			}

			[] as_tbf_ul_est();
			[] as_tbf_dl_est();

			[] LAPDM_SP.receive {}
			[] L1CTL.receive {}

			}

		} else if (ph_state == PH_STATE_TUNING_DCH or ph_state == PH_STATE_DCH) {
			alt {

			/* decode any received DATA frames for the dedicated channel and pass them up */
			[] L1CTL.receive(tr_L1CTL_DATA_IND(chan_desc.chan_nr)) -> value dl {
				if (dl.dl_info.link_id.c == SACCH) {
					lpd.sacch := true;
					/* FIXME: how to deal with UI frames in B4 format (lo length!) */
				} else {
					lpd.sacch := false;
				}
				lpd.sapi := dl.dl_info.link_id.sapi;
				lpd.lapdm.ab := dec_LapdmFrameAB(dl.payload.data_ind.payload);
				LAPDM_SP.send(lpd);
			}

			/* encode any LAPDm record from user and pass it on to L1CTL */
			[] LAPDM_SP.receive(LAPDm_ph_data:?) -> value lpd {
				var octetstring buf;
				var RslLinkId link_id;
				if (lpd.sacch) {
					link_id := valueof(ts_RslLinkID_SACCH(lpd.sapi));
					buf := f_pad_oct(enc_LapdmFrame(lpd.lapdm), 21, '2B'O);
				} else {
					link_id := valueof(ts_RslLinkID_DCCH(lpd.sapi));
					buf := f_pad_oct(enc_LapdmFrame(lpd.lapdm), 23, '2B'O);
				}
				L1CTL.send(ts_L1CTL_DATA_REQ(chan_desc.chan_nr, link_id, buf));
			}

			/* Release dedicated channel */
			[] LAPDM_SP.receive(DCCH_release_req:?) {
				/* go back to BCCH */
				f_release_dcch();
			}

			[] LAPDM_SP.receive {}
			[] L1CTL.receive {}


			}
		} else if (ph_state == PH_STATE_TBF) {
			alt {

			/* decode + forward any blocks from L1 to L23*/
			[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PDCH(?))) -> value dl {
				rpdi.block := dec_RlcmacDlBlock(dl.payload.data_ind.payload);
				/* FIXME: Filter based on g_tbf_dl */
				rpdi.fn := dl.dl_info.frame_nr;
				rpdi.ts_nr := dl.dl_info.chan_nr.tn;
				rpdi.cs := CS1; /* FIXME */
				log("RPDI: ", rpdi);
				LAPDM_SP.send(rpdi);
			}

			[] L1CTL.receive { }

			/* encode + forward any blocks from L23 to L1 */
			[] LAPDM_SP.receive(RLCMAC_ph_data_req:?) -> value rpdr {
				var octetstring buf;
				if (ischosen(rpdr.dyn)) {
					buf := enc_RlcmacUlBlock(rpdr.dyn.block);
					L1CTL.send(ts_L1CTL_DATA_TBF_REQ(buf, L1CTL_CS1, rpdr.dyn.tbf_id));
				} else {
					buf := enc_RlcmacUlBlock(rpdr.abs.block);
					L1CTL.send(ts_L1CTL_DATA_ABS_REQ(buf, rpdr.abs.arfcn,
									rpdr.abs.ts_nr, rpdr.abs.fn,
									L1CTL_CS1, rpdr.abs.tbf_id));
				}
			}

			[] as_tbf_ul_est();
			[] as_tbf_dl_est();

			/* FIXME: release TBF mode */
			[] LAPDM_SP.receive(DCCH_release_req:?) {
				/* go back to BCCH */
				f_release_tbf();
				f_init_tbf();
			}

			}
		}

		} /* while (1) */
	}
}
