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;
import from Misc_Helpers 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_CTRL
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter 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
}

type enumerated RAN_Transport {
	BSSAP_TRANSPORT_AoIP,	/* 3GPP AoIP: SCCP over M3UA over SCTP */
	BSSAP_TRANSPORT_SCCPlite_SERVER, /* SCCPlite: SCCP over IPA over TCP */
	BSSAP_TRANSPORT_SCCPlite_CLIENT, /* SCCPlite: SCCP over IPA over TCP */
	RANAP_TRANSPORT_IuCS	/* 3GPP IuCS: SCCP over M3UA over SCTP */
};

/* 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
}

type record PDU_DTAP_PS_MO {
	OCT1			dlci optional,
	boolean			skip_seq_patching optional,
	PDU_L3_MS_SGSN          dtap
}

type record PDU_DTAP_PS_MT {
	OCT1			dlci optional,
	PDU_L3_SGSN_MS          dtap
}

template PDU_DTAP_MT ts_PDU_DTAP_MT(template PDU_ML3_NW_MS dtap, template OCT1 dlci := omit) := {
	dlci := dlci,
	dtap := dtap
}

template PDU_DTAP_MO ts_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 dlci := '00'O, boolean skip_seq_patching := false) := {
	dlci := dlci,
	skip_seq_patching := skip_seq_patching,
	dtap := dtap
}

template PDU_DTAP_MT tr_PDU_DTAP_MT(template PDU_ML3_NW_MS dtap, template OCT1 dlci := *) := {
	dlci := dlci,
	dtap := dtap
}

template PDU_DTAP_MO tr_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 dlci := *) := {
	dlci := dlci,
	skip_seq_patching := ?,
	dtap := dtap
}

template (value) PDU_DTAP_PS_MT ts_PDU_DTAP_PS_MT(template (value) PDU_L3_SGSN_MS dtap, template (omit) OCT1 dlci := omit) := {
	dlci := dlci,
	dtap := dtap
}

template (value) PDU_DTAP_PS_MO ts_PDU_DTAP_PS_MO(template (value) PDU_L3_MS_SGSN dtap, template (value) OCT1 dlci := '00'O,
						  boolean skip_seq_patching := false) := {
	dlci := dlci,
	skip_seq_patching := skip_seq_patching,
	dtap := dtap
}

template PDU_DTAP_PS_MT tr_PDU_DTAP_PS_MT(template PDU_L3_SGSN_MS dtap, template OCT1 dlci := *) := {
	dlci := dlci,
	dtap := dtap
}

template PDU_DTAP_PS_MO tr_PDU_DTAP_PS_MO(template PDU_L3_MS_SGSN 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,
		BSSAP_N_UNITDATA_req,
		/* 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,
		PDU_DTAP_PS_MO, PDU_DTAP_PS_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
#ifdef RAN_EMULATION_CTRL
	/* CTRL port */
	port IPA_CTRL_PT CTRL;
	port IPA_CTRL_PT CTRL_CLIENT;
#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 := f_bssmap_ie_cic_2_int(cic_ie);
			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;

private function append_osmux_ie()
runs on RAN_Emulation_CT return boolean {
	return g_ran_ops.use_osmux and (g_ran_ops.transport == BSSAP_TRANSPORT_AoIP);
}

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

function f_bssap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on RAN_Emulation_CT {
	timer T := 5.0;
	var boolean append_osmux_support := append_osmux_ie();

	BSSAP.send(ts_BSSAP_UNITDATA_req(peer, own, ts_BSSMAP_Reset(0, append_osmux_support)));
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(own, peer, tr_BSSMAP_ResetAck(append_osmux_support))) {
		log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
		}
	[] as_reset_ack(append_osmux_support);
	[] BSSAP.receive { repeat };
	[] T.timeout {
		setverdict(fail, "BSSMAP: 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 */
			if (g_ran_ops.ps_domain) {
				var PDU_DTAP_PS_MT mt := {
					dlci := omit,
					dtap := dec_PDU_L3_SGSN_MS(valueof(l3))
				};
				if (isvalue(dlci)) {
					mt.dlci := valueof(dlci);
				}
				CLIENT.send(mt) to client;
			} else {
				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 */
			if (g_ran_ops.ps_domain) {
				var PDU_DTAP_PS_MO mo := {
					dlci := omit,
					dtap := dec_PDU_L3_MS_SGSN(valueof(l3))
				};
				if (isvalue(dlci)) {
					mo.dlci := valueof(dlci);
				}
				CLIENT.send(mo) to client;
			} else {
				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("RANAP: Received RESET-ACK in response to RESET, we're ready to go!");
		}
	[] as_reset_ack();
	[] RANAP.receive { repeat };
	[] T.timeout {
		setverdict(fail, "RANAP: 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,
	RAN_Transport transport,
	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);

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 */
private 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(boolean append_osmux_support := false) 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(append_osmux_support))) -> value ud_ind {
		log("BSSMAP: Responding to inbound RESET with RESET-ACK");
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck(append_osmux_support)));
		repeat;
	}
#endif
#ifdef RAN_EMULATION_RANAP
	[] RANAP.receive(tr_RANAP_UNITDATA_ind(?, ?, tr_RANAP_Reset)) -> value rud_ind {
		log("RANAP: Responding 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 BSSAP_N_UNITDATA_req bssap_ud;
		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));
			}

		[] CLIENT.receive(BSSAP_N_UNITDATA_req:?) -> value bssap_ud sender vc_conn {
			BSSAP.send(bssap_ud);
			}

		/* 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;
		var PDU_DTAP_PS_MO ps_mo;
		var PDU_DTAP_PS_MT ps_mt;

		/* 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");
			}
			}

		[g_ran_ops.role_ms] CLIENT.receive(PDU_DTAP_PS_MO:?) -> value ps_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_L3_MS_SGSN(ps_mo.dtap);
			/* patch correct L3 send sequence number N(SD) into l3_enc */
			if (ps_mo.skip_seq_patching == false) {
				//f_ML3_patch_seq(ConnectionTable[idx], ps_mo.dtap, l3_enc);
			}
			f_xmit_raw_l3(ConnectionTable[idx].sccp_conn_id, ps_mo.dlci, l3_enc);
			}

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


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

private altstep as_main_ctrl() runs on RAN_Emulation_CT {
#ifdef RAN_EMULATION_CTRL
		var CtrlMessage ctrl;
		var RAN_ConnHdlr vc_conn;
		var ASP_IPA_Event evt;

		/* Handling of CTRL in IPA SCCPLite case.  This predates 3GPP AoIP
		 * and uses a CTRL session in parallel to BSSAP. */

		/* CTRL_CLIENT -> CTRL */
		[] CTRL_CLIENT.receive(CtrlMessage:?) -> value ctrl sender vc_conn {
			CTRL.send(ctrl);
		}

		/*  CTRL -> CTRL_CLIENT */
		[] CTRL.receive(CtrlMessage:?) -> value ctrl {
			CTRL_CLIENT.send(ctrl);
		}

		[] CTRL.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) -> value evt {
				CTRL_CLIENT.send(evt);
		}
		[] CTRL.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Lost IPA connection!");
		}
		[] CTRL.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {}
#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 template (omit) RANAP_IEs.SAPI sapi := omit;
		var RANAP_PDU ranap;

		/* Perform DLCI -> SAPI transformation (x & 0x07) */
		if (dlci and4b '07'O == '03'O) {
			sapi := sapi_3;
		}

		ranap := valueof(ts_RANAP_DirectTransfer(l3_enc, sapi := sapi));
		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();
		[] as_main_ctrl();

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

	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;
}
#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, template (omit) OCT4 tmsi_or_omit)
runs on RAN_ConnHdlr {
	var OCT4 tmsi;

	/* Resolve omit to a special reserved value */
	if (istemplatekind(tmsi_or_omit, "omit")) {
		tmsi := 'FFFFFFFF'O;
	} else {
		tmsi := valueof(tmsi_or_omit);
	}

	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


}
