module BSSMAP_Emulation {

/* BSSMAP 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 BSSMAP_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 BSSMAP_Emulation.main() function.
 *
 * For each new inbound connections, the BssmapOps.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 BssmapOps.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 BSSAP_ConnHdlr {
	/* port towards MSC Emulator core / SCCP connection dispatchar */
	port BSSAP_Conn_PT BSSAP;
	/* procedure based port to register for incoming connections */
	port BSSMAPEM_PROC_PT BSSAP_PROC;
}

/* Auxiliary primitive that can happen on the port between per-connection client and this dispatcher */
type enumerated BSSAP_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
}


/* port between individual per-connection components and this dispatcher */
type port BSSAP_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 */
		BSSAP_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 */
	BSSAP_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 {
	BSSAP_ConnHdlr	comp_ref,
	hexstring	imsi optional,
	OCT4		tmsi
}

type component BSSMAP_Emulation_CT {
	/* SCCP port on the bottom side, using ASP primitives */
	port BSSAP_CODEC_PT BSSAP;
	/* BSSAP port to the per-connection clients */
	port BSSAP_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 BSSMAPEM_PROC_PT PROC;

	var charstring g_bssmap_id;
	var integer g_next_e1_ts := 1;
	var BssmapOps g_bssmap_ops;
};

private function f_conn_id_known(integer sccp_conn_id)
runs on BSSMAP_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(BSSAP_ConnHdlr client)
runs on BSSMAP_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 BSSMAP_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 BSSMAP_Emulation_CT return BSSAP_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;
		}
	}
	log("BSSMAP Connection table not found by SCCP Connection ID ", sccp_conn_id);
	setverdict(fail);
	self.stop;
}

/* resolve component reference by CIC */
private function f_comp_by_mgcp_tid(MgcpTransId tid)
runs on BSSMAP_Emulation_CT return BSSAP_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;
		}
	}
	log("BSSMAP Connection table not found by MGCP Transaction ID ", tid);
	setverdict(fail);
	self.stop;
}

private function f_comp_store_mgcp_tid(BSSAP_ConnHdlr client, MgcpTransId tid)
runs on BSSMAP_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;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
	self.stop;
}

private function f_comp_by_cic(integer cic)
runs on BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].cic == cic) {
			return ConnectionTable[i].comp_ref;
		}
	}
	log("BSSMAP Connection table not found by CIC ", cic);
	setverdict(fail);
	self.stop;
}

private function f_comp_store_cic(BSSAP_ConnHdlr client, integer cic)
runs on BSSMAP_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;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
}

/* resolve connection ID by component reference */
private function f_conn_id_by_comp(BSSAP_ConnHdlr client)
runs on BSSMAP_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;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
	self.stop;
}

/* resolve ConnectionTable index component reference */
private function f_idx_by_comp(BSSAP_ConnHdlr client)
runs on BSSMAP_Emulation_CT return integer {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		if (ConnectionTable[i].comp_ref == client) {
			return i;
		}
	}
	log("BSSMAP Connection table not found by component ", client);
	setverdict(fail);
	self.stop;
}

private function f_gen_conn_id()
runs on BSSMAP_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 BSSMAP_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(BSSAP_ConnHdlr comp_ref, integer sccp_conn_id)
runs on BSSMAP_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;
		}
	}
	log("BSSMAP Connection table full!");
	setverdict(fail);
	self.stop;
}

private function f_conn_table_del(integer sccp_conn_id)
runs on BSSMAP_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
		}
	}
	log("BSSMAP Connection table attempt to delete non-existant ", sccp_conn_id);
	setverdict(fail);
	self.stop;
}

private function f_imsi_table_find(hexstring imsi, template OCT4 tmsi)
runs on BSSMAP_Emulation_CT return BSSAP_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(BSSAP_ConnHdlr client, PDU_BSSAP bssap)
runs on BSSMAP_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_bssmap_ops.decode_dtap) {
		if (g_bssmap_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 BSSMAP_Emulation_CT return BSSAP_ConnHdlr;

type function BssmapUnitdataCallback(PDU_BSSAP bssap)
runs on BSSMAP_Emulation_CT return template PDU_BSSAP;

/* handle common Unitdata such as Paging */
private function CommonBssmapUnitdataCallback(PDU_BSSAP bssap)
runs on BSSMAP_Emulation_CT return template PDU_BSSAP {
	if (match(bssap, tr_BSSMAP_Paging)) {
		var BSSAP_ConnHdlr client := null;
		client := f_imsi_table_find(bssap.pdu.bssmap.paging.iMSI.digits,
					   bssap.pdu.bssmap.paging.tMSI.tmsiOctets);
		if (isvalue(client)) {
			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_bssmap_ops.unitdata_cb.apply(bssap);
}

type record BssmapOps {
	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 BSSMAP_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 BSSMAP_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);
		}
	}
}

function f_bssap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on BSSMAP_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, "Waiting for RESET-ACK after sending RESET"); }
	}
}

function main(BssmapOps ops, charstring id) runs on BSSMAP_Emulation_CT {

	g_bssmap_id := id;
	g_bssmap_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 BSSAP_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 BSSAP_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 BSSAP_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 BSSAP_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(BSSAP_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_bssmap_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_bssmap_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_bssmap_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(BSSMAPEM_register:{?,?}) -> param(l3_info, vc_hdlr) {
			f_create_expect(l3_info, vc_hdlr);
			PROC.reply(BSSMAPEM_register:{l3_info, vc_hdlr}) to vc_hdlr;
			}

		[] PROC.getcall(BSSMAPEM_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) {
			f_create_imsi(imsi, tmsi, vc_hdlr);
			PROC.reply(BSSMAPEM_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 */
	BSSAP_ConnHdlr vc_conn
}

/* procedure based port to register for incoming connections */
signature BSSMAPEM_register(in octetstring l3, in BSSAP_ConnHdlr hdlr);

/* procedure based port to register for incoming IMSI/TMSI */
signature BSSMAPEM_register_imsi(in hexstring imsi, in OCT4 tmsi, in BSSAP_ConnHdlr hdlr);

type port BSSMAPEM_PROC_PT procedure {
	inout BSSMAPEM_register, BSSMAPEM_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 BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var BSSAP_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");
		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);
	return ret;
}

private function f_create_expect(octetstring l3, BSSAP_ConnHdlr hdlr)
runs on BSSMAP_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;
		}
	}
	setverdict(fail, "No space left in ExpectTable");
}

private function f_create_imsi(hexstring imsi, OCT4 tmsi, BSSAP_ConnHdlr hdlr)
runs on BSSMAP_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;
		}
	}
	setverdict(fail, "No space left in ImsiTable");
	self.stop;
}


private function f_expect_table_init()
runs on BSSMAP_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_bssmap_register_imsi(hexstring imsi, OCT4 tmsi)
runs on BSSAP_ConnHdlr {
	BSSAP_PROC.call(BSSMAPEM_register_imsi:{imsi, tmsi, self}) {
		[] BSSAP_PROC.getreply(BSSMAPEM_register_imsi:{?,?,?}) {};
	}
}


}
