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.
 *
 * (C) 2017 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" };

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

type port RSLEM_PROC_PT procedure {
	inout RSLEM_register, RSLEM_unregister, RSLEM_suspend;
} 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 return integer {
	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 i;
		}
	}
	log("No free entry in conn table for ", ra, fn);
	return -1;
}

/* 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 return integer {
	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 i;
		}
	}
	log("No free entry in conn table for ", trx_nr, chan_nr, comp_ref);
	return -1;
}


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

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;

	/* state of all concurrent connections / dedicated channels */
	var ConnectionData ConnectionTable[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() runs on RSL_Emulation_CT {
	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();

	while (true) {
		alt {
		[] IPA_PT.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) {
			}
		[] 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)));
			}
		[] 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);
					}
				}
			}
		}

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

		[] IPA_PT.receive(tr_RSL(tr_RSL_MsgTypeT(?))) -> value rx_rsl {
			log("Ingnoring TRX Mgmt ", rx_rsl.rsl);
		}

		[] IPA_PT.receive(tr_RSL(tr_RSL_MsgTypeC(?))) -> value rx_rsl {
			log("Ignoring Common Channel Mgmt ", rx_rsl.rsl);
		}

		/* blindly acknowledge all channel activations */
		[] 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;
			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;
		}

		[] 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));
			}

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

		}
	}
}

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



}
