diff --git a/library/RAN_Emulation.ttcn b/library/RAN_Emulation.ttcn
new file mode 100644
index 0000000..72e2733
--- /dev/null
+++ b/library/RAN_Emulation.ttcn
@@ -0,0 +1,836 @@
+module RAN_Emulation {
+
+/* RAN Emulation, runs on top of BSSAP_CodecPort.  It multiplexes/demultiplexes
+ * the individual connections, so there can be separate TTCN-3 components handling
+ * each of the connections.
+ *
+ * The RAN_Emulation.main() function processes SCCP primitives from the SCCP
+ * stack via the BSSAP_CodecPort, and dispatches them to the per-connection components.
+ *
+ * Outbound BSSAP/SCCP connections are initiated by sending a BSSAP_Conn_Req primitive
+ * to the component running the RAN_Emulation.main() function.
+ *
+ * For each new inbound connections, the RanOps.create_cb() is called.  It can create
+ * or resolve a TTCN-3 component, and returns a component reference to which that inbound
+ * connection is routed/dispatched.
+ *
+ * If a pre-existing component wants to register to handle a future inbound connection, it can
+ * do so by registering an "expect" with the expected Layer 3 (DTAP) payload.  This is e.g. useful
+ * if you are simulating BTS + MSC, and first trigger a connection from BTS/RSL side in a
+ * component which then subsequently should also handle the MSC emulation.
+ *
+ * Inbound Unit Data messages (such as are dispatched to the RanOps.unitdata_cb() callback,
+ * which is registered with an argument to the main() function below.
+ *
+ * (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 SCCP_Emulation all;
+import from SCCPasp_Types all;
+import from BSSAP_Types all;
+import from BSSAP_CodecPort all;
+import from BSSMAP_Templates all;
+import from MGCP_Types all;
+import from MGCP_Templates all;
+import from IPA_Emulation all;
+import from MobileL3_Types all;
+
+/* General "base class" component definition, of which specific implementations
+ * derive themselves by means of the "extends" feature */
+type component RAN_ConnHdlr {
+	/* port towards MSC Emulator core / SCCP connection dispatchar */
+	port RAN_Conn_PT BSSAP;
+	/* procedure based port to register for incoming connections */
+	port RAN_PROC_PT BSSAP_PROC;
+}
+
+/* Auxiliary primitive that can happen on the port between per-connection client and this dispatcher */
+type enumerated RAN_Conn_Prim {
+	/* SCCP tell us that connection was released */
+	MSC_CONN_PRIM_DISC_IND,
+	/* we tell SCCP to release connection */
+	MSC_CONN_PRIM_DISC_REQ,
+	/* Connection confirmed indication */
+	MSC_CONN_PRIM_CONF_IND
+}
+
+type record BSSAP_Conn_Req {
+	SCCP_PAR_Address	addr_peer,
+	SCCP_PAR_Address	addr_own,
+	PDU_BSSAP		bssap
+}
+
+/* similar to PDU_BSSAP with DTAP, but DTAP is already decoded! */
+type record PDU_DTAP_MO {
+	OCT1			dlci optional,
+	boolean			skip_seq_patching optional,
+	PDU_ML3_MS_NW		dtap
+}
+
+/* similar to PDU_BSSAP with DTAP, but DTAP is already decoded! */
+type record PDU_DTAP_MT {
+	OCT1			dlci optional,
+	PDU_ML3_NW_MS		dtap
+}
+
+template PDU_DTAP_MT ts_PDU_DTAP_MT(template PDU_ML3_NW_MS dtap, template OCT1 dlci := omit) := {
+	dlci := dlci,
+	dtap := dtap
+}
+
+template PDU_DTAP_MO ts_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 dlci := '00'O, boolean skip_seq_patching := false) := {
+	dlci := dlci,
+	skip_seq_patching := skip_seq_patching,
+	dtap := dtap
+}
+
+template PDU_DTAP_MT tr_PDU_DTAP_MT(template PDU_ML3_NW_MS dtap, template OCT1 dlci := *) := {
+	dlci := dlci,
+	dtap := dtap
+}
+
+template PDU_DTAP_MO tr_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 dlci := *) := {
+	dlci := dlci,
+	skip_seq_patching := ?,
+	dtap := dtap
+}
+
+template BSSAP_Conn_Req ts_BSSAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, PDU_BSSAP bssap) := {
+	addr_peer := peer,
+	addr_own := own,
+	bssap := bssap
+};
+
+
+/* port between individual per-connection components and this dispatcher */
+type port RAN_Conn_PT message {
+		/* BSSAP or direct DTAP messages from/to clients */
+	inout	PDU_BSSAP, PDU_DTAP_MO, PDU_DTAP_MT,
+		/* misc indications / requests between SCCP and client */
+		RAN_Conn_Prim,
+		/* Client requests us to create SCCP Connection */
+		BSSAP_Conn_Req,
+		/* MGCP, only used for IPA SCCPlite (MGCP in IPA mux) */
+		MgcpCommand, MgcpResponse;
+} with { extension "internal" };
+
+
+/* represents a single BSSAP connection over SCCP */
+type record ConnectionData {
+	/* reference to the instance of the per-connection component */
+	RAN_ConnHdlr	comp_ref,
+	integer		sccp_conn_id,
+	/* most recent MGCP transaction ID (Used on MSC side) */
+	MgcpTransId	mgcp_trans_id optional,
+	/* CIC that has been used for voice of this channel (BSC side) */
+	integer		cic optional,
+	/* array of N(SD) values for MO DTAP messages, indexed by discriminator */
+	uint2_t		n_sd[4]
+}
+
+type record ImsiMapping {
+	RAN_ConnHdlr	comp_ref,
+	hexstring	imsi optional,
+	OCT4		tmsi
+}
+
+type component RAN_Emulation_CT {
+	/* SCCP port on the bottom side, using ASP primitives */
+	port BSSAP_CODEC_PT BSSAP;
+	/* BSSAP port to the per-connection clients */
+	port RAN_Conn_PT CLIENT;
+	/* MGCP port */
+	port IPA_MGCP_PT MGCP;
+
+	/* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */
+	var ConnectionData ConnectionTable[16];
+
+	/* pending expected incoming connections */
+	var ExpectData ExpectTable[8];
+
+	/* tables for mapping inbound unitdata (like paging) */
+	var ImsiMapping ImsiTable[16];
+
+	/* procedure based port to register for incoming connections */
+	port RAN_PROC_PT PROC;
+
+	var charstring g_ran_id;
+	var integer g_next_e1_ts := 1;
+	var RanOps g_ran_ops;
+};
+
+private function f_conn_id_known(integer sccp_conn_id)
+runs on RAN_Emulation_CT return boolean {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].sccp_conn_id == sccp_conn_id){
+			return true;
+		}
+	}
+	return false;
+}
+
+private function f_comp_known(RAN_ConnHdlr client)
+runs on RAN_Emulation_CT return boolean {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].comp_ref == client) {
+			return true;
+		}
+	}
+	return false;
+}
+
+private function f_cic_known(integer cic)
+runs on RAN_Emulation_CT return boolean {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].cic == cic) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/* resolve component reference by connection ID */
+private function f_comp_by_conn_id(integer sccp_conn_id)
+runs on RAN_Emulation_CT return RAN_ConnHdlr {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {
+			return ConnectionTable[i].comp_ref;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by SCCP Connection ID ", sccp_conn_id);
+	mtc.stop;
+}
+
+/* resolve component reference by CIC */
+private function f_comp_by_mgcp_tid(MgcpTransId tid)
+runs on RAN_Emulation_CT return RAN_ConnHdlr {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].mgcp_trans_id == tid) {
+			return ConnectionTable[i].comp_ref;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by MGCP Transaction ID ", tid);
+	mtc.stop;
+}
+
+private function f_comp_store_mgcp_tid(RAN_ConnHdlr client, MgcpTransId tid)
+runs on RAN_Emulation_CT {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].comp_ref == client) {
+			ConnectionTable[i].mgcp_trans_id := tid;
+			return;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by component ", client);
+	mtc.stop;
+}
+
+private function f_comp_by_cic(integer cic)
+runs on RAN_Emulation_CT return RAN_ConnHdlr {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].cic == cic) {
+			return ConnectionTable[i].comp_ref;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by CIC ", cic);
+	mtc.stop;
+}
+
+private function f_comp_store_cic(RAN_ConnHdlr client, integer cic)
+runs on RAN_Emulation_CT {
+	var integer i;
+	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].comp_ref == client) {
+			ConnectionTable[i].cic := cic;
+			return;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by component ", client);
+	mtc.stop;
+}
+
+/* resolve connection ID by component reference */
+private function f_conn_id_by_comp(RAN_ConnHdlr client)
+runs on RAN_Emulation_CT return integer {
+	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].comp_ref == client) {
+			return ConnectionTable[i].sccp_conn_id;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by component ", client);
+	mtc.stop;
+}
+
+/* resolve ConnectionTable index component reference */
+private function f_idx_by_comp(RAN_ConnHdlr client)
+runs on RAN_Emulation_CT return integer {
+	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].comp_ref == client) {
+			return i;
+		}
+	}
+	setverdict(fail, "RAN Connection table not found by component ", client);
+	mtc.stop;
+}
+
+private function f_gen_conn_id()
+runs on RAN_Emulation_CT return integer {
+	var integer conn_id;
+
+	do {
+		conn_id := float2int(rnd()*SCCP_Emulation.tsp_max_ConnectionId);
+	} while (f_conn_id_known(conn_id) == true);
+
+	return conn_id;
+}
+
+private function f_conn_table_init()
+runs on RAN_Emulation_CT {
+	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		ConnectionTable[i].comp_ref := null;
+		ConnectionTable[i].sccp_conn_id := -1;
+		ConnectionTable[i].mgcp_trans_id := omit;
+		ConnectionTable[i].cic := omit;
+		ConnectionTable[i].n_sd := { 0, 0, 0, 0 };
+	}
+	for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {
+		ImsiTable[i].comp_ref := null;
+		ImsiTable[i].imsi := omit;
+		ImsiTable[i].tmsi := 'FFFFFFFF'O;
+	}
+}
+
+private function f_conn_table_add(RAN_ConnHdlr comp_ref, integer sccp_conn_id)
+runs on RAN_Emulation_CT {
+	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].sccp_conn_id == -1) {
+			ConnectionTable[i].comp_ref := comp_ref;
+			ConnectionTable[i].sccp_conn_id := sccp_conn_id;
+			ConnectionTable[i].n_sd := { 0, 0, 0, 0 };
+			log("Added conn table entry ", i, comp_ref, sccp_conn_id);
+			return;
+		}
+	}
+	testcase.stop("RAN Connection table full!");
+}
+
+private function f_conn_table_del(integer sccp_conn_id)
+runs on RAN_Emulation_CT {
+	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
+		if (ConnectionTable[i].sccp_conn_id == sccp_conn_id) {
+			log("Deleted conn table entry ", i,
+			    ConnectionTable[i].comp_ref, sccp_conn_id);
+			ConnectionTable[i].sccp_conn_id := -1;
+			ConnectionTable[i].comp_ref := null;
+			return
+		}
+	}
+	setverdict(fail, "RAN Connection table attempt to delete non-existant ", sccp_conn_id);
+	mtc.stop;
+}
+
+private function f_imsi_table_find(hexstring imsi, template OCT4 tmsi)
+runs on RAN_Emulation_CT return RAN_ConnHdlr {
+	for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {
+		if (ImsiTable[i].imsi == imsi or
+		    isvalue(tmsi) and match(ImsiTable[i].tmsi, tmsi)) {
+			return ImsiTable[i].comp_ref;
+		}
+	}
+	return null;
+}
+
+/* handle (optional) userData portion of various primitives and dispatch it to the client */
+private function f_handle_userData(RAN_ConnHdlr client, PDU_BSSAP bssap)
+runs on RAN_Emulation_CT {
+	/* decode + send decoded BSSAP to client */
+
+	if (ischosen(bssap.pdu.bssmap)) {
+		/* BSC Side: If this is an assignment command, store CIC */
+		if (ischosen(bssap.pdu.bssmap.assignmentRequest) and
+		    ispresent(bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode)) {
+			var BSSMAP_IE_CircuitIdentityCode cic_ie :=
+				bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode;
+			var integer cic := (oct2int(cic_ie.cicHigh) * 256) + oct2int(cic_ie.cicLow);
+			f_comp_store_cic(client, cic);
+		}
+	}
+
+	if (ischosen(bssap.pdu.dtap) and g_ran_ops.decode_dtap) {
+		if (g_ran_ops.role_ms) {
+			/* we are the MS, so any message to us must be MT */
+			var PDU_DTAP_MT mt := {
+				dlci := bssap.dlci,
+				dtap := dec_PDU_ML3_NW_MS(bssap.pdu.dtap)
+			};
+			CLIENT.send(mt) to client;
+		} else {
+			/* we are the Network, so any message to us must be MO */
+			var PDU_DTAP_MO mo := {
+				dlci := bssap.dlci,
+				dtap := dec_PDU_ML3_MS_NW(bssap.pdu.dtap)
+			};
+			CLIENT.send(mo) to client;
+		}
+	} else {
+		CLIENT.send(bssap) to client;
+	}
+}
+
+/* call-back type, to be provided by specific implementation; called when new SCCP connection
+ * arrives */
+type function BssmapCreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)
+runs on RAN_Emulation_CT return RAN_ConnHdlr;
+
+type function BssmapUnitdataCallback(PDU_BSSAP bssap)
+runs on RAN_Emulation_CT return template PDU_BSSAP;
+
+/* handle common Unitdata such as Paging */
+private function CommonBssmapUnitdataCallback(PDU_BSSAP bssap)
+runs on RAN_Emulation_CT return template PDU_BSSAP {
+	if (match(bssap, tr_BSSMAP_Paging)) {
+		var RAN_ConnHdlr client := null;
+		client := f_imsi_table_find(bssap.pdu.bssmap.paging.iMSI.digits,
+					   bssap.pdu.bssmap.paging.tMSI.tmsiOctets);
+		if (client != null) {
+			log("CommonBssmapUnitdataCallback: IMSI/TMSI found in table, dispatching to ",
+				client);
+			CLIENT.send(bssap) to client;
+			return omit;
+		}
+		log("CommonBssmapUnitdataCallback: IMSI/TMSI not found in table");
+	} else {
+		log("CommonBssmapUnitdataCallback: Not a paging message");
+	}
+	/* ELSE: handle in user callback */
+	return g_ran_ops.unitdata_cb.apply(bssap);
+}
+
+type record RanOps {
+	BssmapCreateCallback create_cb,
+	BssmapUnitdataCallback unitdata_cb,
+	boolean decode_dtap,
+	boolean role_ms,
+	/* needed for performing BSSMAP RESET */
+	SCCP_PAR_Address sccp_addr_local optional,
+	SCCP_PAR_Address sccp_addr_peer optional
+}
+
+template BIT4 t_ML3_DISC_CC_MM_SS := ('0011'B, '0101'B, '1011'B);
+
+/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */
+function f_ML3_patch_seq(inout ConnectionData cd, in PDU_ML3_MS_NW dtap, inout octetstring enc_l3) {
+	var uint2_t seq_nr;
+	if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) {
+		seq_nr := cd.n_sd[0];
+		cd.n_sd[0] := (cd.n_sd[0] + 1) mod 4;
+	} else if (ischosen(dtap.msgs.gcc)) {
+		seq_nr := cd.n_sd[1];
+		cd.n_sd[1] := (cd.n_sd[1] + 1) mod 2;
+	} else if (ischosen(dtap.msgs.bcc)) {
+		seq_nr := cd.n_sd[2];
+		cd.n_sd[2] := (cd.n_sd[2] + 1) mod 2;
+	} else if (ischosen(dtap.msgs.loc)) {
+		seq_nr := cd.n_sd[3];
+		cd.n_sd[3] := (cd.n_sd[3] + 1) mod 2;
+	} else {
+		/* no sequence number to patch */
+		return;
+	}
+	log("patching N(SD)=", seq_nr, " into dtap ", enc_l3);
+	enc_l3[1] := (enc_l3[1] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
+	log("patched enc_l3: ", enc_l3);
+}
+
+private function f_bssap_l3_is_rr(PDU_BSSAP bssap) return boolean {
+	var template octetstring l3 := f_bssap_extract_l3(bssap);
+	if (not isvalue(l3)) {
+		return false;
+	}
+	var octetstring l3v := valueof(l3);
+	if (lengthof(l3v) < 1) {
+		return false;
+	}
+	/* lower 4 bits of first octet are protocol discriminator */
+	if ((oct2bit(l3v[0]) and4b '00001111'B) == '00000110'B) {
+		return true;
+	}
+	return false;
+}
+
+private altstep as_reset_ack() runs on RAN_Emulation_CT {
+	var BSSAP_N_UNITDATA_ind ud_ind;
+	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
+		log("Respoding to inbound RESET with RESET-ACK");
+		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
+			   ts_BSSMAP_ResetAck));
+		repeat;
+	}
+}
+
+
+private function f_bssap_wait_for_reset() runs on RAN_Emulation_CT {
+	var BSSAP_N_UNITDATA_ind ud_ind;
+	timer T := 20.0;
+
+	T.start;
+	alt {
+	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
+		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
+			   ts_BSSMAP_ResetAck));
+		}
+	[] as_reset_ack();
+	[] BSSAP.receive {
+		repeat;
+		}
+	[] T.timeout {
+		setverdict(fail, "Timeout waiting for BSSAP RESET");
+		mtc.stop;
+		}
+	}
+}
+
+function f_bssap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on RAN_Emulation_CT {
+	timer T := 5.0;
+
+	BSSAP.send(ts_BSSAP_UNITDATA_req(peer, own, ts_BSSMAP_Reset(0)));
+	T.start;
+	alt {
+	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(own, peer, tr_BSSMAP_ResetAck)) {
+		log("Received RESET-ACK in response to RESET, we're ready to go!");
+		}
+	[] as_reset_ack();
+	[] BSSAP.receive { repeat };
+	[] T.timeout {
+		setverdict(fail, "Timeout waiting for RESET-ACK after sending RESET");
+		mtc.stop;
+		}
+	}
+}
+
+function main(RanOps ops, charstring id) runs on RAN_Emulation_CT {
+
+	g_ran_id := id;
+	g_ran_ops := ops;
+	f_conn_table_init();
+	f_expect_table_init();
+
+	if (isvalue(ops.sccp_addr_peer) and isvalue(ops.sccp_addr_local)) {
+		f_sleep(1.0);	/* HACK to wait for M3UA/ASP to be ACTIVE */
+		f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local);
+	}
+
+	while (true) {
+		var BSSAP_N_UNITDATA_ind ud_ind;
+		var BSSAP_N_CONNECT_ind conn_ind;
+		var BSSAP_N_CONNECT_cfm conn_cfm;
+		var BSSAP_N_DATA_ind data_ind;
+		var BSSAP_N_DISCONNECT_ind disc_ind;
+		var BSSAP_Conn_Req creq;
+		var RAN_ConnHdlr vc_conn;
+		var PDU_BSSAP bssap;
+		var PDU_DTAP_MO dtap_mo;
+		var PDU_DTAP_MT dtap_mt;
+		var MgcpCommand mgcp_req;
+		var MgcpResponse mgcp_resp;
+		var RAN_ConnHdlr vc_hdlr;
+		var octetstring l3_info;
+		var hexstring imsi;
+		var OCT4 tmsi;
+
+		alt {
+		/* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */
+		[] BSSAP.receive(BSSAP_N_UNITDATA_ind:?) -> value ud_ind {
+			/* Connectionless Procedures like RESET */
+			var template PDU_BSSAP resp;
+			resp := CommonBssmapUnitdataCallback(ud_ind.userData);
+			if (isvalue(resp)) {
+				BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress,
+								ud_ind.calledAddress, resp));
+			}
+			}
+
+		/* SCCP -> Client: new connection from BSC */
+		[] BSSAP.receive(BSSAP_N_CONNECT_ind:?) -> value conn_ind {
+			vc_conn := ops.create_cb.apply(conn_ind, id);
+			/* store mapping between client components and SCCP connectionId */
+			f_conn_table_add(vc_conn, conn_ind.connectionId);
+			/* handle user payload */
+			f_handle_userData(vc_conn, conn_ind.userData);
+			/* confirm connection establishment */
+			BSSAP.send(ts_BSSAP_CONNECT_res(conn_ind.connectionId, omit));
+			}
+
+		/* SCCP -> Client: connection-oriented data in existing connection */
+		[] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value data_ind {
+			vc_conn := f_comp_by_conn_id(data_ind.connectionId);
+			if (ispresent(data_ind.userData)) {
+				f_handle_userData(vc_conn, data_ind.userData);
+			}
+			}
+
+		/* SCCP -> Client: disconnect of an existing connection */
+		[] BSSAP.receive(BSSAP_N_DISCONNECT_ind:?) -> value disc_ind {
+			vc_conn := f_comp_by_conn_id(disc_ind.connectionId);
+			if (ispresent(disc_ind.userData)) {
+				f_handle_userData(vc_conn, disc_ind.userData);
+			}
+			/* notify client about termination */
+			var RAN_Conn_Prim prim := MSC_CONN_PRIM_DISC_IND;
+			CLIENT.send(prim) to vc_conn;
+			f_conn_table_del(disc_ind.connectionId);
+			/* TOOD: return confirm to other side? */
+			}
+
+		/* SCCP -> Client: connection confirm for outbound connection */
+		[] BSSAP.receive(BSSAP_N_CONNECT_cfm:?) -> value conn_cfm {
+			vc_conn := f_comp_by_conn_id(conn_cfm.connectionId);
+			var RAN_Conn_Prim prim := MSC_CONN_PRIM_CONF_IND;
+			CLIENT.send(prim) to vc_conn;
+			/* handle user payload */
+			if (ispresent(conn_cfm.userData)) {
+				f_handle_userData(vc_conn, conn_cfm.userData);
+			}
+			}
+
+		/* Disconnect request client -> SCCP */
+		[] CLIENT.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn {
+			var integer conn_id := f_conn_id_by_comp(vc_conn);
+			BSSAP.send(ts_BSSAP_DISC_req(conn_id, 0));
+			f_conn_table_del(conn_id);
+			}
+
+		/* BSSAP from client -> SCCP */
+		[] CLIENT.receive(BSSAP_Conn_Req:?) -> value creq sender vc_conn {
+			var integer conn_id;
+			/* send to dispatcher */
+
+			if (f_comp_known(vc_conn) == false) {
+				/* unknown client, create new connection */
+				conn_id := f_gen_conn_id();
+
+				/* store mapping between client components and SCCP connectionId */
+				f_conn_table_add(vc_conn, conn_id);
+
+				BSSAP.send(ts_BSSAP_CONNECT_req(creq.addr_peer, creq.addr_own, conn_id,
+								creq.bssap));
+			} else {
+				/* known client, send via existing connection */
+				conn_id := f_conn_id_by_comp(vc_conn);
+				BSSAP.send(ts_BSSAP_DATA_req(conn_id, creq.bssap));
+			}
+
+			/* InitialL3 contains RR (PAG RESP) or MM (CM SRV REQ), we must increment
+			 * counter only on MM/CC/SS, but not on RR */
+			if (g_ran_ops.role_ms and not f_bssap_l3_is_rr(creq.bssap)) {
+				/* we have just sent the first MM message, increment the counter */
+				var integer idx := f_idx_by_comp(vc_conn);
+				ConnectionTable[idx].n_sd[0] := 1;
+				log("patch: N(SD) for ConnIdx ", idx, " set to 1");
+			}
+
+			}
+
+		[] CLIENT.receive(PDU_BSSAP:?) -> value bssap sender vc_conn {
+			var integer conn_id := f_conn_id_by_comp(vc_conn);
+			/* send it to dispatcher */
+			BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap));
+			}
+
+		[g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MO:?) -> value dtap_mo sender vc_conn {
+			var integer idx := f_idx_by_comp(vc_conn);
+			/* convert from decoded DTAP to encoded DTAP */
+			var octetstring l3_enc := enc_PDU_ML3_MS_NW(dtap_mo.dtap);
+			/* patch correct L3 send sequence number N(SD) into l3_enc */
+			if (dtap_mo.skip_seq_patching == false) {
+				f_ML3_patch_seq(ConnectionTable[idx], dtap_mo.dtap, l3_enc);
+			}
+			bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci));
+			BSSAP.send(ts_BSSAP_DATA_req(ConnectionTable[idx].sccp_conn_id, bssap));
+			}
+
+		[not g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt sender vc_conn {
+			var integer conn_id := f_conn_id_by_comp(vc_conn);
+			/* convert from decoded DTAP to encoded DTAP */
+			var octetstring l3_enc := enc_PDU_ML3_NW_MS(dtap_mt.dtap);
+			bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci));
+			BSSAP.send(ts_BSSAP_DATA_req(conn_id, bssap));
+			}
+
+
+		/* Handling of MGCP in IPA SCCPLite case.  This predates 3GPP AoIP
+		 * and uses a MGCP session in parallel to BSSAP.  BSSAP uses CIC
+		 * as usual, and MGCP uses "CIC@mgw" endpoint naming, where CIC
+		 * is printed as hex string, e.g. a@mgw for CIC 10 */
+
+		/* CLIENT -> MGCP */
+		[] CLIENT.receive(MgcpCommand:?) -> value mgcp_req sender vc_conn {
+			/* MGCP request from Handler (we're MSC) */
+			/* store the transaction ID we've seen */
+			f_comp_store_mgcp_tid(vc_conn, mgcp_req.line.trans_id);
+			/* simply forward any MGCP from the client to the port */
+			MGCP.send(mgcp_req);
+			}
+		[] CLIENT.receive(MgcpResponse:?) -> value mgcp_resp sender vc_conn {
+			/* MGCP response from Handler (we're BSC/MGW) */
+			/* simply forward any MGCP from the client to the port */
+			MGCP.send(mgcp_resp);
+			}
+
+		/* MGCP -> CLIENT */
+		[] MGCP.receive(MgcpCommand:?) -> value mgcp_req {
+			/* MGCP request from network side (we're BSC/MGW) */
+			/* Extract CIC from local part of endpoint name */
+			var integer cic := f_mgcp_ep_extract_cic(mgcp_req.line.ep);
+			if (match(mgcp_req, tr_RSIP) and f_cic_known(cic) == false) {
+				/* ignore RSIP for unknown CIC */
+			} else {
+				/* Resolve the vc_conn by the CIC */
+				vc_conn := f_comp_by_cic(cic);
+				CLIENT.send(mgcp_req) to vc_conn;
+			}
+			}
+		[] MGCP.receive(MgcpResponse:?) -> value mgcp_resp {
+			/* MGCP response from network side (we're MSC) */
+			/* Resolve the vc_conn by the transaction ID */
+			vc_conn := f_comp_by_mgcp_tid(mgcp_resp.line.trans_id);
+			CLIENT.send(mgcp_resp) to vc_conn;
+			}
+
+
+		[] PROC.getcall(RAN_register:{?,?}) -> param(l3_info, vc_hdlr) {
+			f_create_expect(l3_info, vc_hdlr);
+			PROC.reply(RAN_register:{l3_info, vc_hdlr}) to vc_hdlr;
+			}
+
+		[] PROC.getcall(RAN_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) {
+			f_create_imsi(imsi, tmsi, vc_hdlr);
+			PROC.reply(RAN_register_imsi:{imsi, tmsi, vc_hdlr}) to vc_hdlr;
+			}
+
+
+		}
+	}
+}
+
+private function f_mgcp_ep_extract_cic(charstring inp) return integer {
+	var charstring local_part := regexp(inp, "(*)@*", 0);
+	return hex2int(str2hex(local_part));
+
+}
+
+/***********************************************************************
+ * "Expect" Handling (mapping for expected incoming SCCP connections)
+ ***********************************************************************/
+
+/* data about an expected future incoming connection */
+type record ExpectData {
+	/* L3 payload based on which we can match it */
+	octetstring l3_payload optional,
+	/* component reference for this connection */
+	RAN_ConnHdlr vc_conn
+}
+
+/* procedure based port to register for incoming connections */
+signature RAN_register(in octetstring l3, in RAN_ConnHdlr hdlr);
+
+/* procedure based port to register for incoming IMSI/TMSI */
+signature RAN_register_imsi(in hexstring imsi, in OCT4 tmsi, in RAN_ConnHdlr hdlr);
+
+type port RAN_PROC_PT procedure {
+	inout RAN_register, RAN_register_imsi;
+} with { extension "internal" };
+
+/* CreateCallback that can be used as create_cb and will use the expectation table */
+function ExpectedCreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)
+runs on RAN_Emulation_CT return RAN_ConnHdlr {
+	var RAN_ConnHdlr ret := null;
+	var octetstring l3_info;
+	var integer i;
+
+	if (not ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {
+		setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3");
+		mtc.stop;
+		return ret;
+	}
+	l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;
+
+	for (i := 0; i < sizeof(ExpectTable); i:= i+1) {
+		if (not ispresent(ExpectTable[i].l3_payload)) {
+			continue;
+		}
+		if (l3_info == ExpectTable[i].l3_payload) {
+			ret := ExpectTable[i].vc_conn;
+			/* release this entry to be used again */
+			ExpectTable[i].l3_payload := omit;
+			ExpectTable[i].vc_conn := null;
+			log("Found Expect[", i, "] for ", l3_info, " handled at ", ret);
+			/* return the component reference */
+			return ret;
+		}
+	}
+	setverdict(fail, "Couldn't find Expect for incoming connection ", conn_ind);
+	mtc.stop;
+	return ret;
+}
+
+private function f_create_expect(octetstring l3, RAN_ConnHdlr hdlr)
+runs on RAN_Emulation_CT {
+	var integer i;
+	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
+		if (not ispresent(ExpectTable[i].l3_payload)) {
+			ExpectTable[i].l3_payload := l3;
+			ExpectTable[i].vc_conn := hdlr;
+			log("Created Expect[", i, "] for ", l3, " to be handled at ", hdlr);
+			return;
+		}
+	}
+	testcase.stop("No space left in ExpectTable");
+}
+
+private function f_create_imsi(hexstring imsi, OCT4 tmsi, RAN_ConnHdlr hdlr)
+runs on RAN_Emulation_CT {
+	for (var integer i := 0; i < sizeof(ImsiTable); i := i+1) {
+		if (not ispresent(ImsiTable[i].imsi)) {
+			ImsiTable[i].imsi := imsi;
+			ImsiTable[i].tmsi := tmsi;
+			ImsiTable[i].comp_ref := hdlr;
+			log("Created IMSI[", i, "] for ", imsi, tmsi, " to be handled at ", hdlr);
+			return;
+		}
+	}
+	testcase.stop("No space left in ImsiTable");
+}
+
+
+private function f_expect_table_init()
+runs on RAN_Emulation_CT {
+	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
+		ExpectTable[i].l3_payload := omit;
+	}
+}
+
+/* helper function for clients to register their IMSI/TMSI */
+function f_ran_register_imsi(hexstring imsi, OCT4 tmsi)
+runs on RAN_ConnHdlr {
+	BSSAP_PROC.call(RAN_register_imsi:{imsi, tmsi, self}) {
+		[] BSSAP_PROC.getreply(RAN_register_imsi:{?,?,?}) {};
+	}
+}
+
+
+}
