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.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

import from Misc_Helpers all;
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;
	port RSL_DCHAN_PT RSL2;
	port RSLEM_PROC_PT RSL2_PROC;
};

type record RSLDC_ChanRqd {
	OCT1		ra,
	GsmFrameNumber	fn optional
};

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

template (value) RSLDC_ChanRqd ts_RSLDC_ChanRqd_anyFN(OCT1 ra) := {
	ra := ra,
	fn := omit
}

type enumerated RSLEm_EventType {
	RSLEM_EV_TRX_UP,
	RSLEM_EV_TRX_DOWN
};

type record RSLEm_Event {
	RSLEm_EventType		ev_type,
	IpaStreamId		sid
};

template (value) RSLEm_Event ts_RSLEm_EV(RSLEm_EventType ev_type,
					 IpaStreamId sid) := {
	ev_type := ev_type,
	sid := sid
};
template RSLEm_Event tr_RSLEm_EV(template RSLEm_EventType ev_type,
				 template IpaStreamId sid := ?) := {
	ev_type := ev_type,
	sid := sid
};

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

type port RSL_CCHAN_PT message {
	inout ASP_RSL_Unitdata, RSLEm_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_wait_queue(boolean enable);
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_wait_queue,
	      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");
			mtc.stop;
		}
		[] T.timeout {
			setverdict(fail, "Timeout waiting for RSL on DCHAN");
			mtc.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,
		    template uint3_t tsc := ?)
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));
	/* At this point the BSC sends a CHAN ACTIV which we always ACK. Checking it below. */
	/* 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);
	if (not match(rr.payload.imm_ass.chan_desc.tsc, tsc)) {
		setverdict(fail, "Immediate Assignment: unexpected TSC in Channel Description: expected ", tsc, " got ",
			   rr.payload.imm_ass.chan_desc.tsc);
		mtc.stop;
	}
	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));

	/* Check above CHAN ACTIV */
	var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
	var RSL_IE_Body ie;
	if (f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, ie)) {
		var uint3_t got_tsc := ie.chan_ident.ch_desc.v.tsc;
		if (not match(got_tsc, tsc)) {
			setverdict(fail, "RSL CHANnel ACTIVation: unexpected TSC in Channel Description: expected ",
				   tsc, " got ", got_tsc);
			mtc.stop;
		}
	}
}

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=", 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=", trx_nr, " and chan_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=", ra, " and fn=", fn);
	return -1;
}

/* Matches by only RA if FN is ommited in one of the connections allocated */
private function f_cid_by_ra_fn2(OCT1 ra, RSL_IE_FrameNumber 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) {
			if (not ispresent(ConnectionTable[i].ra_fn) or
			    fn == valueof(ts_RSL_IE_FrameNumber(ConnectionTable[i].ra_fn))) {
					return i;
			}
		}
	}
	log("No Dchan handler for ra=", ra, " and fn=", fn);
	return -1;
}

/* create an ew client with given RA and FN */
private function f_cid_create(OCT1 ra, template (omit) 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;
			if (ispresent(fn)) {
				ConnectionTable[i].ra_fn := valueof(fn);
			} else {
				ConnectionTable[i].ra_fn := omit;
			}
			ConnectionTable[i].comp_ref := comp_ref;
			return;
		}
	}
	testcase.stop("No free entry in conn table for ", ra, fn);
}

/* create a new 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;
		}
	}
	testcase.stop("No free entry in conn table for ", trx_nr, chan_nr, comp_ref);
}


/* delete 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;
		}
	}
	testcase.stop("No space left in LastActTable to store chan_act for ", chan_nr);
}

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;
		}
	}
	testcase.stop("No LastActTable entry found for TRX ", trx_nr, " ", chan_nr);
}

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

private function f_trx_conn_map_init()
runs on RSL_Emulation_CT {
	for (var integer i := 0; i < sizeof(TrxConnMap); i := i + 1) {
		TrxConnMap[i] := -1;
	}
}

private function f_trx_conn_map_register(integer conn_id, in IpaCcmIdResp id_resp)
runs on RSL_Emulation_CT return IpaStreamId {
	var template charstring unit_id_fmt := pattern "(\d+)/(\d+)/(\d+)";
	var charstring unit_id;
	var integer trx_nr;
	var integer idx;

	/* Check if we have room for a new connection */
	if (TrxConnNum >= sizeof(TrxConnMap)) {
		testcase.stop("We cannot handle more than ", sizeof(TrxConnMap), " transceivers");
	}

	/* Find IPAC_IDTAG_UNITID in the IPA IDENTITY RESPONSE */
	idx := f_ipa_id_resp_find_ie(id_resp, IPAC_IDTAG_UNITID);
	if (idx < 0) {
		testcase.stop("IPA IDENTITY RESPONSE contains no unit-id");
	}

	/* Make sure that IPA unit-id is valid */
	unit_id := oct2char(id_resp[idx].data);
	if (not match(unit_id, unit_id_fmt)) {
		testcase.stop("IPA unit-id has unknown/unexpected format");
	}

	/* Parse transceiver number (site/bts/trx).
	 * TODO: implement and use declaratice types. */
	unit_id := regexp(unit_id, unit_id_fmt, 2);
	trx_nr  := str2int(unit_id);

	if (trx_nr >= sizeof(TrxConnMap)) {
		testcase.stop("Transceiver #", trx_nr, " does not fit");
	} else if (TrxConnMap[trx_nr] != -1) {
		testcase.stop("Transceiver #", trx_nr, " is already connected?!?");
	}

	/* Finally, store the connection ID */
	log("Mapped TRX#", trx_nr, " to TCP/IP conn_id=", conn_id);
	TrxConnMap[trx_nr] := conn_id;
	TrxConnNum := TrxConnNum + 1;

	return f_streamId_by_trx(trx_nr);
}

private function f_trx_conn_map_unregister(integer conn_id)
runs on RSL_Emulation_CT return IpaStreamId {

	for (var integer i := 0; i < sizeof(TrxConnMap); i := i + 1) {
		if (conn_id == TrxConnMap[i]) {
			TrxConnMap[i] := -1;
			TrxConnNum := TrxConnNum - 1;
			return f_streamId_by_trx(i);
		}
	}

	testcase.stop("Trying to unregister an unknown conn_id=", conn_id);
}

private function f_trx_conn_map_resolve(IpaStreamId id)
runs on RSL_Emulation_CT return integer {
	var integer trx_nr := f_trx_by_streamId(id);

	if (TrxConnMap[trx_nr] == -1) {
		testcase.stop("Transceiver #", trx_nr, " is not connected");
	}

	return TrxConnMap[trx_nr];
}

private type record of ASP_RSL_Unitdata ASP_RSL_UDList;

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

	/* RSL messages for which no handler is currently registered */
	var ASP_RSL_UDList WaitingQueue := { };

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

	/* IPA stream ID -> TCP/IP connection ID mapping for transceivers */
	var integer TrxConnNum := 0; /* number of connected transceivers */
	var integer TrxConnMap[4]; /* up to 4 transceivers for now */
}


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; }
	}
	setverdict(fail, "Unknown stream ID ", trx_nr);
	mtc.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 conn_id;
	var integer cid;
	var integer i;
	/* special synchronization handling during hand-over */
	var boolean dchan_suspended := false;
	/* Whether to keep RSL messages, for which no handler is found in ConnectionTable,
	 * in a queue. These messages will remain in the queue until the appropriate
	 * connection handler is registered. */
	var boolean wait_queue_enabled := false;

	f_conn_table_init();
	f_trx_conn_map_init();
	f_last_act_table_init();

	while (true) {
		alt {
		[bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) {
			}
		[not bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) -> value evt {
			log("A new IPA/RSL connection has been established (conn_id=",
			    evt.conn_id, "), waiting for IDENTITY RESPONSE...");
			}
		[not bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_RESP)) -> value evt {
			log("Got IDENTITY RESPONSE (conn_id=", evt.conn_id, "): ", evt.id_resp);
			/* Update [ IPA stream ID -> TCP/IP connection ID ] mapping */
			var IpaStreamId sid := f_trx_conn_map_register(evt.conn_id, evt.id_resp);
			/* Notify the upper layers about a new connection */
			CCHAN_PT.send(ts_RSLEm_EV(RSLEM_EV_TRX_UP, sid));
			}
		[bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) -> value evt {
			log("Lost IPA connection! (conn_id=", evt.conn_id, "): ", evt.id_resp);
			/* Notify the upper layers about lost connection */
			var IpaStreamId sid := f_trx_conn_map_unregister(evt.conn_id);
			CCHAN_PT.send(ts_RSLEm_EV(RSLEM_EV_TRX_DOWN, sid));
			}
		[not bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) -> value evt {
			log("Lost IPA connection! (conn_id=", evt.conn_id, ")");
			/* Notify the upper layers about lost connection */
			var IpaStreamId sid := f_trx_conn_map_unregister(evt.conn_id);
			CCHAN_PT.send(ts_RSLEm_EV(RSLEM_EV_TRX_DOWN, sid));
			}
		[bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
			IPA_PT.send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
			}
		[not bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { }
		[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN, sid := ?)) -> value rx_rsl {
			var GsmRrMessage rr;
			var OCT1 ra;
			var GsmFrameNumber fn;
			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");
					mtc.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);
					}
				}
			}
		}
		[not bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_CHAN_RQD(?), sid := ?)) -> value rx_rsl {
			var RSL_IE_RequestRef req_ref;
			req_ref := rx_rsl.rsl.ies[1].body.req_ref;
			cid := f_cid_by_ra_fn2(req_ref.ra, req_ref.frame_nr);
			if (cid != -1) {
				CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[cid].comp_ref;
				f_cid_clear(cid);
			} else {
				CCHAN_PT.send(rx_rsl);
			}
		}

		[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?, ?), sid := ?)) -> value rx_rsl {
			/* broadcast to all clients? */
			for (i := 0; i < sizeof(ConnectionTable); i := i + 1) {
				if (ispresent(ConnectionTable[i].comp_ref) and ConnectionTable[i].comp_ref != null) {
					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_ASP_RSL_UD(tr_RSL_MsgTypeT(?), sid := ?)) -> value rx_rsl {
			CCHAN_PT.send(rx_rsl);
		}

		/* Forward common channel management to the special port for it */
		[] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeC(?), sid := ?)) -> value rx_rsl {
			CCHAN_PT.send(rx_rsl);
		}

		/* blindly acknowledge all channel activations */
		[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> 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(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl.streamId));
		}

		[not dchan_suspended] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeDR(?), sid := ?)) -> 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 if (wait_queue_enabled) {
				log("Storing an RSL message in the waiting queue");
				WaitingQueue := WaitingQueue & { rx_rsl };
			} else {
				setverdict(fail, "RSL for unknown Dchan");
				mtc.stop;
			}
		}

		[not dchan_suspended] IPA_PT.receive {
			setverdict(fail, "Received unknown primitive from IPA");
			mtc.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(ts_RSL_CHAN_RQD(chan_rqd.ra, chan_rqd.fn)));
			}

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

		/* RSL message from a component that runs on RSL_DchanHdlr */
		[bts_role] CLIENT_PT.receive(tr_RSL_MsgType(?)) -> value rx_rsl_msg sender vc_conn {
			cid := f_cid_by_comp_ref(vc_conn);
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl_msg, ConnectionTable[cid].stream_id));
			}
		[bts_role] CLIENT_PT.receive(tr_ASP_RSL_UD(?, sid := ?)) -> value rx_rsl {
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl.rsl, rx_rsl.streamId));
			}
		[not bts_role] CLIENT_PT.receive(tr_RSL_MsgType(?)) -> value rx_rsl_msg sender vc_conn {
			cid := f_cid_by_comp_ref(vc_conn);
			conn_id := f_trx_conn_map_resolve(ConnectionTable[cid].stream_id);
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl_msg, ConnectionTable[cid].stream_id, conn_id));
			}

		/* RSL message from MTC */
		[bts_role] CCHAN_PT.receive(tr_ASP_RSL_UD(?, sid := ?)) -> value rx_rsl {
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl.rsl, rx_rsl.streamId));
			}
		[not bts_role] CCHAN_PT.receive(tr_ASP_RSL_UD(?, sid := ?)) -> value rx_rsl {
			conn_id := f_trx_conn_map_resolve(rx_rsl.streamId);
			IPA_PT.send(ts_ASP_RSL_UD(rx_rsl.rsl, rx_rsl.streamId, conn_id));
			}

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

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

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

		[not wait_queue_enabled] RSL_PROC.getcall(RSLEM_wait_queue:{true}) -> sender vc_conn {
			wait_queue_enabled := true;
			log("Enabled queueing of DChan messages");
			RSL_PROC.reply(RSLEM_wait_queue:{wait_queue_enabled}) to vc_conn;
			}

		[wait_queue_enabled] RSL_PROC.getcall(RSLEM_wait_queue:{false}) -> sender vc_conn {
			/* Dispatch stalled messages (if any) */
			f_WaitingQueue_dispatch();

			wait_queue_enabled := false;
			log("Disabled queueing of DChan messages");
			RSL_PROC.reply(RSLEM_wait_queue:{wait_queue_enabled}) to vc_conn;
			}

		[] RSL_PROC.getcall(RSLEM_wait_queue:{?}) -> sender vc_conn {
			log("Queueing of DChan messages is already enabled/disabled");
			RSL_PROC.reply(RSLEM_wait_queue:{wait_queue_enabled}) to vc_conn;
			}

		[] RSL_PROC.getcall(RSLEM_get_last_act:{?,?,?}) -> param(trx_nr, chan_nr) sender vc_conn {
			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}) to vc_conn;
			}
		}
	}
}

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

private function f_WaitingQueue_dispatch()
runs on RSL_Emulation_CT {
	var integer cid;

	for (var integer i := 0; i < lengthof(WaitingQueue); i := i + 1) {
		cid := f_cid_by_chan_nr(f_trx_by_streamId(WaitingQueue[i].streamId),
					WaitingQueue[i].rsl.ies[0].body.chan_nr);
		if (cid == -1) {
			setverdict(fail, "No Dchan handler found for: ", WaitingQueue[i]);
			mtc.stop;
		}

		/* Dispatch a stalled message to the appropriate handler */
		CLIENT_PT.send(WaitingQueue[i].rsl) to ConnectionTable[cid].comp_ref;
	}

	/* All messages dispatched, clear the queue */
	WaitingQueue := { };
}

/* 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:{?,?,?}) {};
	}
}

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

/* Enable queueing of RSL DChan messages from IPA until f_rslem_dchan_queue_disable() is called. */
function f_rslem_dchan_queue_enable(RSLEM_PROC_PT PT := RSL_PROC)
runs on RSL_DchanHdlr {
	PT.call(RSLEM_wait_queue:{true}) {
		[] PT.getreply(RSLEM_wait_queue:{true}) {};
	}
}

/* Disable queueing of RSL DChan messages after f_rslem_dchan_queue_enable() is called.
 * Dispatch all stalled messages to the registered handlers. Make sure that no
 * messages for which there is no handler are left in the queue (mtc.stop if so). */
function f_rslem_dchan_queue_dispatch(RSLEM_PROC_PT PT := RSL_PROC)
runs on RSL_DchanHdlr {
	PT.call(RSLEM_wait_queue:{false}) {
		[] PT.getreply(RSLEM_wait_queue:{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;
}




}
