module RSL_Emulation {

/* RSL Emulation, runs on top of IPA_Emulation.  It multiplexes/demultiplexes
 * the individual connections (logical channels), so there can be separate TTCN-3 components
 * handling each of the connections.
 *
 * The RSL_Emulation.main() function processes RSL messages from the IPA demultiplex
 * stack via the IPA_RSL_PT, and dispatches them to the per-connection components.
 *
 * Outbound RSL connections are initiated by sending a RSLDC_ChanRqd primitive
 * to the component running the RSL_Emulation.main() function.
 *
 * in case we're emulating the BTS-side of RSL: We have no clue as to which particular logical
 * channel the BSC may decide to activate at which point, so we have to blindly acknowledge all
 * channel activations.  Still, a test case might be interested in the exact assignment message to
 * determine the type of activation, encryption, codec flags etc. at some later point, when it's
 * clear for which transaction this activation happened.  We keep this in the LastChanAct table.
 *
 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 */

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RR_Types all;
import from RSL_Types all;
import from IPA_Types all;
import from IPA_Emulation all;


/* General "base class" component definition, of which specific implementations
 * derive themselves by means of the "extends" feature */
type component RSL_DchanHdlr {
	/* port facing up towards dedicated channel handler */
	port RSL_DCHAN_PT RSL;
	port RSLEM_PROC_PT RSL_PROC;
	var RslChannelNr g_chan_nr;
	/* second BTS / DChan during hand-over */
	port RSL_DCHAN_PT RSL1;
	port RSLEM_PROC_PT RSL1_PROC;
};

type record RSLDC_ChanRqd {
	OCT1		ra,
	GsmFrameNumber	fn
};

template RSLDC_ChanRqd ts_RSLDC_ChanRqd(OCT1 ra, GsmFrameNumber fn) := {
	ra := ra,
	fn := fn
}

type port RSL_DCHAN_PT message {
	inout RSLDC_ChanRqd, RSL_Message;
} with { extension "internal" };

type port RSL_CCHAN_PT message {
	inout ASP_RSL_Unitdata, ASP_IPA_Event;
} with { extension "internal" };


signature RSLEM_register(uint8_t trx_nr, RslChannelNr chan_nr, RSL_DchanHdlr hdlr);
signature RSLEM_unregister(uint8_t trx_nr, RslChannelNr chan_nr, RSL_DchanHdlr hdlr);
signature RSLEM_suspend(boolean suspend);
signature RSLEM_get_last_act(in uint8_t trx_nr, in RslChannelNr chan_nr, out RSL_Message chan_act);

type port RSLEM_PROC_PT procedure {
	inout RSLEM_register, RSLEM_unregister, RSLEM_suspend, RSLEM_get_last_act;
} with { extension "internal" };

/***********************************************************************
 * Client Component for a single dedicated channel
 ***********************************************************************/

private function f_rx_or_fail(template RSL_Message exp_rx) runs on RSL_DchanHdlr return RSL_Message
{
	var RSL_Message rx_rsl;
	timer T := 10.0;

	/* request a channel to be established */
	T.start;
	alt {
		[] RSL.receive(exp_rx) -> value rx_rsl {
			T.stop;
			return rx_rsl;
		}
		[] RSL.receive {
			setverdict(fail, "Unexpected RSL message on DCHAN");
			self.stop;
		}
		[] T.timeout {
			setverdict(fail, "Timeout waiting for RSL on DCHAN");
			self.stop;
		}
	}
	/* never reached */
	return rx_rsl;
}

/* establish a dedicated channel using 'ra' */
function f_chan_est(OCT1 ra, octetstring est_l3, template RslLinkId link_id, GsmFrameNumber fn := 23)
runs on RSL_DchanHdlr {
	var RSL_Message rx_rsl;
	var GsmRrMessage rr;

	/* request a channel to be established */
	RSL.send(ts_RSLDC_ChanRqd(ra, fn));
	/* expect immediate assignment */
	rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
	rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
	g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
	RSL.send(ts_RSL_EST_IND(g_chan_nr, valueof(link_id), est_l3));
}

function f_deact_chan(RSL_Cause cause) runs on RSL_DchanHdlr
{
	var RSL_Message rx_rsl;

	RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, cause));
	rx_rsl := f_rx_or_fail(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL));
	/* FIXME RSL.send(ts_RSL_RF_CHAN_REL_ACK()) */
}



/***********************************************************************
 * Main Component
 ***********************************************************************/

private type record ConnectionData {
	/* component reference to the client component */
	RSL_DchanHdlr	comp_ref,
	/* RSL (dedicated) Channel number we're handling */
	uint8_t		trx_nr optional,
	IpaStreamId	stream_id optional,
	RslChannelNr	chan_nr optional,
	/* Random Reference */
	OCT1		ra optional,
	GsmFrameNumber	ra_fn optional
};

private function f_cid_by_comp_ref(RSL_DchanHdlr comp_ref)
runs on RSL_Emulation_CT return integer {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ispresent(ConnectionTable[i].comp_ref) and 
		    ConnectionTable[i].comp_ref == comp_ref) {
			return i;
		}
	}
	log("No Dchan handler for ", comp_ref);
	return -1;
}

private function f_cid_by_chan_nr(uint8_t trx_nr, RslChannelNr chan_nr)
runs on RSL_Emulation_CT return integer {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ispresent(ConnectionTable[i].chan_nr) and 
		    ConnectionTable[i].chan_nr == chan_nr and ConnectionTable[i].trx_nr == trx_nr) {
			return i;
		}
	}
	log("No Dchan handler for ", trx_nr, chan_nr);
	return -1;
}

private function f_cid_by_ra_fn(OCT1 ra, GsmFrameNumber fn)
runs on RSL_Emulation_CT return integer {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ispresent(ConnectionTable[i].ra) and
		    ConnectionTable[i].ra == ra and ConnectionTable[i].ra_fn == fn) {
			return i;
		}
	}
	log("No Dchan handler for ", ra, fn);
	return -1;
}

/* create an ew client with given RA and FN */
private function f_cid_create(OCT1 ra, GsmFrameNumber fn, RSL_DchanHdlr comp_ref)
runs on RSL_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (not ispresent(ConnectionTable[i].ra) and
		    not ispresent(ConnectionTable[i].trx_nr)) {
			ConnectionTable[i].ra := ra;
			ConnectionTable[i].ra_fn := fn;
			ConnectionTable[i].comp_ref := comp_ref;
			return;
		}
	}
	setverdict(fail, "No free entry in conn table for ", ra, fn);
}

/* create an ew client with given RA and FN */
private function f_cid_create_cnr(uint8_t trx_nr, RslChannelNr chan_nr,  RSL_DchanHdlr comp_ref)
runs on RSL_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (not ispresent(ConnectionTable[i].ra) and
		    not ispresent(ConnectionTable[i].trx_nr)) {
			ConnectionTable[i].stream_id := f_streamId_by_trx(trx_nr);
			ConnectionTable[i].trx_nr := trx_nr;
			ConnectionTable[i].chan_nr := chan_nr;
			ConnectionTable[i].comp_ref := comp_ref;
			return;
		}
	}
	setverdict(fail, "No free entry in conn table for ", trx_nr, chan_nr, comp_ref);
}


/* create an ew client with given RA and FN */
private function f_cid_delete_cnr(IpaStreamId stream_id, RslChannelNr chan_nr,  RSL_DchanHdlr comp_ref)
runs on RSL_Emulation_CT return integer {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == null) {
			continue;
		}
		if (ConnectionTable[i].stream_id == stream_id and
		    ConnectionTable[i].chan_nr == chan_nr and
		    ConnectionTable[i].comp_ref == comp_ref) {
			f_cid_clear(i);
		}
	}
	log("Unable to find entry to delete for ", stream_id, chan_nr, comp_ref);
	return -1;
}


private function f_cid_clear(integer cid)
runs on RSL_Emulation_CT {
	ConnectionTable[cid].ra := omit;
	ConnectionTable[cid].ra_fn := omit;
	ConnectionTable[cid].trx_nr := omit;
	ConnectionTable[cid].stream_id := omit;
	ConnectionTable[cid].chan_nr := omit;
	ConnectionTable[cid].comp_ref := null;
}

/* last activation for a given channel number */
type record LastActData {
	uint8_t		trx_nr optional,
	RslChannelNr	chan_nr optional,
	RSL_Message	chan_act optional
}

private function f_store_last_act_data(uint8_t trx_nr, RslChannelNr chan_nr, RSL_Message chan_act)
runs on RSL_Emulation_CT {
	for (var integer i := 0; i < sizeof(LastActTable); i := i+1) {
		if (not ispresent(LastActTable[i].chan_nr) or
		    (LastActTable[i].chan_nr == chan_nr and LastActTable[i].trx_nr == trx_nr)) {
			LastActTable[i].trx_nr := trx_nr;
			LastActTable[i].chan_nr := chan_nr;
			LastActTable[i].chan_act := chan_act;
			return;
		}
	}
	setverdict(fail, "No space left in LastActTable to store chan_act for ", chan_nr);
	self.stop;
}

private function f_lookup_last_act(uint8_t trx_nr, RslChannelNr chan_nr)
runs on RSL_Emulation_CT return RSL_Message {
	for (var integer i := 0; i < sizeof(LastActTable); i := i+1) {
		if (ispresent(LastActTable[i].chan_nr) and LastActTable[i].chan_nr == chan_nr
		    and LastActTable[i].trx_nr == trx_nr) {
			return LastActTable[i].chan_act;
		}
	}
	setverdict(fail, "No LastActTable entry found for TRX ", trx_nr, " ", chan_nr);
	self.stop;
}

private function f_last_act_table_init() runs on RSL_Emulation_CT {
	for (var integer i := 0; i < sizeof(LastActTable); i := i+1) {
		LastActTable[i] := { omit, omit, omit };
	}
}

type component RSL_Emulation_CT {
	/* port facing down towards IPA emulation */
	port IPA_RSL_PT IPA_PT;
	/* port facing up towards dedicated channel handler */
	port RSL_DCHAN_PT CLIENT_PT;
	port RSLEM_PROC_PT RSL_PROC;

	/* port for Common Channel / TRX Management */
	port RSL_CCHAN_PT CCHAN_PT;

	/* state of all concurrent connections / dedicated channels */
	var ConnectionData ConnectionTable[64];

	/* last RSL CHAN ACT for each chan_nr */
	var LastActData LastActTable[64];
}


/* template for an ASP_RSL_Unitdata as we receive it from the IPA_Emulateion component */
private template ASP_RSL_Unitdata tr_RSL(template RSL_Message rsl, template IpaStreamId sid := ?) := {
	streamId := sid,
	rsl := rsl
}

private function f_trx_by_streamId(IpaStreamId id) return integer {
	return enum2int(id);
}

private function f_streamId_by_trx(uint8_t trx_nr) return IpaStreamId {
	select (trx_nr) {
	case (0) { return IPAC_PROTO_RSL_TRX0; }
	case (1) { return IPAC_PROTO_RSL_TRX1; }
	case (2) { return IPAC_PROTO_RSL_TRX2; }
	case (3) { return IPAC_PROTO_RSL_TRX3; }
	}
	self.stop;
}


function main(boolean bts_role := true) runs on RSL_Emulation_CT {
	var ASP_IPA_Event evt;
	var ASP_RSL_Unitdata rx_rsl;
	var RSL_Message rx_rsl_msg;
	var RSLDC_ChanRqd chan_rqd;
	var RSL_DchanHdlr vc_conn;
	var RslChannelNr chan_nr;
	var uint8_t trx_nr;
	var integer cid;
	var integer i;
	/* special synchronization handling during hand-over */
	var boolean dchan_suspended := false;

	f_conn_table_init();
	f_last_act_table_init();

	while (true) {
		alt {
		[bts_role] IPA_PT.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) {
			}
		[not bts_role] IPA_PT.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) -> value evt {
			CCHAN_PT.send(evt);
			}
		[bts_role] IPA_PT.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_ID_ACK}) {
			IPA_PT.send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_PAGING_LOAD_IND(23)));
			}
		[bts_role] IPA_PT.receive(tr_RSL(tr_RSL_IMM_ASSIGN)) -> value rx_rsl {
			var GsmRrMessage rr;
			var OCT1 ra;
			var GsmFrameNumber fn;
			log("IMM ASS INFO ", rx_rsl.rsl.ies[1].body);
			rr := dec_GsmRrMessage(rx_rsl.rsl.ies[1].body.full_imm_ass_info.payload);
			if (ischosen(rr.payload.imm_ass)) {
				ra := bit2oct(rr.payload.imm_ass.req_ref.ra);
				fn := 23; //FIXME(rr.payload.imm_ass);
				/* lookup client based on RA+time, deliver to client */
				cid := f_cid_by_ra_fn(ra, fn);
				if (cid == -1) {
					setverdict(fail, "IMM ASS for unknown DChan");
					self.stop;
				}
				/* update client with trx_nr */
				ConnectionTable[cid].trx_nr := f_trx_by_streamId(rx_rsl.streamId);
				ConnectionTable[cid].stream_id := rx_rsl.streamId;
				/* update client with chan_nr */
				ConnectionTable[cid].chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
				/* TODO: add timer to time-out ConnectionTable entries which
				 * never get followed-up to */
				CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[cid].comp_ref;
			} else if (ischosen(rr.payload.imm_ass_rej)) {
				for (i := 0; i < sizeof(rr.payload.imm_ass_rej.payload); i := i + 1) {
					ra := bit2oct(rr.payload.imm_ass_rej.payload[i].req_ref.ra);
					fn := 23; //FIXME();
					/* lookup client based on RA+time, deliver to client */
					cid := f_cid_by_ra_fn(ra, fn);
					if (cid != -1) {
						CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[cid].comp_ref;
						/* delete ClientTable entry, as it failed */
						f_cid_clear(cid);
					}
				}
			}
		}

		[bts_role] IPA_PT.receive(tr_RSL(tr_RSL_PAGING_CMD(?, ?))) -> value rx_rsl {
			log("PAGING IDENTITY ", rx_rsl.rsl.ies[2].body.other);
			/* broadcast to all clients? */
			for (i := 0; i < sizeof(ConnectionTable); i := i + 1) {
				if (ispresent(ConnectionTable[i].comp_ref)) {
					CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[i].comp_ref;
				}
			}
		}

		/* Forward common channel management to the special port for it */
		[] IPA_PT.receive(tr_RSL(tr_RSL_MsgTypeT(?))) -> value rx_rsl {
			log("Forwarding TRX Mgmt ", rx_rsl.rsl);
			CCHAN_PT.send(rx_rsl);
		}

		/* Forward common channel management to the special port for it */
		[] IPA_PT.receive(tr_RSL(tr_RSL_MsgTypeC(?))) -> value rx_rsl {
			log("Forwarding Common Channel Mgmt ", rx_rsl.rsl);
			CCHAN_PT.send(rx_rsl);
		}

		/* blindly acknowledge all channel activations */
		[bts_role] IPA_PT.receive(tr_RSL(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) -> value rx_rsl {
			chan_nr := rx_rsl.rsl.ies[0].body.chan_nr;
			trx_nr := f_trx_by_streamId(rx_rsl.streamId);
			f_store_last_act_data(trx_nr, chan_nr, rx_rsl.rsl);
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl.streamId, ts_RSL_CHAN_ACT_ACK(chan_nr, 23)));
		}

		[not dchan_suspended] IPA_PT.receive(tr_RSL(tr_RSL_MsgTypeDR(?))) -> value rx_rsl {
			/* dispatch to channel based on ChanId */
			cid := f_cid_by_chan_nr(f_trx_by_streamId(rx_rsl.streamId),
						rx_rsl.rsl.ies[0].body.chan_nr);
			if (cid != -1) {
				CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[cid].comp_ref;
			} else {
				setverdict(fail, "RSL for unknown Dchan");
			}
		}

		[not dchan_suspended] IPA_PT.receive {
			setverdict(fail, "Received unknown primitive from IPA");
			self.stop;
		}

		[bts_role] CLIENT_PT.receive(RSLDC_ChanRqd:?) -> value chan_rqd sender vc_conn {
			/* Store the knowledge that this sender has requested a certain RQ+time */
			f_cid_create(chan_rqd.ra, chan_rqd.fn, vc_conn);
			IPA_PT.send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
						 ts_RSL_CHAN_RQD(chan_rqd.ra, chan_rqd.fn)));
			}

		[] CLIENT_PT.receive(tr_RSL_MsgType(?)) -> value rx_rsl_msg sender vc_conn {
			/* forward to BSC */
			cid := f_cid_by_comp_ref(vc_conn);
			IPA_PT.send(ts_ASP_RSL_UD(ConnectionTable[cid].stream_id, rx_rsl_msg));
			}

		[] CCHAN_PT.receive(tr_RSL(?)) -> value rx_rsl {
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl.streamId, rx_rsl.rsl));
			}

		/* explicit registration, e.g. in (non-immediate) assignment case */
		[] RSL_PROC.getcall(RSLEM_register:{?,?,?}) -> param(trx_nr, chan_nr, vc_conn) {
			f_cid_create_cnr(trx_nr, chan_nr, vc_conn);
			RSL_PROC.reply(RSLEM_register:{trx_nr, chan_nr, vc_conn});
			}

		[] RSL_PROC.getcall(RSLEM_unregister:{?,?,?}) -> param(trx_nr, chan_nr, vc_conn) {
			cid := f_cid_by_chan_nr(trx_nr, chan_nr);
			f_cid_clear(cid);
			RSL_PROC.reply(RSLEM_unregister:{trx_nr, chan_nr, vc_conn});
			}

		[] RSL_PROC.getcall(RSLEM_suspend:{true}) {
			log("Suspending DChan");
			dchan_suspended := true;
			RSL_PROC.reply(RSLEM_suspend:{true});
			}

		[] RSL_PROC.getcall(RSLEM_suspend:{false}) {
			log("Resuming DChan");
			dchan_suspended := false;
			RSL_PROC.reply(RSLEM_suspend:{false});
			}

		[] RSL_PROC.getcall(RSLEM_get_last_act:{?,?,?}) -> param(trx_nr, chan_nr) {
			var RSL_Message last_chan_act := f_lookup_last_act(trx_nr, chan_nr);
			RSL_PROC.reply(RSLEM_get_last_act:{trx_nr, chan_nr, last_chan_act});
			}
		}
	}
}

private function f_conn_table_init()
runs on RSL_Emulation_CT {
	var integer i;

	/* Initialize the ConnectionTable */
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		f_cid_clear(i);
	}
}

/* client/conn_hdlr side function to use procedure port to register stream_id/chan_nr */
function f_rslem_register(uint8_t trx_nr, RslChannelNr chan_nr, RSLEM_PROC_PT PT := RSL_PROC)
runs on RSL_DchanHdlr {
	PT.call(RSLEM_register:{trx_nr, chan_nr, self}) {
		[] PT.getreply(RSLEM_register:{?,?,?}) {};
	}
}

/* client/conn_hdlr side function to use procedure port to unregister stream_id/chan_nr */
function f_rslem_unregister(uint8_t trx_nr, RslChannelNr chan_nr, RSLEM_PROC_PT PT := RSL_PROC)
runs on RSL_DchanHdlr {
	PT.call(RSLEM_unregister:{trx_nr, chan_nr, self}) {
		[] PT.getreply(RSLEM_unregister:{?,?,?}) {};
	}
}

/* resume handling of RSL DChan messages from IPA until f_rslem_resume() is called */
function f_rslem_suspend(RSLEM_PROC_PT PT)
runs on RSL_DchanHdlr {
	PT.call(RSLEM_suspend:{true}) {
		[] PT.getreply(RSLEM_suspend:{true}) {};
	}
}

/* resume handling of RSL DChan messages after f_rslem_suspend() is called */
function f_rslem_resume(RSLEM_PROC_PT PT)
runs on RSL_DchanHdlr {
	PT.call(RSLEM_suspend:{false}) {
		[] PT.getreply(RSLEM_suspend:{false}) {};
	}
}

/* obtain the last RSL_CHAN_ACT message for the given chan_nr */
function f_rslem_get_last_act(RSLEM_PROC_PT PT, uint8_t trx_nr, RslChannelNr chan_nr)
runs on RSL_DchanHdlr return RSL_Message {
	var RSL_Message chan_act;
	PT.call(RSLEM_get_last_act:{trx_nr, chan_nr, -}) {
		[] PT.getreply(RSLEM_get_last_act:{trx_nr, chan_nr, ?}) -> param(chan_act) {};
	}
	return chan_act;
}




}
