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;


modulepar {
	/* Work around switch for ttcn3-bts-test-latest, enables patching of IPA
	 * stream ID in the "BSC" mode. See I5927f59a49724170a63e87be604973f7c9d5d8be. */
	boolean mp_rslem_patch_ipa_cid := false;
};

/* 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;
} 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_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");
			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)
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=", 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_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];
}

/* Work around for a bug in osmo-bts when all transceivers use IPAC_PROTO_RSL_TRX0 */
private function f_trx_conn_map_patch_ud(inout ASP_RSL_Unitdata ud)
runs on RSL_Emulation_CT {
	for (var integer i := 0; i < sizeof(TrxConnMap); i := i + 1) {
		if (ud.conn_id == TrxConnMap[i]) {
			ud.streamId := f_streamId_by_trx(i);
			return; /* We're done */
		}
	}

	testcase.stop("Failed to patch IPA stream ID in ASP RSL UD: ", ud);
}

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

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

	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)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Lost IPA connection!");

			}
		[not bts_role] IPA_PT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Lost IPA connection!");
			}
		[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)) {
					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 {
			if (not bts_role and mp_rslem_patch_ipa_cid) {
				f_trx_conn_map_patch_ud(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 {
			if (not bts_role and mp_rslem_patch_ipa_cid) {
				f_trx_conn_map_patch_ud(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 {
				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));
			}
		[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;
			}

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

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




}
