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,
	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) := {
	dlci := dlci,
	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,
	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);
	/* 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_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 */
			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});
			}

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


		}
	}
}

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


}
