/* 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 */
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(t_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");
				self.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");
				self.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(t_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(t_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(t_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.b := dec_LapdmFrameB(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));
				} else {
					link_id := valueof(ts_RslLinkID_DCCH(lpd.sapi));
				}
				buf := enc_LapdmFrame(lpd.lapdm);
				L1CTL.send(t_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(t_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(t_L1CTL_DATA_TBF_REQ(buf, L1CTL_CS1, rpdr.dyn.tbf_id));
				} else {
					buf := enc_RlcmacUlBlock(rpdr.abs.block);
					L1CTL.send(t_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) */
	}
}
