module RAN_Emulation {

/* RAN 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 RAN_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 RAN_Emulation.main() function.
 *
 * For each new inbound connections, the RanOps.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 RanOps.unitdata_cb() callback,
 * which is registered with an argument to the main() function below.
 *
 * (C) 2017-2019 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 IPA_Emulation all;
import from MobileL3_Types all;

#ifdef RAN_EMULATION_BSSAP
import from BSSAP_Types all;
import from BSSAP_CodecPort all;
import from BSSMAP_Templates all;
#endif

#ifdef RAN_EMULATION_MGCP
import from MGCP_Types all;
import from MGCP_Templates all;
#endif

#ifdef RAN_EMULATION_RANAP
import from RANAP_CodecPort all;
import from RANAP_PDU_Descriptions all;
import from RANAP_Constants all;
import from RANAP_IEs all;
import from RANAP_Templates all;
#endif

/* General "base class" component definition, of which specific implementations
 * derive themselves by means of the "extends" feature */
type component RAN_ConnHdlr {
	/* port towards MSC Emulator core / SCCP connection dispatchar */
	port RAN_Conn_PT BSSAP;
	/* procedure based port to register for incoming connections */
	port RAN_PROC_PT BSSAP_PROC;
}

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

/* 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 RAN_Conn_PT message {
	inout
#ifdef RAN_EMULATION_BSSAP
		PDU_BSSAP,
		/* Client requests us to create SCCP Connection */
		BSSAP_Conn_Req,
#endif
#ifdef RAN_EMULATION_RANAP
		RANAP_PDU,
		/* Client requests us to create SCCP Connection */
		RANAP_Conn_Req,
#endif
#ifdef RAN_EMULATION_MGCP
		/* MGCP, only used for IPA SCCPlite (MGCP in IPA mux) */
		MgcpCommand, MgcpResponse,
#endif
		/* direct DTAP messages from/to clients */
		PDU_DTAP_MO, PDU_DTAP_MT,
		/* misc indications / requests between SCCP and client */
		RAN_Conn_Prim;
} with { extension "internal" };

type uint2_t N_Sd_Array[4];

/* represents a single BSSAP connection over SCCP */
type record ConnectionData {
	/* reference to the instance of the per-connection component */
	RAN_ConnHdlr	comp_ref,
	integer		sccp_conn_id,
#ifdef RAN_EMULATION_MGCP
	/* most recent MGCP transaction ID (Used on MSC side) */
	MgcpTransId	mgcp_trans_id optional,
#endif
	/* 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 */
	N_Sd_Array	n_sd
}

type record ImsiMapping {
	RAN_ConnHdlr	comp_ref,
	hexstring	imsi optional,
	OCT4		tmsi
}

type component RAN_Emulation_CT {
	/* SCCP ports on the bottom side, using ASP primitives */
#ifdef RAN_EMULATION_BSSAP
	port BSSAP_CODEC_PT BSSAP;
#endif
#ifdef RAN_EMULATION_RANAP
	port RANAP_CODEC_PT RANAP;
#endif
	/* BSSAP port to the per-connection clients */
	port RAN_Conn_PT CLIENT;
#ifdef RAN_EMULATION_MGCP
	/* MGCP port */
	port IPA_MGCP_PT MGCP;
#endif

	/* 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 RAN_PROC_PT PROC;

	var charstring g_ran_id;
	var integer g_next_e1_ts := 1;
	var RanOps g_ran_ops;
};

private function f_conn_id_known(integer sccp_conn_id)
runs on RAN_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(RAN_ConnHdlr client)
runs on RAN_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 RAN_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 RAN_Emulation_CT return RAN_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, "RAN Connection table not found by SCCP Connection ID ", sccp_conn_id);
	mtc.stop;
}


#ifdef RAN_EMULATION_MGCP
/* resolve component reference by CIC */
private function f_comp_by_mgcp_tid(MgcpTransId tid)
runs on RAN_Emulation_CT return RAN_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, "RAN Connection table not found by MGCP Transaction ID ", tid);
	mtc.stop;
}

private function f_comp_store_mgcp_tid(RAN_ConnHdlr client, MgcpTransId tid)
runs on RAN_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, "RAN Connection table not found by component ", client);
	mtc.stop;
}
#endif

private function f_comp_by_cic(integer cic)
runs on RAN_Emulation_CT return RAN_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, "RAN Connection table not found by CIC ", cic);
	mtc.stop;
}

private function f_comp_store_cic(RAN_ConnHdlr client, integer cic)
runs on RAN_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, "RAN Connection table not found by component ", client);
	mtc.stop;
}

/* resolve connection ID by component reference */
private function f_conn_id_by_comp(RAN_ConnHdlr client)
runs on RAN_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, "RAN Connection table not found by component ", client);
	mtc.stop;
}

/* resolve ConnectionTable index component reference */
private function f_idx_by_comp(RAN_ConnHdlr client)
runs on RAN_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, "RAN Connection table not found by component ", client);
	mtc.stop;
}

private function f_gen_conn_id()
runs on RAN_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 RAN_Emulation_CT {
	for (var integer i := 0; i < sizeof(ConnectionTable); i := i+1) {
		ConnectionTable[i].comp_ref := null;
		ConnectionTable[i].sccp_conn_id := -1;
#ifdef RAN_EMULATION_MGCP
		ConnectionTable[i].mgcp_trans_id := omit;
#endif
		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(RAN_ConnHdlr comp_ref, integer sccp_conn_id)
runs on RAN_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("RAN Connection table full!");
}

private function f_conn_table_del(integer sccp_conn_id)
runs on RAN_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, "RAN 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 RAN_Emulation_CT return RAN_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;
}

#ifdef RAN_EMULATION_BSSAP
type record BSSAP_Conn_Req {
	SCCP_PAR_Address	addr_peer,
	SCCP_PAR_Address	addr_own,
	PDU_BSSAP		bssap
}
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
};

/* handle (optional) userData portion of various primitives and dispatch it to the client */
private function f_handle_userData(RAN_ConnHdlr client, PDU_BSSAP bssap)
runs on RAN_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_ran_ops.decode_dtap) {
		if (g_ran_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 RAN_Emulation_CT return RAN_ConnHdlr;

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

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

private function f_bssap_wait_for_reset() runs on RAN_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(g_ran_ops.use_osmux))) -> value ud_ind {
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck(g_ran_ops.use_osmux)));
		}
	[] 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 RAN_Emulation_CT {
	timer T := 5.0;

	BSSAP.send(ts_BSSAP_UNITDATA_req(peer, own, ts_BSSMAP_Reset(0, g_ran_ops.use_osmux)));
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(own, peer, tr_BSSMAP_ResetAck(g_ran_ops.use_osmux))) {
		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;
		}
	}
}

private function f_bssap_l3_is_rr(PDU_BSSAP bssap) return boolean {
	var template octetstring l3 := f_bssap_extract_l3(bssap);
	return f_L3_is_rr(l3);
}
#endif

#ifdef RAN_EMULATION_RANAP
type record RANAP_Conn_Req {
	SCCP_PAR_Address	addr_peer,
	SCCP_PAR_Address	addr_own,
	RANAP_PDU		ranap
}
template (value) RANAP_Conn_Req ts_RANAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, RANAP_PDU ranap) := {
	addr_peer := peer,
	addr_own := own,
	ranap := ranap
};

private function fake_dlci_from_sapi(template (omit) SAPI sapi) return template (omit) OCT1
{
	if (istemplatekind(sapi, "omit")) {
		return omit;
	} else if (valueof(sapi) == sapi_3) {
		return '03'O;
	}
	return '00'O;
}

private function f_handle_userData_RANAP(RAN_ConnHdlr client, RANAP_PDU ranap)
runs on RAN_Emulation_CT {
	/* decode + send decoded RANAP to client */
	var template (omit) octetstring l3 := f_ranap_extract_l3(ranap);
	if (istemplatekind(l3, "omit")) {
		CLIENT.send(ranap) to client;
	} else {
		var template (omit) SAPI sapi := f_ranap_extract_sapi(ranap);
		var template (omit) OCT1 dlci := fake_dlci_from_sapi(sapi);
		if (g_ran_ops.role_ms) {
			/* we are the MS, so any message to us must be MT */
			var PDU_DTAP_MT mt := {
				dlci := omit,
				dtap := dec_PDU_ML3_NW_MS(valueof(l3))
			};
			if (isvalue(dlci)) {
				mt.dlci := valueof(dlci)
			}
			CLIENT.send(mt) to client;
		} else {
			/* we are the Network, so any message to us must be MO */
			var PDU_DTAP_MO mo := {
				dlci := omit,
				dtap := dec_PDU_ML3_MS_NW(valueof(l3))
			};
			if (isvalue(dlci)) {
				mo.dlci := valueof(dlci)
			}
			CLIENT.send(mo) to client;
		}
	}
}

/* call-back type, to be provided by specific implementation; called when new SCCP connection
 * arrives */
type function RanapCreateCallback(RANAP_N_CONNECT_ind conn_ind, charstring id)
runs on RAN_Emulation_CT return RAN_ConnHdlr;

type function RanapUnitdataCallback(RANAP_PDU ranap)
runs on RAN_Emulation_CT return template RANAP_PDU;

private function CommonRanapUnitdataCallback(RANAP_PDU ranap)
runs on RAN_Emulation_CT return template RANAP_PDU {
	if (match(ranap, tr_RANAP_Paging(?, ?))) {
		var RAN_ConnHdlr client := null;
		/* extract IMSI and (if present) TMSI */
		var IMSI imsi := ranap.initiatingMessage.value_.paging.protocolIEs[1].value_.permanentNAS_UE_ID.iMSI;
		var template OCT4 tmsi := omit;
		if (lengthof(ranap.initiatingMessage.value_.paging.protocolIEs) > 2 and
		    ranap.initiatingMessage.value_.paging.protocolIEs[2].id == id_TemporaryUE_ID) {
			var TemporaryUE_ID ue_id;
			ue_id := ranap.initiatingMessage.value_.paging.protocolIEs[2].value_.temporaryUE_ID;
			if (ischosen(ue_id.tMSI)) {
				tmsi := ue_id.tMSI;
			} else {
				tmsi := ue_id.p_TMSI;
			}
		}
		client := f_imsi_table_find(oct2hex(imsi), tmsi);
		if (client != null) {
			log("CommonRanapUnitdataCallback: IMSI/TMSI found in table, dispatching to ",
				client);
			CLIENT.send(ranap) to client;
			return omit;
		}
		log("CommonRanapUnitdataCallback: IMSI/TMSI not found in table");
	} else {
		log("CommonRanapUnitdataCallback: Not a paging message");
	}

	/* ELSE: handle in user callback */
	return g_ran_ops.ranap_unitdata_cb.apply(ranap);
}

private function f_ranap_l3_is_rr(RANAP_PDU ranap) return boolean {
	var template (omit) SAPI sapi;
	var template octetstring l3 := f_ranap_extract_l3(ranap);
	return f_L3_is_rr(l3);
}

function f_ranap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on RAN_Emulation_CT {
	timer T := 5.0;
	var CN_DomainIndicator dom;
	if (g_ran_ops.ps_domain) {
		dom := ps_domain;
	} else {
		dom := cs_domain;
	}

	RANAP.send(ts_RANAP_UNITDATA_req(peer, own, ts_RANAP_Reset(ts_RanapCause_om_intervention, dom)));
	T.start;
	alt {
	[] RANAP.receive(tr_RANAP_UNITDATA_ind(own, peer, tr_RANAP_ResetAck)) {
		log("Received RESET-ACK in response to RESET, we're ready to go!");
		}
	[] as_reset_ack();
	[] RANAP.receive { repeat };
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RESET-ACK after sending RESET");
		mtc.stop;
		}
	}
}
#endif


type enumerated RanProtocol {
	RAN_PROTOCOL_BSSAP,
	RAN_PROTOCOL_RANAP
}

type record RanOps {
#ifdef RAN_EMULATION_BSSAP
	BssmapCreateCallback create_cb optional,
	BssmapUnitdataCallback unitdata_cb optional,
#endif
#ifdef RAN_EMULATION_RANAP
	RanapCreateCallback ranap_create_cb optional,
	RanapUnitdataCallback ranap_unitdata_cb optional,
	boolean ps_domain,
#endif
	boolean decode_dtap,
	boolean role_ms,
	RanProtocol protocol,
	boolean use_osmux,
	/* 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);

private function f_L3_is_rr(template octetstring l3) return boolean {
	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;
}

function f_next_n_sd(inout N_Sd_Array n_sd, in integer n_sd_idx) return uint2_t {
	var uint2_t seq_nr;
	if (n_sd_idx == 0) {
		seq_nr := n_sd[0];
		n_sd[0] := (n_sd[0] + 1) mod 4;
	} else if (n_sd_idx >= 1 and n_sd_idx <= 3) {
		seq_nr := n_sd[n_sd_idx];
		n_sd[n_sd_idx] := (n_sd[n_sd_idx] + 1) mod 2;
	} else {
		/* no sequence number to patch */
		seq_nr := 0;
	}
	return seq_nr;
}

/* patch N(SD) into enc_l3, according to 24.007 11.2.3.2 */
function f_ML3_patch_seq_nr(in uint2_t seq_nr, inout octetstring enc_l3) {
	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);
}

function f_ML3_n_sd_idx(in PDU_ML3_MS_NW dtap) return integer {
	var uint2_t seq_nr;
	if (ischosen(dtap.msgs.cc) or ischosen(dtap.msgs.mm) or ischosen(dtap.msgs.ss)) {
		return 0;
	} else if (ischosen(dtap.msgs.gcc)) {
		return 1;
	} else if (ischosen(dtap.msgs.bcc)) {
		return 2;
	} else if (ischosen(dtap.msgs.loc)) {
		return 3;
	}
	/* no sequence number to patch */
	return -1;
}

/* 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 integer n_sd_idx := f_ML3_n_sd_idx(dtap);
	if (n_sd_idx < 0) {
		return;
	}
	var uint2_t seq_nr := f_next_n_sd(cd.n_sd, n_sd_idx);
	f_ML3_patch_seq_nr(seq_nr, enc_l3);
}

private altstep as_reset_ack() runs on RAN_Emulation_CT {
#ifdef RAN_EMULATION_BSSAP
	var BSSAP_N_UNITDATA_ind ud_ind;
#endif
#ifdef RAN_EMULATION_RANAP
	var RANAP_N_UNITDATA_ind rud_ind;
#endif
#ifdef RAN_EMULATION_BSSAP
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_ran_ops.use_osmux))) -> 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(g_ran_ops.use_osmux)));
		repeat;
	}
#endif
#ifdef RAN_EMULATION_RANAP
	[] RANAP.receive(tr_RANAP_UNITDATA_ind(?, ?, tr_RANAP_Reset)) -> value rud_ind {
		log("Respoding to inbound IuRESET with IuRESET-ACK");
		var CN_DomainIndicator dom;
		dom := rud_ind.userData.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
		RANAP.send(ts_RANAP_UNITDATA_req(rud_ind.callingAddress, rud_ind.calledAddress,
			   ts_RANAP_ResetAck(dom)));
	}
#endif
}


private altstep as_main_bssap() runs on RAN_Emulation_CT {
#ifdef RAN_EMULATION_BSSAP
		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 PDU_BSSAP bssap;
		var RAN_ConnHdlr vc_conn;
		var integer targetPointCode;
		var N_Sd_Array last_n_sd;

		/* 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 := g_ran_ops.create_cb.apply(conn_ind, g_ran_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 RAN_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 RAN_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);
			}
			}
		[] 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));
			}

		/* Disconnect request client -> SCCP */
		[] CLIENT.receive(RAN_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_ran_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");
			}
			}

		[] PROC.getcall(RAN_last_n_sd:{?,-}) -> param(vc_conn) {
			var integer idx := f_idx_by_comp(vc_conn);
			last_n_sd := ConnectionTable[idx].n_sd;
			PROC.reply(RAN_last_n_sd:{vc_conn, last_n_sd}) to vc_conn;
			}

		[] PROC.getcall(RAN_continue_after_n_sd:{?,?}) -> param(last_n_sd, vc_conn) {
			var integer idx := f_idx_by_comp(vc_conn);
			ConnectionTable[idx].n_sd := last_n_sd;
			PROC.reply(RAN_continue_after_n_sd:{last_n_sd, vc_conn}) to vc_conn;
			}
#else
		[false] CLIENT.receive {}
#endif
}

private altstep as_main_ranap() runs on RAN_Emulation_CT {
#ifdef RAN_EMULATION_RANAP
		var RANAP_N_UNITDATA_ind rud_ind;
		var RANAP_N_CONNECT_ind rconn_ind;
		var RANAP_N_CONNECT_cfm rconn_cfm;
		var RANAP_N_DATA_ind rdata_ind;
		var RANAP_N_DISCONNECT_ind rdisc_ind;
		var RANAP_Conn_Req creq;
		var RANAP_PDU ranap;
		var RAN_ConnHdlr vc_conn;

		/* SCCP -> Client: UNIT-DATA (connectionless SCCP) from a BSC */
		[] RANAP.receive(RANAP_N_UNITDATA_ind:?) -> value rud_ind {
			/* Connectionless Procedures like RESET */
			var template RANAP_PDU resp;
			resp := CommonRanapUnitdataCallback(rud_ind.userData);
			if (isvalue(resp)) {
				RANAP.send(ts_RANAP_UNITDATA_req(rud_ind.callingAddress,
								 rud_ind.calledAddress, resp));
			}
			}
		/* SCCP -> Client: new connection from BSC */
		[] RANAP.receive(RANAP_N_CONNECT_ind:?) -> value rconn_ind {
			vc_conn := g_ran_ops.ranap_create_cb.apply(rconn_ind, g_ran_id);
			/* store mapping between client components and SCCP connectionId */
			f_conn_table_add(vc_conn, rconn_ind.connectionId);
			/* handle user payload */
			f_handle_userData_RANAP(vc_conn, rconn_ind.userData);
			/* confirm connection establishment */
			RANAP.send(ts_RANAP_CONNECT_res(rconn_ind.connectionId, omit));
			}
		/* SCCP -> Client: connection-oriented data in existing connection */
		[] RANAP.receive(RANAP_N_DATA_ind:?) -> value rdata_ind {
			vc_conn := f_comp_by_conn_id(rdata_ind.connectionId);
			if (ispresent(rdata_ind.userData)) {
				f_handle_userData_RANAP(vc_conn, rdata_ind.userData);
			}
			}
		/* SCCP -> Client: disconnect of an existing connection */
		[] RANAP.receive(RANAP_N_DISCONNECT_ind:?) -> value rdisc_ind {
			vc_conn := f_comp_by_conn_id(rdisc_ind.connectionId);
			if (ispresent(rdisc_ind.userData)) {
				f_handle_userData_RANAP(vc_conn, rdisc_ind.userData);
			}
			/* notify client about termination */
			var RAN_Conn_Prim prim := MSC_CONN_PRIM_DISC_IND;
			CLIENT.send(prim) to vc_conn;
			f_conn_table_del(rdisc_ind.connectionId);
			/* TOOD: return confirm to other side? */
			}
		/* SCCP -> Client: connection confirm for outbound connection */
		[] RANAP.receive(RANAP_N_CONNECT_cfm:?) -> value rconn_cfm {
			vc_conn := f_comp_by_conn_id(rconn_cfm.connectionId);
			var RAN_Conn_Prim prim := MSC_CONN_PRIM_CONF_IND;
			CLIENT.send(prim) to vc_conn;
			/* handle user payload */
			if (ispresent(rconn_cfm.userData)) {
				f_handle_userData_RANAP(vc_conn, rconn_cfm.userData);
			}
			}

		[] CLIENT.receive(RANAP_PDU:?) -> value ranap sender vc_conn {
			var integer conn_id := f_conn_id_by_comp(vc_conn);
			/* send it to dispatcher */
			RANAP.send(ts_RANAP_DATA_req(conn_id, ranap));
			}

		/* Disconnect request client -> SCCP */
		[] CLIENT.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ) -> sender vc_conn {
			var integer conn_id := f_conn_id_by_comp(vc_conn);
			RANAP.send(ts_RANAP_DISC_req(conn_id, 0));
			f_conn_table_del(conn_id);
			}

		/* BSSAP from client -> SCCP */
		[] CLIENT.receive(RANAP_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);

				RANAP.send(ts_RANAP_CONNECT_req(creq.addr_peer, creq.addr_own, conn_id,
								creq.ranap));
			} else {
				/* known client, send via existing connection */
				conn_id := f_conn_id_by_comp(vc_conn);
				RANAP.send(ts_RANAP_DATA_req(conn_id, creq.ranap));
			}

			/* 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_ran_ops.role_ms and not f_ranap_l3_is_rr(creq.ranap)) {
				/* 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");
			}
			}

#else
		[false] CLIENT.receive {}
#endif
}

private altstep as_main_mgcp() runs on RAN_Emulation_CT {
#ifdef RAN_EMULATION_MGCP
		var MgcpCommand mgcp_req;
		var MgcpResponse mgcp_resp;
		var RAN_ConnHdlr vc_conn;

		/* 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;
			}
#else
		[false] CLIENT.receive {}
#endif
}

/* send a raw (encoded) L3 message over given SCCP connection */
private function f_xmit_raw_l3(integer sccp_conn_id, OCT1 dlci, octetstring l3_enc) runs on RAN_Emulation_CT
{
	select (g_ran_ops.protocol) {
#ifdef RAN_EMULATION_BSSAP
	case (RAN_PROTOCOL_BSSAP) {
		var PDU_BSSAP bssap;
		bssap := valueof(ts_BSSAP_DTAP(l3_enc, dlci));
		BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, bssap));
		}
#endif
#ifdef RAN_EMULATION_RANAP
	case (RAN_PROTOCOL_RANAP) {
		var RANAP_PDU ranap;
		if (false /* SAPI */) {
			var RANAP_IEs.SAPI sapi := sapi_0;
			ranap := valueof(ts_RANAP_DirectTransferSAPI(l3_enc, sapi));
		} else {
			ranap := valueof(ts_RANAP_DirectTransfer(l3_enc));
		}
		RANAP.send(ts_RANAP_DATA_req(sccp_conn_id, ranap));
		}
#endif
	}
}

function main(RanOps ops, charstring id) runs on RAN_Emulation_CT {

	g_ran_id := id;
	g_ran_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 */
		select (g_ran_ops.protocol) {
#ifdef RAN_EMULATION_BSSAP
		case (RAN_PROTOCOL_BSSAP) {
			f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local);
			}
#endif
#ifdef RAN_EMULATION_RANAP
		case (RAN_PROTOCOL_RANAP) {
			f_ranap_reset(ops.sccp_addr_peer, ops.sccp_addr_local);
			}
#endif
		}
	}

	while (true) {
		var RAN_ConnHdlr vc_conn;
		var PDU_DTAP_MO dtap_mo;
		var PDU_DTAP_MT dtap_mt;
		var RAN_ConnHdlr vc_hdlr;
		var octetstring l3_info;
		var hexstring imsi;
		var OCT4 tmsi;
		var integer targetPointCode;

		alt {
		[g_ran_ops.protocol == RAN_PROTOCOL_BSSAP] as_main_bssap();
		[g_ran_ops.protocol == RAN_PROTOCOL_RANAP] as_main_ranap();

		[g_ran_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);
			}
			f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, dtap_mo.dlci, l3_enc);
			}

		[not g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_MT:?) -> value dtap_mt 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_NW_MS(dtap_mt.dtap);
			f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, dtap_mt.dlci, l3_enc);
			}

		[] as_main_mgcp();

		[] PROC.getcall(RAN_register:{?,?}) -> param(l3_info, vc_hdlr) {
			f_create_expect(l3_info, vc_hdlr);
			PROC.reply(RAN_register:{l3_info, vc_hdlr}) to vc_hdlr;
			}

		[] PROC.getcall(RAN_register_handoverRequest:{?,?}) -> param(targetPointCode, vc_hdlr) {
			f_create_expect(omit, vc_hdlr, targetPointCode);
			PROC.reply(RAN_register_handoverRequest:{targetPointCode, vc_hdlr}) to vc_hdlr;
			}

		[] PROC.getcall(RAN_register_imsi:{?,?,?}) -> param(imsi, tmsi, vc_hdlr) {
			f_create_imsi(imsi, tmsi, vc_hdlr);
			PROC.reply(RAN_register_imsi:{imsi, tmsi, vc_hdlr}) to vc_hdlr;
			}


		}
	}
}

#ifdef RAN_EMULATION_MGCP
private function f_mgcp_ep_extract_cic(charstring inp) return integer {
	var charstring local_part := regexp(inp, "(*)@*", 0);
	return hex2int(str2hex(local_part));

}
#endif

/***********************************************************************
 * "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,
	integer handoverRequestPointCode optional,
	/* component reference for this connection */
	RAN_ConnHdlr vc_conn
}

/* procedure based port to register for incoming connections */
signature RAN_register(in octetstring l3, in RAN_ConnHdlr hdlr);
signature RAN_register_handoverRequest(in integer targetPointCode, in RAN_ConnHdlr hdlr);

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

/* If DTAP happens across other channels (e.g. GSUP), provide manual advancing of the n_sd sequence number */
signature RAN_last_n_sd(in RAN_ConnHdlr hdlr, out N_Sd_Array last_n_sd);

/* Update conn's n_sd sequence nr after the connection was taken over from elsewhere */
signature RAN_continue_after_n_sd(N_Sd_Array last_n_sd, in RAN_ConnHdlr hdlr);

type port RAN_PROC_PT procedure {
	inout RAN_register, RAN_register_imsi, RAN_register_handoverRequest, RAN_last_n_sd, RAN_continue_after_n_sd;
} with { extension "internal" };

#ifdef RAN_EMULATION_BSSAP
/* 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 RAN_Emulation_CT return RAN_ConnHdlr {
	var RAN_ConnHdlr ret := null;
	var octetstring l3_info;
	var boolean handoverRequest := false;
	var integer handoverRequestPointCode;
	var integer i;

	if (ischosen(conn_ind.userData.pdu.bssmap.completeLayer3Information)) {
		l3_info := conn_ind.userData.pdu.bssmap.completeLayer3Information.layer3Information.layer3info;
		log("ExpectedCreateCallback completeLayer3Information");
	} else if (ischosen(conn_ind.userData.pdu.bssmap.handoverRequest)) {
		handoverRequest := true;
		handoverRequestPointCode := bit2int(conn_ind.calledAddress.signPointCode);
		log("ExpectedCreateCallback handoverRequest ", handoverRequestPointCode);
	} else {
		setverdict(fail, "N-CONNECT.ind with L3 != COMPLETE L3 nor a Handover Request");
		mtc.stop;
		return ret;
	}

	for (i := 0; i < sizeof(ExpectTable); i:= i+1) {
		if (handoverRequest) {
			log("ExpectTable[", i, "].handoverRequestPointCode = ", ExpectTable[i].handoverRequestPointCode,
			    " ==? ", handoverRequestPointCode);
			if (ExpectTable[i].handoverRequestPointCode == handoverRequestPointCode) {
				ret := ExpectTable[i].vc_conn;
				log("Found Expect[", i, "] for handoverRequest handled at ", ret);
				return ret;
			} else {
				continue;
			}
		}
		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;
}
#endif

#ifdef RAN_EMULATION_RANAP
/* CreateCallback that can be used as create_cb and will use the expectation table */
function RanapExpectedCreateCallback(RANAP_N_CONNECT_ind conn_ind, charstring id)
runs on RAN_Emulation_CT return RAN_ConnHdlr {
	var RAN_ConnHdlr ret := null;
	var template (omit) octetstring l3_info;
	var integer i;

	l3_info := f_ranap_extract_l3(conn_ind.userData);
	if (istemplatekind(l3_info, "omit")) {
		setverdict(fail, "N-CONNECT.ind without NAS payload");
		mtc.stop;
		return ret;
	}

	for (i := 0; i < sizeof(ExpectTable); i:= i+1) {
		if (not ispresent(ExpectTable[i].l3_payload)) {
			continue;
		}
		if (valueof(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;
}
#endif

private function f_create_expect(template octetstring l3, RAN_ConnHdlr hdlr,
				 template integer handoverRequestPointCode := omit)
runs on RAN_Emulation_CT {
	var integer i;
	log("f_create_expect(l3 := ", l3, ", handoverRequest := ", handoverRequestPointCode);
	for (i := 0; i < sizeof(ExpectTable); i := i+1) {
		if (not ispresent(ExpectTable[i].l3_payload)
		    and not ispresent(ExpectTable[i].handoverRequestPointCode)) {
			if (ispresent(l3)) {
				ExpectTable[i].l3_payload := valueof(l3);
			}
			if (ispresent(handoverRequestPointCode)) {
				ExpectTable[i].handoverRequestPointCode := valueof(handoverRequestPointCode);
			}
			ExpectTable[i].vc_conn := hdlr;
			if (ispresent(handoverRequestPointCode)) {
				log("Created Expect[", i, "] for handoverRequest to be handled at ", hdlr);
			} else {
				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, RAN_ConnHdlr hdlr)
runs on RAN_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 RAN_Emulation_CT {
	for (var integer i := 0; i < sizeof(ExpectTable); i := i+1) {
		ExpectTable[i].l3_payload := omit;
		ExpectTable[i].handoverRequestPointCode := omit;
	}
}

/* helper function for clients to register their IMSI/TMSI */
function f_ran_register_imsi(hexstring imsi, OCT4 tmsi)
runs on RAN_ConnHdlr {
	BSSAP_PROC.call(RAN_register_imsi:{imsi, tmsi, self}) {
		[] BSSAP_PROC.getreply(RAN_register_imsi:{?,?,?}) {};
	}
}

#ifdef RAN_EMULATION_RANAP
/* expect a IuReleaseCommand; Confirm that; expect SCCP-level N-DISCONNET.ind */
altstep as_iu_release_compl_disc(float t := 5.0) runs on RAN_ConnHdlr {
	var RANAP_PDU ranap;
	[] BSSAP.receive(tr_RANAP_IuReleaseCommand(?)) {
		BSSAP.send(ts_RANAP_IuReleaseComplete);
		alt {
		[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(pass);
			}
		[] BSSAP.receive {
			setverdict(fail, "Unexpected RANAP while waiting for SCCP Release ");
			mtc.stop;
			}
		}
		}
	[] BSSAP.receive(RANAP_PDU:?) -> value ranap{
		setverdict(fail, "Unexpected RANAP while waiting for IuReleaseCommand", ranap);
		mtc.stop;
		}
}
#endif


}
