diff --git a/library/SGsAP_Emulation.ttcn b/library/SGsAP_Emulation.ttcn
new file mode 100644
index 0000000..0c37840
--- /dev/null
+++ b/library/SGsAP_Emulation.ttcn
@@ -0,0 +1,418 @@
+module SGsAP_Emulation {
+
+/* SGsAP Emulation, runs on top of SGsAP_CodecPort.  It multiplexes/demultiplexes
+ * the individual IMSIs/subscribers, so there can be separate TTCN-3 components handling
+ * each of them.
+ *
+ * The SGsAP_Emulation.main() function processes SGsAP primitives from the SGsAP
+ * socket via the SGsAP_CodecPort, and dispatches them to the per-IMSI components.
+ *
+ * For each new IMSI, the SgsapOps.create_cb() is called.  It can create
+ * or resolve a TTCN-3 component, and returns a component reference to which that IMSI
+ * is routed/dispatched.
+ *
+ * If a pre-existing component wants to register to handle a future inbound IMSI, it can
+ * do so by registering an "expect" with the expected IMSI.
+ *
+ * Inbound SGsAP messages without IMSI (such as RESET-IND/ACK) are dispatched to
+ * the SgsapOps.unitdata_cb() callback, which is registered with an argument to the
+ * main() function below.
+ *
+ * (C) 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 SGsAP_CodecPort all;
+import from SGsAP_CodecPort_CtrlFunct all;
+import from SGsAP_Types all;
+import from SGsAP_Templates all;
+import from Osmocom_Types all;
+import from IPL4asp_Types all;
+
+type component SGsAP_ConnHdlr {
+	port SGsAP_Conn_PT SGsAP;
+	/* procedure based port to register for incoming connections */
+	port SGsAPEM_PROC_PT SGsAP_PROC;
+}
+
+/* port between individual per-connection components and this dispatcher */
+type port SGsAP_Conn_PT message {
+	inout PDU_SGsAP;
+} with { extension "internal" };
+
+/* represents a single SGsAP Association */
+type record AssociationData {
+	SGsAP_ConnHdlr	comp_ref,
+	hexstring	imsi optional
+};
+
+type component SGsAP_Emulation_CT {
+	/* Port facing to the UDP SUT */
+	port SGsAP_CODEC_PT SGsAP;
+	/* All SGsAP_ConnHdlr SGsAP ports connect here
+	 * SGsAP_Emulation_CT.main needs to figure out what messages
+	 * to send where with CLIENT.send() to vc_conn */
+	port SGsAP_Conn_PT SGsAP_CLIENT;
+	/* currently tracked connections */
+	var AssociationData SgsapAssociationTable[16];
+	/* pending expected CRCX */
+	var ExpectData SgsapExpectTable[8];
+	/* procedure based port to register for incoming connections */
+	port SGsAPEM_PROC_PT SGsAP_PROC;
+
+	var charstring g_sgsap_id;
+	var integer g_sgsap_conn_id := -1;
+}
+
+type function SGsAPCreateCallback(PDU_SGsAP msg, hexstring imsi, charstring id)
+runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr;
+
+type function SGsAPUnitdataCallback(PDU_SGsAP msg)
+runs on SGsAP_Emulation_CT return template PDU_SGsAP;
+
+type record SGsAPOps {
+	SGsAPCreateCallback create_cb,
+	SGsAPUnitdataCallback unitdata_cb
+}
+
+type record SGsAP_conn_parameters {
+	HostName remote_ip,
+	PortNumber remote_sctp_port,
+	HostName local_ip,
+	PortNumber local_sctp_port
+}
+
+function tr_SGsAP_RecvFrom_R(template PDU_SGsAP msg)
+runs on SGsAP_Emulation_CT return template SGsAP_RecvFrom {
+	var template SGsAP_RecvFrom mrf := {
+		connId := g_sgsap_conn_id,
+		remName := ?,
+		remPort := ?,
+		locName := ?,
+		locPort := ?,
+		msg := msg
+	}
+	return mrf;
+}
+
+private function f_imsi_known(hexstring imsi)
+runs on SGsAP_Emulation_CT return boolean {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		if (SgsapAssociationTable[i].imsi == imsi) {
+			return true;
+		}
+	}
+	return false;
+}
+
+private function f_comp_known(SGsAP_ConnHdlr client)
+runs on SGsAP_Emulation_CT return boolean {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		if (SgsapAssociationTable[i].comp_ref == client) {
+			return true;
+		}
+	}
+	return false;
+}
+
+private function f_comp_by_imsi(hexstring imsi)
+runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		if (SgsapAssociationTable[i].imsi == imsi) {
+			return SgsapAssociationTable[i].comp_ref;
+		}
+	}
+	setverdict(fail, "SGsAP Association Table not found by IMSI", imsi);
+	mtc.stop;
+}
+
+private function f_imsi_by_comp(SGsAP_ConnHdlr client)
+runs on SGsAP_Emulation_CT return hexstring {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		if (SgsapAssociationTable[i].comp_ref == client) {
+			return SgsapAssociationTable[i].imsi;
+		}
+	}
+	setverdict(fail, "SGsAP Association Table not found by component ", client);
+	mtc.stop;
+}
+
+private function f_imsi_table_add(SGsAP_ConnHdlr comp_ref, hexstring imsi)
+runs on SGsAP_Emulation_CT {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		if (not isvalue(SgsapAssociationTable[i].imsi)) {
+			SgsapAssociationTable[i].imsi := imsi;
+			SgsapAssociationTable[i].comp_ref := comp_ref;
+			return;
+		}
+	}
+	testcase.stop("SGsAP Association Table full!");
+}
+
+private function f_imsi_table_del(SGsAP_ConnHdlr comp_ref, hexstring imsi)
+runs on SGsAP_Emulation_CT {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		if (SgsapAssociationTable[i].comp_ref == comp_ref and
+		    SgsapAssociationTable[i].imsi == imsi) {
+			SgsapAssociationTable[i].imsi := omit;
+			SgsapAssociationTable[i].comp_ref := null;
+			return;
+		}
+	}
+	setverdict(fail, "SGsAP Association Table: Couldn't find to-be-deleted entry!");
+	mtc.stop;
+}
+
+
+private function f_imsi_table_init()
+runs on SGsAP_Emulation_CT {
+	for (var integer i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
+		SgsapAssociationTable[i].comp_ref := null;
+		SgsapAssociationTable[i].imsi := omit;
+	}
+}
+
+private function f_SGsAP_get_imsi(PDU_SGsAP pdu) return template (omit) IMSI
+{
+	if (ischosen(pdu.sGsAP_ALERT_ACK)) {
+		return pdu.sGsAP_ALERT_ACK.iMSI;
+	} else if (ischosen(pdu.sGsAP_ALERT_REJECT)) {
+		return pdu.sGsAP_ALERT_REJECT.iMSI;
+	} else if (ischosen(pdu.sGsAP_ALERT_REQUEST)) {
+		return pdu.sGsAP_ALERT_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_DOWNLINK_UNITDATA)) {
+		return pdu.sGsAP_DOWNLINK_UNITDATA.iMSI;
+	} else if (ischosen(pdu.sGsAP_EPS_DETACH_ACK)) {
+		return pdu.sGsAP_EPS_DETACH_ACK.iMSI;
+	} else if (ischosen(pdu.sGsAP_EPS_DETACH_INDICATION)) {
+		return pdu.sGsAP_EPS_DETACH_INDICATION.iMSI;
+	} else if (ischosen(pdu.sGsAP_IMSI_DETACH_ACK)) {
+		return pdu.sGsAP_IMSI_DETACH_ACK.iMSI;
+	} else if (ischosen(pdu.sGsAP_IMSI_DETACH_INDICATION)) {
+		return pdu.sGsAP_IMSI_DETACH_INDICATION.iMSI;
+	} else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_ACCEPT)) {
+		return pdu.sGsAP_LOCATION_UPDATE_ACCEPT.iMSI;
+	} else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_REJECT)) {
+		return pdu.sGsAP_LOCATION_UPDATE_REJECT.iMSI;
+	} else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_REQUEST)) {
+		return pdu.sGsAP_LOCATION_UPDATE_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_MM_INFORMATION_REQUEST)) {
+		return pdu.sGsAP_MM_INFORMATION_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_PAGING_REJECT)) {
+		return pdu.sGsAP_PAGING_REJECT.iMSI;
+	} else if (ischosen(pdu.sGsAP_PAGING_REQUEST)) {
+		return pdu.sGsAP_PAGING_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_SERVICE_REQUEST)) {
+		return pdu.sGsAP_SERVICE_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_STATUS)) {
+		return pdu.sGsAP_STATUS.iMSI;
+	} else if (ischosen(pdu.sGsAP_TMSI_REALLOCATION_COMPLETE)) {
+		return pdu.sGsAP_TMSI_REALLOCATION_COMPLETE.iMSI;
+	} else if (ischosen(pdu.sGsAP_UE_ACTIVITY_INDICATION)) {
+		return pdu.sGsAP_UE_ACTIVITY_INDICATION.iMSI;
+	} else if (ischosen(pdu.sGsAP_UE_UNREACHABLE)) {
+		return pdu.sGsAP_UE_UNREACHABLE.iMSI;
+	} else if (ischosen(pdu.sGsAP_UPLINK_UNITDATA)) {
+		return pdu.sGsAP_UPLINK_UNITDATA.iMSI;
+	} else if (ischosen(pdu.sGsAP_RELEASE_REQUEST)) {
+		return pdu.sGsAP_RELEASE_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_SERVICE_ABORT_REQUEST)) {
+		return pdu.sGsAP_SERVICE_ABORT_REQUEST.iMSI;
+	} else if (ischosen(pdu.sGsAP_MO_CSFB_INDICATION)) {
+		return pdu.sGsAP_MO_CSFB_INDICATION.iMSI;
+	}
+	return omit;
+}
+
+private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := omit) := {
+	sinfo_stream := omit,
+	sinfo_ppid := ppid,
+	remSocks := omit,
+	assocId := omit
+};
+
+private template PortEvent tr_SctpAssocChange := {
+	sctpEvent := {
+		sctpAssocChange := ?
+	}
+}
+private template PortEvent tr_SctpPeerAddrChange := {
+	sctpEvent := {
+		sctpPeerAddrChange := ?
+	}
+}
+
+private function f_sgsap_xceive(template (value) PDU_SGsAP tx,
+				template PDU_SGsAP rx_t := ?)
+runs on SGsAP_Emulation_CT  return PDU_SGsAP {
+	timer T := 10.0;
+	var SGsAP_RecvFrom mrf;
+
+	SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, tx));
+	alt {
+	[] SGsAP.receive(tr_SGsAP_RecvFrom_R(rx_t)) -> value mrf { }
+	[] SGsAP.receive(tr_SctpAssocChange) { repeat; }
+	[] SGsAP.receive(tr_SctpPeerAddrChange)  { repeat; }
+	[] T.timeout {
+		setverdict(fail, "Timeout waiting for ", rx_t);
+		mtc.stop;
+		}
+	}
+	return mrf.msg;
+}
+
+function main(SGsAPOps ops, SGsAP_conn_parameters p, charstring id) runs on SGsAP_Emulation_CT {
+	var Result res;
+	g_sgsap_id := id;
+	f_imsi_table_init();
+	f_expect_table_init();
+
+	map(self:SGsAP, system:SGsAP_CODEC_PT);
+	if (p.remote_sctp_port == -1) {
+		res := SGsAP_CodecPort_CtrlFunct.f_IPL4_listen(SGsAP, p.local_ip, p.local_sctp_port, { sctp := valueof(ts_SCTP) });
+	} else {
+		res := SGsAP_CodecPort_CtrlFunct.f_IPL4_connect(SGsAP, p.remote_ip, p.remote_sctp_port,
+								p.local_ip, p.local_sctp_port, -1, { sctp := valueof(ts_SCTP) });
+	}
+	if (not ispresent(res.connId)) {
+		setverdict(fail, "Could not connect SGsAP socket, check your configuration");
+		mtc.stop;
+	}
+	g_sgsap_conn_id := res.connId;
+
+	while (true) {
+		var SGsAP_ConnHdlr vc_conn;
+		var template IMSI imsi_t;
+		var hexstring imsi;
+		var SGsAP_RecvFrom mrf;
+		var PDU_SGsAP msg;
+
+		alt {
+		/* SGsAP from client */
+		[] SGsAP_CLIENT.receive(PDU_SGsAP:?) -> value msg sender vc_conn {
+			/* Pass message through */
+			/* TODO: check which ConnectionID client has allocated + store in table? */
+			SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, msg));
+			}
+		[] SGsAP.receive(tr_SGsAP_RecvFrom_R(?)) -> value mrf {
+			imsi_t := f_SGsAP_get_imsi(mrf.msg);
+			if (isvalue(imsi_t)) {
+				imsi := valueof(imsi_t.iMSI.digits);
+				if (f_imsi_known(imsi)) {
+					vc_conn := f_comp_by_imsi(imsi);
+					SGsAP_CLIENT.send(mrf.msg) to vc_conn;
+				} else {
+					vc_conn := ops.create_cb.apply(mrf.msg, imsi, id);
+					f_imsi_table_add(vc_conn, imsi);
+					SGsAP_CLIENT.send(mrf.msg) to vc_conn;
+				}
+			} else {
+				/* message contained no IMSI; is not IMSI-oriented */
+				var template PDU_SGsAP resp := ops.unitdata_cb.apply(mrf.msg);
+				if (isvalue(resp)) {
+					SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, valueof(resp)));
+				}
+			}
+			}
+		[] SGsAP.receive(tr_SctpAssocChange) { }
+		[] SGsAP.receive(tr_SctpPeerAddrChange)  { }
+		[] SGsAP_PROC.getcall(SGsAPEM_register:{?,?}) -> param(imsi, vc_conn) {
+			f_create_expect(imsi, vc_conn);
+			SGsAP_PROC.reply(SGsAPEM_register:{imsi, vc_conn}) to vc_conn;
+			}
+		}
+
+	}
+}
+
+/* "Expect" Handling */
+
+type record ExpectData {
+	hexstring imsi optional,
+	SGsAP_ConnHdlr vc_conn
+}
+
+signature SGsAPEM_register(in hexstring imsi, in SGsAP_ConnHdlr hdlr);
+
+type port SGsAPEM_PROC_PT procedure {
+	inout SGsAPEM_register;
+} with { extension "internal" };
+
+/* Function that can be used as create_cb and will usse the expect table */
+function ExpectedCreateCallback(PDU_SGsAP msg, hexstring imsi, charstring id)
+runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr {
+	var SGsAP_ConnHdlr ret := null;
+	var integer i;
+
+	for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {
+		if (not ispresent(SgsapExpectTable[i].imsi)) {
+			continue;
+		}
+		if (imsi == SgsapExpectTable[i].imsi) {
+			ret := SgsapExpectTable[i].vc_conn;
+			/* Release this entry */
+			SgsapExpectTable[i].imsi := omit;
+			SgsapExpectTable[i].vc_conn := null;
+			log("Found Expect[", i, "] for ", msg, " handled at ", ret);
+			return ret;
+		}
+	}
+	setverdict(fail, "Couldn't find Expect for ", msg);
+	mtc.stop;
+}
+
+private function f_create_expect(hexstring imsi, SGsAP_ConnHdlr hdlr)
+runs on SGsAP_Emulation_CT {
+	var integer i;
+
+	/* Check an entry like this is not already presnt */
+	for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {
+		if (imsi == SgsapExpectTable[i].imsi) {
+			setverdict(fail, "IMSI already present", imsi);
+			mtc.stop;
+		}
+	}
+	for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {
+		if (not ispresent(SgsapExpectTable[i].imsi)) {
+			SgsapExpectTable[i].imsi := imsi;
+			SgsapExpectTable[i].vc_conn := hdlr;
+			log("Created Expect[", i, "] for ", imsi, " to be handled at ", hdlr);
+			return;
+		}
+	}
+	testcase.stop("No space left in SgsapExpectTable")
+}
+
+/* client/conn_hdlr side function to use procedure port to create expect in emulation */
+function f_create_sgsap_expect(hexstring imsi) runs on SGsAP_ConnHdlr {
+	SGsAP_PROC.call(SGsAPEM_register:{imsi, self}) {
+		[] SGsAP_PROC.getreply(SGsAPEM_register:{?,?}) {};
+	}
+}
+
+
+private function f_expect_table_init()
+runs on SGsAP_Emulation_CT {
+	var integer i;
+	for (i := 0; i < sizeof(SgsapExpectTable); i := i + 1) {
+		SgsapExpectTable[i].imsi := omit;
+	}
+}
+
+function DummyUnitdataCallback(PDU_SGsAP msg)
+runs on SGsAP_Emulation_CT return template PDU_SGsAP {
+	log("Ignoring SGsAP ", msg);
+	return omit;
+}
+
+
+}
