/* 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(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");
				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(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));
				} else {
					link_id := valueof(ts_RslLinkID_DCCH(lpd.sapi));
				}
				buf := enc_LapdmFrame(lpd.lapdm);
				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) */
	}
}
