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 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 {
	inout PDU_BSSAP, PDU_DTAP_MO, PDU_DTAP_MT, BSSAP_Conn_Prim, BSSAP_Conn_Req, 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
}

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;
}

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;
	}
	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;
			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
}

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();

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

			}

		[] 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 conn_id := f_conn_id_by_comp(vc_conn);
			/* convert from decoded DTAP to encoded DTAP */
			var octetstring l3_enc := enc_PDU_ML3_MS_NW(dtap_mo.dtap);
			bssap := valueof(ts_BSSAP_DTAP(l3_enc, dtap_mo.dlci));
			BSSAP.send(ts_BSSAP_DATA_req(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:{?,?,?}) {};
	}
}


}
