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
}

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 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;
		}
	}
	setverdict(fail, "BSSMAP 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 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;
		}
	}
	setverdict(fail, "BSSMAP Connection table not found by MGCP Transaction ID ", tid);
	mtc.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;
		}
	}
	setverdict(fail, "BSSMAP Connection table not found by component ", client);
	mtc.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;
		}
	}
	setverdict(fail, "BSSMAP Connection table not found by CIC ", cic);
	mtc.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;
		}
	}
	setverdict(fail, "BSSMAP Connection table not found by component ", client);
	mtc.stop;
}

/* 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;
		}
	}
	setverdict(fail, "BSSMAP Connection table not found by component ", client);
	mtc.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;
		}
	}
	setverdict(fail, "BSSMAP Connection table not found by component ", client);
	mtc.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;
		}
	}
	testcase.stop("BSSMAP Connection table full!");
}

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
		}
	}
	setverdict(fail, "BSSMAP 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 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, "Timeout waiting for BSSAP RESET");
		mtc.stop;
		}
	}
}

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, "Timeout waiting for RESET-ACK after sending RESET");
		mtc.stop;
		}
	}
}

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");
		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, 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;
		}
	}
	testcase.stop("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;
		}
	}
	testcase.stop("No space left in ImsiTable");
}


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:{?,?,?}) {};
	}
}


}
