/* 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 GSM_RestOctets 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;

	type record length(8) of uint8_t TfiUsfArr;

	/* request to tune to a given ARFCN and start BCCH decoding */
	type record BCCH_tune_req {
		GsmBandArfcn 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
	}

	/* directly switch to a dedicated channel (without RACH/IMM.ASS */
	type record DCCH_switch_req {
		ChannelDescription chan_desc,
		L1ctlMA ma optional
	}

	type record DCCH_switch_res {
		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,
		GsmBandArfcn 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_switch_req,
			DCCH_release_req,
			TBF_UL_establish_req,
			TBF_DL_establish_req,
			RLCMAC_ph_data_req,
			LAPDm_ph_data;
		out	DCCH_establish_res,
			DCCH_switch_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,
			DCCH_switch_res,
			TBF_UL_establish_res,
			RLCMAC_ph_data_ind,
			LAPDm_ph_data;
		out	BCCH_tune_req,
			DCCH_establish_req,
			DCCH_switch_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;

		/* last SACCH downlink L1 header we received */
		var uint5_t ms_power_lvl := 0;
		var uint8_t timing_adv := 0;

		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(GsmBandArfcn 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, TODO: Mobile Allocation */
		f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass);
		set_ph_state(PH_STATE_DCH);
	}

	/* switching directly to a dedicated channel *without RACH/IMM-ASS */
	private function f_switch_dcch(in DCCH_switch_req sw_req) runs on lapdm_CT {
		set_ph_state(PH_STATE_TUNING_DCH);
		/* store/save channel description */
		chan_desc := sw_req.chan_desc;

		/* tune the L1 to the indicated channel */
		if (chan_desc.h) {
			L1CTL.send(ts_L1CTL_DM_EST_REQ_H1(chan_desc.chan_nr,
							  chan_desc.tsc,
							  chan_desc.maio_hsn.hsn,
							  chan_desc.maio_hsn.maio,
							  sw_req.ma));
		} else {
			L1CTL.send(ts_L1CTL_DM_EST_REQ_H0(chan_desc.chan_nr,
							  chan_desc.tsc,
							  chan_desc.arfcn));
		}

		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;
	}

	template (value) RLCMAC_ph_data_req ts_PH_DATA_ABS(uint8_t tbf_id, GprsCodingScheme cs,
							   uint8_t ts, uint32_t fn,
							   GsmBandArfcn 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 return boolean {
		var template GsmRrMessage imm_ass_rr;
		var ImmediateAssignment imm_ass;
		var PacketUlAssign pkt_ul_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);

		/* make sure we got *Packet* (Uplink) Immediate Assignment */
		imm_ass_rr := tr_IMM_TBF_ASS(dl := false, ra := ra, fn := rach_fn,
					     rest := tr_IaRestOctets_ULAss(?));
		if (not match(imm_ass, imm_ass_rr.payload.imm_ass)) {
			log("Failed to match Packet Immediate Assignment");
			return false;
		}

		/* decapsulate PacketUlAssign for further matching */
		pkt_ul_ass := imm_ass.rest_octets.hh.pa.uldl.ass.ul;

		/* Dynamic Block Allocation */
		if (match(pkt_ul_ass, tr_PacketUlDynAssign)) {
			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, pkt_ul_ass.dynamic.usf);
			// FIXME: f_L1CTL_TBF_CFG(L1CTL, true, tua);
			return true;
		/* FIXME: Single Block Allocation */
		} else if (match(pkt_ul_ass, tr_PacketUlSglAssign)) {
			log("Non-dynamic UL TBF assignment not supported yet");
			return false;
		} else {
			log("Failed to match Uplink Block Allocation: ", pkt_ul_ass);
			return false;
		}
	}

	private function f_release_tbf() runs on lapdm_CT {
		var TfiUsfArr tua := f_TfiUsfArrInit();
		/* send "all timeslots unused" for both UL and DL */
		// FIXME: f_L1CTL_TBF_CFG(L1CTL, true, tua);
		// FIXME: 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;
			// FIXME: 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 L1ctlMessage 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_switch_req sw_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);
			}
			[] LAPDM_SP.receive(DCCH_switch_req:?) -> value sw_req {
				var DCCH_switch_res res;
				f_switch_dcch(sw_req);
				if (ph_state == PH_STATE_DCH) {
					res := { omit };
				} else {
					res := { "Unable to switch to 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 {
				var octetstring l2;
				if (dl.dl_info.link_id.c == SACCH) {
					lpd.sacch := true;
					var octetstring l1 := substr(dl.payload.data_ind.payload, 0, 2);
					l2 := substr(dl.payload.data_ind.payload, 2,
						     lengthof(dl.payload.data_ind.payload)-2);
					ms_power_lvl := oct2int(l1[0] and4b '1F'O);
					timing_adv := oct2int(l1[1]);
					/* FIXME: how to deal with UI frames in B4 format (lo length!) */
				} else {
					lpd.sacch := false;
					l2 := dl.payload.data_ind.payload;
				}
				lpd.sapi := dl.dl_info.link_id.sapi;
				lpd.lapdm.ab := dec_LapdmFrameAB(l2);
				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);
					var SacchL1Header l1h := valueof(ts_SacchL1Header(ms_power_lvl,
											  timing_adv));
					L1CTL.send(ts_L1CTL_DATA_REQ_SACCH(chan_desc.chan_nr, link_id,
									   l1h, buf));
				} 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);
					// FIXME: L1CTL.send(ts_L1CTL_DATA_TBF_REQ(buf, L1CTL_CS1, rpdr.dyn.tbf_id));
				} else {
					buf := enc_RlcmacUlBlock(rpdr.abs.block);
					// FIXME: 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) */
	}
}
