/* dual-faced port that wraps an Unixdomain port and encodes/decodes L1CTL */
module L1CTL_PortType {
	import from L1CTL_Types all;
	import from UD_PortType all;
	import from UD_Types all;
	import from Osmocom_Types all;
	import from GSM_Types all;
	import from GSM_RR_Types all;

	type record L1CTL_connect {
		charstring	path
	}

	type record L1CTL_connect_result {
		UD_Result_code	result_code optional,
		charstring	err optional
	}

	function f_L1CTL_FBSB(L1CTL_PT pt, Arfcn arfcn, L1ctlCcchMode ccch_mode := CCCH_MODE_COMBINED) {
		timer T := 5.0;
		pt.send(t_L1CTL_FBSB_REQ(arfcn, t_L1CTL_FBSB_F_ALL, 0, ccch_mode, 0));
		T.start
		alt {
			[] pt.receive(t_L1CTL_FBSB_CONF(0)) {};
			[] pt.receive { repeat; };
			[] T.timeout { setverdict(fail, "Timeout in FBSB") };
		}
	}

	function f_L1CTL_RACH(L1CTL_PT pt, uint8_t ra, uint8_t combined := 1, uint16_t offset := 0) return GsmFrameNumber {
		var L1ctlDlMessage rc;
		var GsmFrameNumber fn;
		timer T := 2.0;
		T.start
		pt.send(t_L1CTL_RACH_REQ(ra, 0, 0))
		alt {
			[] pt.receive(t_L1CTL_RACH_CONF) -> value rc { fn := rc.dl_info.frame_nr };
			[] pt.receive { repeat; };
			[] T.timeout { setverdict(fail, "Timeout in RACH") };
		}
		return fn;
	}

	function f_L1CTL_WAIT_IMM_ASS(L1CTL_PT pt, uint8_t ra, GsmFrameNumber rach_fn) return ImmediateAssignment {
		var L1ctlDlMessage dl;
		var GsmRrMessage rr;
		timer T := 10.0;
		T.start;
		alt {
			[] pt.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
				rr := dec_GsmRrMessage(dl.payload.data_ind.payload);
				log("PCH/AGCN DL RR: ", rr);
				if (match(rr, t_RR_IMM_ASS(ra, rach_fn))) {
					log("Received IMM.ASS for our RACH!");
				} else {
					repeat;
				}
			};
			[] pt.receive { repeat };
			[] T.timeout { setverdict(fail, "Timeout waiting for IMM ASS") };
		}
		T.stop;
		return rr.payload.imm_ass;
	}

	function f_L1CTL_TBF_CFG(L1CTL_PT pt, boolean is_uplink, TfiUsfArr tfi_usf) {
		timer T := 2.0;
		T.start;
		pt.send(t_L1CTL_TBF_CFG_REQ(is_uplink, tfi_usf));
		alt {
			[] pt.receive(t_L1CTL_TBF_CFG_CONF(is_uplink)) {}
			[] pt.receive { repeat };
			[] T.timeout { setverdict(fail, "Timeout waiting for TBF-CFG.conf") };
		}
		T.stop;
	}

	/* Send DM_EST_REQ from parameters derived from IMM ASS */
	function f_L1CTL_DM_EST_REQ_IA(L1CTL_PT pt, ImmediateAssignment imm_ass) {
		pt.send(t_L1CTL_DM_EST_REQ({ false, imm_ass.chan_desc.arfcn }, imm_ass.chan_desc.chan_nr, imm_ass.chan_desc.tsc));
	}

	function f_connect_reset(L1CTL_PT pt, charstring l1ctl_sock_path := "/tmp/osmocom_l2") {
		pt.send(L1CTL_connect:{path:=l1ctl_sock_path});
		pt.receive(L1CTL_connect_result:{result_code := SUCCESS, err:=omit});

		pt.send(t_L1ctlResetReq(L1CTL_RES_T_SCHED));
		pt.receive;
	}

	private function L1CTL_to_UD_connect(in L1CTL_connect pin, out UD_connect pout) {
		pout.path := pin.path;
		pout.id := 0;
	} with { extension "prototype(fast)" }

	private function UD_to_L1CTL_connect_result(in UD_connect_result pin, out L1CTL_connect_result pout) {
		pout.result_code := pin.result.result_code;
		pout.err := pin.result.err;
	} with { extension "prototype(fast)" }

	private function L1CTL_to_UD_ul(in L1ctlUlMessage pin, out UD_send_data pout) {
		var L1ctlUlMessageLV msg_lv := { msg := pin };
		pout.data := enc_L1ctlUlMessageLV(msg_lv);
		pout.id := 0;
	} with { extension "prototype(fast)" }

	private function UD_to_L1CTL_dl(in UD_send_data pin, out L1ctlDlMessage pout) {
		var L1ctlDlMessageLV msg_lv := dec_L1ctlDlMessageLV(pin.data);
		pout:= msg_lv.msg;
	} with { extension "prototype(fast)" }

	type port L1CTL_PT message {
		out L1ctlUlMessage
		out L1CTL_connect
		in L1ctlDlMessage
		in L1CTL_connect_result
		in UD_listen_result
		in UD_connected
	} with { extension "user UD_PT
		out(L1ctlUlMessage -> UD_send_data: function(L1CTL_to_UD_ul);
		    L1CTL_connect -> UD_connect: function(L1CTL_to_UD_connect))
		in(UD_send_data -> L1ctlDlMessage: function(UD_to_L1CTL_dl);
		   UD_connect_result -> L1CTL_connect_result: function(UD_to_L1CTL_connect_result);
		   UD_listen_result -> UD_listen_result: simple;
		   UD_connected -> UD_connected: simple
		)" }
}
