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

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

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




}
