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
}

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

private function f_bssap_wait_for_reset() runs on RAN_Emulation_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	timer T := 20.0;
	var boolean append_osmux_support := append_osmux_ie();

	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(append_osmux_support))) -> value ud_ind {
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck(append_osmux_support)));
		}
	[] as_reset_ack(append_osmux_support);
	[] 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;
	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("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, "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,
	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);

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(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("Respoding 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("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
}

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(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) -> value evt {
				CTRL_CLIENT.send(evt);
		}
		[] CTRL.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_DOWN}) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Lost IPA connection!");
		}
		[] CTRL.receive(ASP_IPA_Event:{up_down := 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 RANAP_PDU ranap;
		/* FIXME: convert DLCI into SAPI */
		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();
		[] 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;
		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


}
