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

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

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