/* 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 Osmocom_Types all;
	import from GSM_Types all;
	import from GSM_RR_Types all;
	import from L1CTL_PortType_CtrlFunct all;

	type record L1CTL_connect {
		charstring	path
	}

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

	modulepar {
		charstring	m_l1ctl_sock_path := "/tmp/osmocom_l2";
	}

	function f_L1CTL_getMsgLen(in octetstring stream, inout ro_integer args) return integer {
		var integer stream_len := lengthof(stream);
		var integer len;
		if (stream_len < 2) {
			return -1;
		}
		len := 2 + oct2int(substr(stream, 0, 2));
		return len;
	}

	function f_L1CTL_FBSB(L1CTL_PT pt, Arfcn arfcn, L1ctlCcchMode ccch_mode := CCCH_MODE_COMBINED, integer rxlev_exp := 57) {
		timer T := 15.0;
		for (var integer i := 0; i < 10; i := i+1) {
			var L1ctlDlMessage dl;
			pt.send(ts_L1CTL_FBSB_REQ(arfcn, valueof(t_L1CTL_FBSB_F_ALL), 0, ccch_mode, rxlev_exp));
			T.start
			alt {
			[] pt.receive(tr_L1CTL_FBSB_CONF(0)) { return; };
			[i >= 9] pt.receive(tr_L1CTL_FBSB_CONF(?)) -> value dl {
				setverdict(fail, "FBSB Failed with non-zero return code ", dl.payload.fbsb_conf.result);
				mtc.stop;
				};
			[] pt.receive(tr_L1CTL_FBSB_CONF(?)) {
				f_sleep(1.0);
				}
			[] pt.receive { repeat; };
			[] T.timeout {
				setverdict(fail, "Timeout in FBSB") 
				mtc.stop;
				};
			}
		}
	}

	function f_L1CTL_CCCH_MODE(L1CTL_PT pt, L1ctlCcchMode ccch_mode) {
		timer T := 2.0;
		pt.send(ts_L1CTL_CCCH_MODE_REQ(ccch_mode));
		T.start;
		alt {
		[] pt.receive(tr_L1CTL_CCCH_MODE_CONF) { }
		[] pt.receive { repeat; }
		[] T.timeout {
			setverdict(fail, "Timeout in CCH_MODE");
			mtc.stop;
			}
		}
	}

	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(ts_L1CTL_RACH_REQ(ra, combined, offset))
		alt {
			[] pt.receive(tr_L1CTL_RACH_CONF) -> value rc { fn := rc.dl_info.frame_nr };
			[] pt.receive { repeat; };
			[] T.timeout {
				setverdict(fail, "Timeout in RACH");
				mtc.stop;
				}
		}
		return fn;
	}

	function f_L1CTL_PARAM(L1CTL_PT pt, uint8_t ta, uint8_t tx_power) {
		pt.send(ts_L1CTL_PAR_REQ(ta, tx_power));
	}

	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(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
				rr := dec_GsmRrMessage(dl.payload.data_ind.payload);
				log("PCH/AGCH 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");
				mtc.stop;
				}
		}
		T.stop;
		return rr.payload.imm_ass;
	}

	function f_L1CTL_WAIT_IMM_ASS_TBF_DL(L1CTL_PT pt, GprsTlli tlli) return ImmediateAssignment {
		var L1ctlDlMessage dl;
		var GsmRrMessage rr;
		timer T := 10.0;
		T.start;
		alt {
			[] pt.receive(tr_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_TBF_DL(tlli))) {
					log("Received IMM.ASS for our TLLI!");
				} else {
					repeat;
				}
			};
			[] pt.receive { repeat };
			[] T.timeout {
				setverdict(fail, "Timeout waiting for IMM ASS");
				mtc.stop;
				}
		}
		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(ts_L1CTL_TBF_CFG_REQ(is_uplink, tfi_usf));
		alt {
			[] pt.receive(tr_L1CTL_TBF_CFG_CONF(is_uplink)) {}
			[] pt.receive { repeat };
			[] T.timeout {
				setverdict(fail, "Timeout waiting for TBF-CFG.conf");
				mtc.stop;
				};
		}
		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(ts_L1CTL_DM_EST_REQ({ false, imm_ass.chan_desc.arfcn }, imm_ass.chan_desc.chan_nr, imm_ass.chan_desc.tsc));
	}

	/* Send DM_REL_REQ from parameters derived from IMM ASS */
	function f_L1CTL_DM_REL_REQ(L1CTL_PT pt, RslChannelNr chan_nr) {
		pt.send(ts_L1CTL_DM_REL_REQ(chan_nr));
	}

	function f_L1CTL_RESET(L1CTL_PT pt, L1ctlResetType res_type := L1CTL_RES_T_FULL) {
		timer T := 2.0;
		pt.send(t_L1ctlResetReq(res_type));
		T.start;
		alt {
			[] pt.receive(tr_L1CTL_MsgType(L1CTL_RESET_CONF)) { }
			[] pt.receive { repeat; }
			[] T.timeout {
				setverdict(fail, "Timeout waiting for RESET.conf");
				mtc.stop;
				}
		}
	}

	function f_L1CTL_CRYPTO_REQ(L1CTL_PT pt, RslChannelNr chan_nr, uint8_t algo, octetstring key) {
		pt.send(ts_L1CTL_CRYPTO_REQ(chan_nr, algo, key));
	}

	function f_connect_reset(L1CTL_PT pt, charstring l1ctl_sock_path := m_l1ctl_sock_path) {
		var f_UD_getMsgLen vl_f := refers(f_L1CTL_getMsgLen);
		f_L1CTL_setGetMsgLen(pt, -1, vl_f, {});
		pt.send(L1CTL_connect:{path:=l1ctl_sock_path});
		pt.receive(L1CTL_connect_result:{result_code := SUCCESS, err:=omit});
		f_L1CTL_setGetMsgLen(pt, 0, vl_f, {});
		f_L1CTL_RESET(pt);
	}

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