/* 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) {
		timer T := 15.0;
		for (var integer i := 0; i < 10; i := i+1) {
			pt.send(ts_L1CTL_FBSB_REQ(arfcn, valueof(t_L1CTL_FBSB_F_ALL), 0, ccch_mode, 57));
			T.start
			alt {
			[] pt.receive(tr_L1CTL_FBSB_CONF(0)) { return; };
			[i >= 9] pt.receive(tr_L1CTL_FBSB_CONF(?)) {
				setverdict(fail, "FBSB Failed with non-zero return code");
				self.stop;
				};
			[] pt.receive(tr_L1CTL_FBSB_CONF(?)) {
				f_sleep(1.0);
				}
			[] pt.receive { repeat; };
			[] T.timeout {
				setverdict(fail, "Timeout in FBSB") 
				self.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");
			self.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");
				self.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");
				self.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");
				self.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");
				self.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");
				self.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
		)" }
}
