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

	/* 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 DCCH_release_req {
	}

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

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

	/* port from user (external) point of view */
	type port LAPDm_PT message {
		in	DCCH_establish_res,
			LAPDm_ph_data;
		out	BCCH_tune_req,
			DCCH_establish_req,
			DCCH_release_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
	}

	type component lapdm_CT {
		var charstring l1ctl_sock_path := "/tmp/osmocom_l2";

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

	/* 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, l1ctl_sock_path);
		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_NULL);
	}

	/* 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();
		}

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

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

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

			[] 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 {}


			}
		}
		} /* while (1) */
	}
}
