module HNBGW_Tests {

/* Integration Tests for OsmoHNBGW
 * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite tests OsmoHNBGW while emulating the hNodeB as well as MSC, SGSN, MGW
 * See README for more details.
 */

import from Misc_Helpers all;
import from General_Types all;
import from GSM_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from Native_Functions all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from StatsD_Types all;
import from StatsD_CodecPort all;
import from StatsD_CodecPort_CtrlFunct all;
import from StatsD_Checker all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

import from HNBAP_Templates all;
import from HNBAP_PDU_Descriptions all;

import from RUA_IEs all;
import from RUA_Templates all;
import from RUA_Emulation all;

import from Iuh_Emulation all;

import from RANAP_Types all;
import from RANAP_PDU_Descriptions all;
import from RANAP_PDU_Contents all;
import from RANAP_IEs all;
import from RANAP_Templates all;
import from RANAP_CodecPort all;

import from RAN_Adapter all;
import from RAN_Emulation all;

import from MGCP_Emulation all;
import from MGCP_Types all;
import from MGCP_Templates all;
import from MGCP_CodecPort all;
import from SDP_Types all;

import from PFCP_Types all;
import from PFCP_Emulation all;
import from PFCP_Templates all;
import from PFCP_CodecPort all;

import from TCCConversion_Functions all;
import from MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from MobileL3_GMM_SM_Types all;
import from L3_Templates all;
import from L3_Common all;

import from SCCPasp_Types all;

const integer NUM_MSC := 4;
const integer NUM_SGSN := 4;

const integer FIRST_MSC_IDX := 0;
const integer FIRST_SGSN_IDX := NUM_MSC;

modulepar {
	/* IP address at which the HNodeB can be reached */
	charstring mp_hnodeb_ip := "127.0.0.1";
	integer mp_hnodeb_port := -1;

	/* IP address at which the test binds */
	charstring mp_hnbgw_ip := "127.0.0.1";
	integer mp_hnbgw_iuh_port := 29169;
	integer mp_hnbgw_ctrl_port := 4262;

	charstring mp_mgw_ip := "127.0.0.1";
	integer mp_mgw_port := 2427;

	RAN_Configurations mp_cn_cfg := {
		/* MSCs (NUM_MSC entries) */
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
			own_pc := 188,	/* 0.23.4 first MSC emulation */
			own_ssn := 142,
			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 1
		},
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
			own_pc := 2,	/* 0.0.2 second MSC emulation */
			own_ssn := 142,
			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 3
		},
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { 23909, "127.0.0.1", 2905, "127.0.0.1" },
			own_pc := 3,	/* 0.0.3 third MSC emulation */
			own_ssn := 142,
			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 5
		},
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { 23911, "127.0.0.1", 2905, "127.0.0.1" },
			own_pc := 4,	/* 0.0.4 fourth MSC emulation */
			own_ssn := 142,
			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 7
		},

		/* SGSNs (NUM_SGSN entries) */
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { /* local */ 23906, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
			own_pc := 185,	/* 0.23.1 first SGSN emulation */
			own_ssn := 142,
			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 2
		},
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { /* local */ 23908, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
			own_pc := 10,	/* 0.1.2 second SGSN emulation */
			own_ssn := 142,
			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 4
		},
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { /* local */ 23910, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
			own_pc := 11,	/* 0.1.3 third SGSN emulation */
			own_ssn := 142,
			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 6
		},
		{
			transport := RANAP_TRANSPORT_IuCS,
			sccp_service_type := "mtp3_itu",
			sctp_addr := { /* local */ 23912, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
			own_pc := 12,	/* 0.1.4 fourth SGSN emulation */
			own_ssn := 142,
			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
			peer_ssn := 142,
			sio := '83'O,
			rctx := 8
		}
	};

	boolean mp_enable_pfcp_tests := false;

	/* IP address at which we listen for PFCP to emulate a UPF in ttcn3 */
	charstring mp_pfcp_ip_local := "127.0.0.1";

	/* IP address from which the SUT (osmo-hnbgw) sends PFCP requests, and to which the ttcn3 UPF emulation sends
	 * PFCP responses. */
	charstring mp_pfcp_ip_remote := "127.0.0.2";

	boolean mp_validate_talloc_asn1 := true;

	/* The X31 timer configured at osmo-hnbgw (seconds). This provided an idea on
	 * minimum time the test must wait to consider this timer triggered */
	integer mp_hnbgw_timer_x31 := 5;
}

function MSC_UnitdataCallback(RANAP_PDU ranap) runs on RAN_Emulation_CT return template RANAP_PDU {
	// TODO: Actually implement unitdata handling
	return omit;
}

const RanOps MSC_RanOps := {
	ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
	ranap_unitdata_cb := refers(MSC_UnitdataCallback),
	ps_domain := false,
	decode_dtap := false,
	role_ms := false,
	protocol := RAN_PROTOCOL_RANAP,
	transport := RANAP_TRANSPORT_IuCS,
	use_osmux := false,
	bssap_reset_retries := 1,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
}

type record MgwResponse {
	integer resp,
	HostName mgw_rtp_ip,
	/* if set, used after first received MDCX: */
	HostName mgw_rtp_ip_mdcx optional,
	PortNumber mgw_rtp_port,
	MgcpConnectionId mgcp_connection_id
}
type record MgcpParameters {
	integer got_crcx_count,
	integer got_dlcx_count,
	MgcpCallId mgcp_call_id optional,
	MgcpEndpoint mgcp_ep,
	MgwResponse mgw_conn_ran,
	MgwResponse mgw_conn_cn,
	uint7_t rtp_payload_type,
	charstring rtp_sdp_format,
	HostName hnb_rtp_ip,
	PortNumber hnb_rtp_port,
	HostName cn_rtp_ip,
	PortNumber cn_rtp_port,
	boolean use_osmux,
	integer got_osmux_count
}

template (value) MgcpParameters t_MgcpParams := {
	got_crcx_count := 0,
	got_dlcx_count := 0,
	mgcp_call_id := omit,
	mgcp_ep := "rtpbridge/1@mgw",
	mgw_conn_ran := {
		resp := 1,
		mgw_rtp_ip := "127.1.2.1",
		mgw_rtp_ip_mdcx := omit,
		mgw_rtp_port := 10000,
		mgcp_connection_id := '11111'H
	},
	mgw_conn_cn := {
		resp := 1,
		mgw_rtp_ip := "127.1.2.2",
		mgw_rtp_ip_mdcx := omit,
		mgw_rtp_port := 20000,
		mgcp_connection_id := '22222'H
	},
	rtp_payload_type := 112,
	rtp_sdp_format := "VND.3GPP.IUFP",
	hnb_rtp_ip := "127.1.1.1",
	hnb_rtp_port := 10001,
	cn_rtp_ip := "127.1.3.1",
	cn_rtp_port := 20001,
	use_osmux := false,
	got_osmux_count := 0
}

type record TestHdlrParams {
	integer hnb_idx,
	/* cn_idx indicates which CN link from g_cn[] to connect to the test component.
	 * See also f_cn_idx(). */
	integer cn_idx,
	hexstring imsi,
	boolean ps_domain,
	MgcpParameters mgcp_pars optional,
	HnbConfig hnb optional,
	boolean expect_separate_sccp_cr,
	integer tx_sccp_cr_data_len,
	charstring pfcp_local_addr,
	octetstring nas_pdu optional,
	/* local and remote SCCP addresses, used in TC_mscpool_paging_* */
	SCCP_PAR_Address sccp_addr_msc optional,
	SCCP_PAR_Address sccp_addr_hnbgw optional
}

/* We extend:
   * RUA_ConnHdlr (for the Iuh side, emulating the HNB)
   * RAN_ConnHdlr (for the Iu side, emulating the MSC)
   * MGCP_ConnHdlr (for the MGCP side, emulating the MGW)
 */
type component ConnHdlr extends RAN_ConnHdlr, MGCP_ConnHdlr, RUA_ConnHdlr, PFCP_ConnHdlr {
	var integer g_sccp_conn_id;
	var TestHdlrParams g_pars;
	timer g_Tguard;

	port TELNETasp_PT HNBGWVTY;
}


const MGCPOps MSC_MGCPOps := {
	create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
}

function f_create_ranap_exp(octetstring l3_enc) runs on ConnHdlr {
	BSSAP_PROC.call(RAN_register:{l3_enc, self}) {
		[] BSSAP_PROC.getreply(RAN_register:{?, ?}) {};
	}
}


const integer NUM_HNB := 2;

type record HnbConfig {
	LocationAreaIdentification lai,
	integer sac
}

type component test_CT extends CTRL_Adapter_CT {
	var boolean g_initialized := false;

	/********************* Iu side */
	var RAN_Adapter g_cn[NUM_MSC + NUM_SGSN];

	/********************* Iuh side */
	var HnbConfig g_hnb_cfg[NUM_HNB];
	var Iuh_Emulation_CT vc_Iuh[NUM_HNB];
	var RUA_Emulation_CT vc_RUA[NUM_HNB];
	port HNBAP_PT HNBAP[NUM_HNB];
	/* Number of HNBs to be used/started by the test */
	var integer g_num_hnbs := NUM_HNB;

	var MGCP_Emulation_CT vc_MGCP;
	port TELNETasp_PT HNBGWVTY;
	/* global test case guard timer (actual timeout value is set in f_init()) */
	timer T_guard := 30.0;

	/* The cnlink type 'msc' or 'sgsn', to be used in CTRL commands to obtain counters */
	var charstring g_ctr_cn_node_name;
	/* Counter state */
	var CounterNameValsList g_ctr_cn;
}

/* global altstep for global guard timer; */
altstep as_Tguard() runs on test_CT {
	[] T_guard.timeout {
			setverdict(fail, "Timeout of T_guard");
			mtc.stop;
		}
}

function f_init_vty(charstring id := "foo") runs on test_CT {
	if (HNBGWVTY.checkstate("Mapped")) {
		/* skip initialization if already executed once */
		return;
	}
	map(self:HNBGWVTY, system:HNBGWVTY);
	f_vty_set_prompts(HNBGWVTY);
	f_vty_transceive(HNBGWVTY, "enable");
}

function f_init_mgcp(charstring id) runs on test_CT {
	id := id & "-MGCP";
	var MGCPOps ops := {
		create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
	}
	var MGCP_conn_parameters pars := {
		callagent_ip := mp_hnbgw_ip,
		callagent_udp_port := -1,
		mgw_ip := mp_mgw_ip,
		mgw_udp_port := mp_mgw_port,
		multi_conn_mode := false
	}

	vc_MGCP := MGCP_Emulation_CT.create(id);
	map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
	vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
}

function f_init_pfcp(charstring id) runs on ConnHdlr {
	id := id & "-PFCP";

	var PFCP_Emulation_Cfg pfcp_cfg := {
		pfcp_bind_ip := mp_pfcp_ip_local,
		pfcp_bind_port := PFCP_PORT,
		pfcp_remote_ip := mp_pfcp_ip_remote,
		pfcp_remote_port := PFCP_PORT,
		role := UPF
	};

	vc_PFCP := PFCP_Emulation_CT.create(id) alive;
	connect(self:PFCP, vc_PFCP:CLIENT);
	connect(self:PFCP_PROC, vc_PFCP:CLIENT_PROC);
	vc_PFCP.start(PFCP_Emulation.main(pfcp_cfg));
}

function f_init_hnodeb(charstring id, integer hnb_idx, RuaOps rua_ops) runs on test_CT {
	id := id & "-Iuh" & int2str(hnb_idx);

	/* Iuh lower layer (RUA/HNBAP demux) */
	var Iuh_conn_parameters iuh_pars;
	iuh_pars.remote_ip := mp_hnbgw_ip;
	iuh_pars.remote_sctp_port := mp_hnbgw_iuh_port;
	iuh_pars.local_ip := mp_hnodeb_ip;
	iuh_pars.local_sctp_port := mp_hnodeb_port + hnb_idx;
	vc_Iuh[hnb_idx] := Iuh_Emulation_CT.create(id);
	connect(self:HNBAP[hnb_idx], vc_Iuh[hnb_idx]:HNBAP);

	vc_RUA[hnb_idx] := RUA_Emulation_CT.create(id & "-RUA");
	connect(vc_RUA[hnb_idx]:RUA, vc_Iuh[hnb_idx]:RUA);

	/* Start Iuh side components */
	vc_Iuh[hnb_idx].start(Iuh_Emulation.main(iuh_pars, id));
	vc_RUA[hnb_idx].start(RUA_Emulation.main(rua_ops, id & "-RUA"));
}

private type record of boolean BooleanList;

private function f_vty_cnlink_allow_attach(TELNETasp_PT pt, boolean ps_domain, BooleanList allow_attach_list)
{
	var charstring config := f_vty_transceive_ret(pt, "show running-config");

	var charstring msc_sgsn;
	if (ps_domain) {
		msc_sgsn := "sgsn";
	} else {
		msc_sgsn := "msc";
	}

	f_vty_enter_config(pt);
	for (var integer cn_nr := 0; cn_nr < sizeof(allow_attach_list); cn_nr := cn_nr+1) {
		if (f_strstr(config, "\n" & msc_sgsn & " " & int2str(cn_nr) & "\n") < 0) {
			/* There is no 'msc N' for this cn_nr in the running config, so don't create an empty cn by
			 * stepping into that config node. */
			log(msc_sgsn, cn_nr, " is not configured, skipping");
			continue;
		}
		f_vty_transceive(pt, msc_sgsn & " " & int2str(cn_nr));

		if (allow_attach_list[cn_nr]) {
			/* strict := false: ignore if osmo-hnbgw does not support this config option (latest build) */
			f_vty_transceive(pt, "allow-attach", strict := false);
		} else {
			f_vty_transceive(pt, "no allow-attach", strict := false);
		}
		f_vty_transceive(pt, "exit");
	}
	f_vty_transceive(pt, "exit");
}

/* Start RAN adapter for CN link N.
 * e.g. link for 'msc 0' = (ps_domain := false, cn_nr := 0)
 * link for 'sgsn 3' = (ps_domain := true, cn_nr := 3)
 */
private function f_cn_nr_init(boolean ps_domain, integer cn_nr) runs on test_CT {
	var RanOps ranops := MSC_RanOps;
	ranops.ps_domain := ps_domain;
	var integer cn_idx := f_cn_idx(ps_domain, cn_nr);
	var charstring msc_sgsn := "msc";
	if (ps_domain) {
		msc_sgsn := "sgsn";
	}
	f_ran_adapter_init(g_cn[cn_idx], mp_cn_cfg[cn_idx], "HNBGW_Test." & msc_sgsn & int2str(cn_nr), ranops);
	f_ran_adapter_start(g_cn[cn_idx]);
}

private function f_cn_idx_disconnect(integer cn_idx) runs on test_CT {
	f_ran_adapter_cleanup(g_cn[cn_idx]);
}

/* global initialization function */
function f_init(charstring id := "HNBGW", float guard_timeout := 30.0, integer nr_msc := 1, integer nr_sgsn := 1,
		boolean start_hnb := true) runs on test_CT {

	T_guard.start(guard_timeout);
	activate(as_Tguard());

	/* RUA/RANAP emulation on top of lower-layer Iuh */
	var RuaOps rua_ops := {
		create_cb := refers(IuhRanapCreateCallback),
		unitdata_cb := refers(IuhRanapUnitdataCallback)
	};
	for (var integer i := 0; i < g_num_hnbs; i := i+1) {
		g_hnb_cfg[i] := {
			lai := {
				mcc_mnc := '00F110'H,
				lac := 2342 + i
			},
			sac := 55
		};
		f_init_hnodeb(testcasename(), i, rua_ops);
	}

	f_init_vty("VirtHNBGW");
	f_ipa_ctrl_start_client(mp_hnbgw_ip, mp_hnbgw_ctrl_port);

	/* MSC emulation */

	/* Make sure each MSC's internal state is "DISCONNECTED" at first */
	for (var integer i := 0; i < NUM_MSC; i := i + 1) {
		f_vty_transceive(HNBGWVTY, "msc " & int2str(i) & " ranap reset", strict := false);
	}

	var BooleanList allow_attach := { false, false, false, false };
	for (var integer i := 0; i < nr_msc; i := i + 1) {
		var integer cn_idx := FIRST_MSC_IDX + i;
		allow_attach[i] := true;
		f_cn_nr_init(ps_domain := false, cn_nr := i);
	}
	/* start the test with exactly all enabled MSCs allowed to attach */
	f_vty_cnlink_allow_attach(HNBGWVTY, false, allow_attach);

	/* SGSN emulation */

	/* Make sure each SGSN's internal state is "DISCONNECTED" at first */
	for (var integer i := 0; i < NUM_SGSN; i := i + 1) {
		f_vty_transceive(HNBGWVTY, "sgsn " & int2str(i) & " ranap reset", strict := false);
	}

	allow_attach := { false, false, false, false };
	for (var integer i := 0; i < nr_sgsn; i := i + 1) {
		var integer cn_idx := FIRST_SGSN_IDX + i;
		allow_attach[i] := true;
		f_cn_nr_init(ps_domain := true, cn_nr := i);
	}
	f_vty_cnlink_allow_attach(HNBGWVTY, true, allow_attach);

	f_init_mgcp(id);

	if (start_hnb) {
		f_start_hnbs();
	}

	/* Sometimes, the RUA InitialUE-Message from a test happens too quickly, before the RANAP RESET from
	 * RAN_Emulation is through, after above f_cn_nr_init(). In the pcap it seems to be a matter of 50 ms. Give some
	 * grace. */
	 f_sleep(1.0);
}

friend function f_shutdown_helper() runs on test_CT {
	if (mp_validate_talloc_asn1) {
		f_verify_talloc_bytes(HNBGWVTY, {"asn1_context"}, 1);
	}

	all component.stop;
	setverdict(pass);
	mtc.stop;
}

/* helper function to start all of the simulated hNodeBs */
function f_start_hnbs() runs on test_CT {
	for (var integer i:= 0; i < g_num_hnbs; i := i+1) {
		f_hnbap_register(i, i);
	}
}

/***********************************************************************
 * code running in test_CT, preparing start of per-UE ConnHdlr
 ***********************************************************************/

/* inbound RUA connection establishment on Iuh side */
function IuhRanapCreateCallback(ContextId context_id, RUA_IEs.CN_DomainIndicator domain, charstring id)
runs on RUA_Emulation_CT return RUA_ConnHdlr {
	log("CreateCallback");
	return null;
}

/* inbound RUA connectionless data on Iuh side */
function IuhRanapUnitdataCallback(RANAP_PDU ranap)
runs on RUA_Emulation_CT return template RANAP_PDU {
	log("UnitdataCallback");
	return omit;
}

private function f_start_handler_create(TestHdlrParams pars) runs on test_CT return ConnHdlr {
	var ConnHdlr vc_conn;
	var charstring id := testcasename() & int2str(pars.hnb_idx);

	vc_conn := ConnHdlr.create(id);

	/* Iuh RUA part */
	connect(vc_conn:RUA, vc_RUA[pars.hnb_idx]:CLIENT);

	/* MSC or SGSN */
	connect(vc_conn:BSSAP, g_cn[pars.cn_idx].vc_RAN:CLIENT);
	connect(vc_conn:BSSAP_PROC, g_cn[pars.cn_idx].vc_RAN:PROC);

	/* MGCP part */
	connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
	connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);

	return vc_conn;
}

private function f_start_handler_run(ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars) runs on test_CT {
	var charstring id := testcasename(); // & int2str(pars.ran_idx);
	/* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
	 *  a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
	pars.hnb := g_hnb_cfg[pars.hnb_idx];
	vc_conn.start(derefers(fn)(id, pars));
}

function f_start_handler_with_pars(void_fn fn, template (value) TestHdlrParams pars)
runs on test_CT return ConnHdlr {
	var ConnHdlr vc_conn;
	vc_conn := f_start_handler_create(valueof(pars));
	f_start_handler_run(vc_conn, fn, valueof(pars));
	return vc_conn;
}

/***********************************************************************
 * code running inside per-UE ConnHdlr
 ***********************************************************************/

type function void_fn(charstring id, TestHdlrParams pars) runs on ConnHdlr;

function f_init_handler(TestHdlrParams pars, float t_guard := 20.0) runs on ConnHdlr {
	/* make parameters available via component variable */
	g_pars := pars;

	f_init_pfcp(testcasename());

	/* start guard timer and activate it as default */
	g_Tguard.start(t_guard);
	activate(as_Tguard_ConnHdlr());

	map(self:HNBGWVTY, system:HNBGWVTY);
	f_vty_set_prompts(HNBGWVTY);
	f_vty_transceive(HNBGWVTY, "enable");

	/* TODO: CTRL? */

	f_sleep(1.0);
}

/* global altstep for global guard timer; */
private altstep as_Tguard_ConnHdlr() runs on ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Timeout of T_guard");
		mtc.stop;
	}
}

private function f_bssap_expect(template (present) RANAP_PDU exp_rx) runs on ConnHdlr return RANAP_PDU
{
	var RANAP_PDU rx;
	timer T := 5.0;
	T.start;
	alt {
	[] BSSAP.receive(exp_rx) -> value rx {
		setverdict(pass);
		}
	[] BSSAP.receive(RANAP_PDU:?) {
		setverdict(fail, "Got an unexpected RANAP message on BSSAP port, was waiting for ", exp_rx);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RANAP on BSSAP port: ", exp_rx);
		mtc.stop;
		}
	}
	T.stop;
	return rx;
}

/* send RANAP on Iuh and expect it to show up on Iu */
function f_iuh2iu(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
runs on ConnHdlr return RANAP_PDU {
	var RANAP_PDU rx;
	timer T := 5.0;

	if (istemplatekind(exp_rx, "omit")) {
		exp_rx := tx;
	}

	RUA.send(tx);

	return f_bssap_expect(exp_rx);
}

/* send RANAP on Iu and expect it to show up on Iuh */
function f_iu2iuh(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
runs on ConnHdlr return RANAP_PDU {
	if (istemplatekind(exp_rx, "omit")) {
		exp_rx := tx;
	}

	BSSAP.send(tx);

	return f_rua_expect(exp_rx)
}

/* expect to receive a specific RUA message on Iuh */
private function f_rua_expect(template (present) RANAP_PDU exp_rx) runs on ConnHdlr return RANAP_PDU
{
	var RANAP_PDU rx;
	timer T := 5.0;
	T.start;
	alt {
	[] RUA.receive(exp_rx) -> value rx {
		setverdict(pass);
		}
	[] RUA.receive(RANAP_PDU:?) {
		setverdict(fail, "Got an unexpected RUA message, was waiting for ", exp_rx);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iuh ", exp_rx);
		mtc.stop;
		}
	}
	T.stop;
	return rx;
}

/* send RANAP on Iuh and expect it to show up on Iu */
function f_iuh2iu_connect(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
runs on ConnHdlr return RANAP_PDU {
	var RANAP_PDU rx;
	timer T := 5.0;

	if (istemplatekind(exp_rx, "omit")) {
		exp_rx := tx;
	}

	/* create an expect on the Iu side for the random NAS portion */
	if (g_pars.expect_separate_sccp_cr) {
		f_ran_register_sccp_cr_without_payload();
	} else {
		var template (omit) octetstring nas := f_ranap_extract_l3(valueof(tx));
		f_ran_register_exp(valueof(nas));
	}

	/* send it via Iuh (creating a RUA connection) */
	RUA.send(RUA_Conn_Req:{g_pars.ps_domain, tx});

	if (g_pars.expect_separate_sccp_cr) {
		/* Acknowledge the empty SCCP CR. RAN_Emulation does the confirmation, no need to respond. */
		BSSAP.receive(tr_RANAP_Conn_Req());
	}

	/* expect to receive it on the Iu side */
	return f_bssap_expect(exp_rx);
}

/* 3GPP TS 48.006 9.2 Connection release:
 *
 *  The MSC sends a SCCP released message. This message shall not contain
 *  any user data field.
 *
 * So what we expect normally is:
 *
 *                            HNBGW                    MSC
 *  RUA --id-Disconnect-------> | ---Data-Form-1(!)---> |  Iu-ReleaseComplete
 *                              | <--Released---------- |  (no data)
 *
 * This function tests osmo-hnbgw behavior if the CN fails to send a RLSD:
 * after some timeout, osmo-hnbgw should send a RLSD to the CN.
 */
function f_iuh2iu_disconnect(template (present) RANAP_PDU tx, RUA_IEs.Cause cause,
			     template RANAP_PDU exp_rx := omit)
runs on ConnHdlr return RANAP_PDU {
	var RANAP_PDU rx
	timer T := int2float(mp_hnbgw_timer_x31) + 1.0;

	if (istemplatekind(exp_rx, "omit")) {
		exp_rx := tx;
	}

	/* send it via Iuh (creating a RUA connection) */
	RUA.send(RUA_Disc_Req:{tx, cause});

	/* expect to receive it on the Iu side */
	rx := f_bssap_expect(exp_rx);

	/* expect disconnect on the Iu side */
	T.start;
	alt {
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iu disconnect");
		return rx;
		}

	}
	return rx;
}

private function f_build_initial_ue_with_nas(TestHdlrParams pars, octetstring nas)
  return RANAP_PDU {
	var LAI lai := {
		pLMNidentity := hex2oct(pars.hnb.lai.mcc_mnc),
		lAC := int2oct(pars.hnb.lai.lac, 2),
		iE_Extensions := omit
	};
	var SAI sai := {
		pLMNidentity := lai.pLMNidentity,
		lAC := lai.lAC,
		sAC := int2oct(pars.hnb.sac, 2),
		iE_Extensions := omit
	}
	var IuSignallingConnectionIdentifier sigc_id := int2bit(f_rnd_int(1000), 24);
	var GlobalRNC_ID grnc_id := {
		pLMNidentity := lai.pLMNidentity,
		rNC_ID := 2342
	}
	var template RANAP_PDU ret;
	if (pars.ps_domain) {
		var RAC rac := '00'O;
		ret := ts_RANAP_initialUE_PS(lai, rac, sai, nas, sigc_id, grnc_id);
	} else {
		ret := ts_RANAP_initialUE_CS(lai, sai, nas, sigc_id, grnc_id);
	}
	return valueof(ret);
}

/* build a RANAP InitialUE based on the TestHdlrParams */
friend function f_build_initial_ue(TestHdlrParams pars) return RANAP_PDU {

	var octetstring nas;

	if (pars.tx_sccp_cr_data_len == 0) {
		nas := f_rnd_octstring(10);
	} else {
		/* The test asks for an exact number of Optional Data bytes. */

		/* First see what size the RANAP part of the payload data is,
		 * to adjust the NAS PDU size to the size requested by the test (pars.tx_sccp_cr_data_len). */
		var RANAP_PDU initial_ue := f_build_initial_ue_with_nas(pars, '00'O);

		var octetstring ranap_plus_one_byte_nas := enc_RANAP_PDU(initial_ue);
		var integer ranap_length := lengthof(ranap_plus_one_byte_nas) - 1;

		log("ranap_plus_one_byte_nas = ", lengthof(ranap_plus_one_byte_nas), " bytes, ", initial_ue, " = ",
		    ranap_plus_one_byte_nas);
		log("ranap_length = ", ranap_length);

		/* SCCP CR has a payload length limit of 130 bytes. To trigger this limit, the RANAP + NAS PDU has to be
		 * > 130 bytes. It doesn't need to be 131 bytes in the NAS PDU alone, but let's just make it definitely
		 * large enough. To test for this limit, pars.tx_sccp_cr_data_len asks for a specific amount of data len. */
		nas := f_rnd_octstring(pars.tx_sccp_cr_data_len - ranap_length);
	}

	var RANAP_PDU ret := f_build_initial_ue_with_nas(pars, nas);

	if (pars.tx_sccp_cr_data_len != 0) {
		for (var integer attempts := 0; attempts < 2; attempts := attempts + 1) {
			var octetstring check_len := enc_RANAP_PDU(ret);
			log("final RANAP PDU length = ", lengthof(check_len));
			if (lengthof(check_len) == pars.tx_sccp_cr_data_len) {
				return ret;
			}
			nas := f_rnd_octstring(lengthof(nas) + (pars.tx_sccp_cr_data_len - lengthof(check_len)));
			log("that was off, changed NAS length to ", lengthof(nas), " and trying again");
			ret := f_build_initial_ue_with_nas(pars, nas);
		}
		setverdict(fail, "Ended up with wrong Optional Data length");
		mtc.stop;
	}
	return ret;
}

/* build a RANAP RAB AssignmentResponse based on the TestHdlrParams */
friend function f_build_rab_ass_resp(TestHdlrParams pars) return RANAP_PDU {
	var template RAB_SetupOrModifiedList rab_sml;

	rab_sml := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA("192.168.1.23"), t_RAB_binding_port(1234));

	return valueof(ts_RANAP_RabAssResp(rab_sml));
}


/***********************************************************************
 * HNBAP Testing
 ***********************************************************************/


function f_hnbap_register(integer hnb_idx := 0, integer cell_id := 0, boolean expect_reject := false) runs on test_CT
{
	timer T := 2.0;

	HNBAP[hnb_idx].send(ts_HNBAP_HNBRegisterRequest(char2oct("TTCN3-HNB-" & int2str(hnb_idx)),
					'00F110'O,
					int2bit(1 + cell_id, 28),
					int2oct(2, 2),
					int2oct(3, 1),
					int2oct(4, 2)));

	T.start;
	alt {
	[] HNBAP[hnb_idx].receive(tr_HNBAP_HNBRegisterAccept(?)) {
		if (expect_reject) {
			setverdict(fail, "Rx HNB Register Accept while expecting reject");
		} else {
			setverdict(pass);
		}
	}
	[] HNBAP[hnb_idx].receive(tr_HNBAP_HNBRegisterReject(?)) {
		if (expect_reject) {
			setverdict(pass);
		} else {
			setverdict(fail, "Rx HNB Register Reject while expecting accept");
		}
	}
	[] HNBAP[hnb_idx].receive(IUHEM_Event:?) {
		repeat;
	}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for HNB Register response");
	}
	}
}

testcase TC_hnb_register() runs on test_CT {
	g_num_hnbs := 1;
	f_init(start_hnb := false);
	f_hnbap_register(0);
	f_shutdown_helper();
}

/* Try to register the same HNB from 2 different concurrent connections. Second
 * one should be rejected. */
testcase TC_hnb_register_duplicate() runs on test_CT {
	g_num_hnbs := 2;
	f_init(start_hnb := false);
	f_hnbap_register(0);
	f_hnbap_register(1, 0, expect_reject := true);
	f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
	f_shutdown_helper();
}

/* Try to register the same HNB in the same connection already established, aka
 * duplicate HNB Register Request. It should be accepted and new configuration
 * applied. TS 25.469 8.2.4 */
testcase TC_hnb_register_duplicate_reuse_sctp_assoc() runs on test_CT {
	g_num_hnbs := 1;
	f_init(start_hnb := false);
	f_hnbap_register(0);
	f_hnbap_register(0);
	f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
	f_shutdown_helper();
}

/* Drop HNBAP conn (HNBAP DEREG) and reconnect it (HNBAP REG) using same SCTP association.
 * Related: OS#5676, SYS#6113 */
testcase TC_hnb_reregister_reuse_sctp_assoc() runs on test_CT {
	g_num_hnbs := 1;
	f_init(start_hnb := false);
	f_hnbap_register(0);
	HNBAP[0].send(ts_HNBAP_HNBDe_Register(ts_HnbapCause(unspecified)));
	f_hnbap_register(0);
	f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
	f_shutdown_helper();
}

/***********************************************************************
 * RUA / RANAP Testing
 ***********************************************************************/

/* Translate from {msc,sgsn}x{0..n} to the proper index to use in g_cn[].
 * g_cn[] stores CN links, MSCs and SGSNs in the same array.
 * For example, for 'sgsn 23', use g_cn[ f_cn_idx(ps_domain := true, cn_nr := 23) ].
 *
 * Note the naming:
 * cn_nr is the number used in the cfg file, as in 'msc 0'.
 * cn_idx is the array index in g_cn[].
 */
private function f_cn_idx(boolean ps_domain, integer cn_nr := 0) return integer
{
	if (ps_domain) {
		return FIRST_SGSN_IDX + cn_nr;
	}
	return FIRST_MSC_IDX + cn_nr;
}

private template (value) TestHdlrParams
t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
       boolean expect_separate_sccp_cr := false, integer tx_sccp_cr_data_len := 0,
       integer cn_nr := 0) := {
	hnb_idx := hnb_idx,
	cn_idx := f_cn_idx(ps_domain, cn_nr),
	imsi := f_gen_imsi(imsi_suffix),
	ps_domain := ps_domain,
	mgcp_pars := t_MgcpParams,
	hnb := omit,	/* filled in later */
	expect_separate_sccp_cr := expect_separate_sccp_cr,
	tx_sccp_cr_data_len := tx_sccp_cr_data_len,
	pfcp_local_addr := mp_pfcp_ip_local,
	nas_pdu := omit,
	sccp_addr_msc := omit,
	sccp_addr_hnbgw := omit
}

/* Create an Iuh connection; send InitialUE; expect it to appear on new SCCP conenction */
friend function f_tc_initial_ue(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	f_init_handler(pars);
	var RANAP_PDU tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);
}
testcase TC_ranap_cs_initial_ue() runs on test_CT {
	var ConnHdlr vc_conn;

	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1));
	vc_conn.done;

	f_shutdown_helper();
}
testcase TC_ranap_ps_initial_ue() runs on test_CT {
	var ConnHdlr vc_conn;

	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(2, true));
	vc_conn.done;

	f_shutdown_helper();
}

private function f_vty_set_sccp_max_optional_data(TELNETasp_PT pt, integer val := -1)
{
	var charstring valstr;
	if (val < 0) {
		valstr := "standard";
	} else {
		valstr := int2str(val);
	}
	f_vty_enter_config(pt);
	f_vty_transceive(pt, "cs7 instance 0");
	f_vty_transceive(pt, "sccp max-optional-data " & valstr);
	f_vty_transceive(pt, "end");
}

testcase TC_ranap_cs_initial_ue_empty_cr() runs on test_CT {
	var ConnHdlr vc_conn;

	g_num_hnbs := 1;
	f_init();

	f_vty_set_sccp_max_optional_data(HNBGWVTY, 0);

	vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1, expect_separate_sccp_cr := true));
	vc_conn.done;

	/* reset */
	f_vty_set_sccp_max_optional_data(HNBGWVTY);

	f_shutdown_helper();
}
testcase TC_ranap_ps_initial_ue_empty_cr() runs on test_CT {
	var ConnHdlr vc_conn;

	g_num_hnbs := 1;
	f_init();

	f_vty_set_sccp_max_optional_data(HNBGWVTY, 0);

	vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(2, true, expect_separate_sccp_cr := true));
	vc_conn.done;

	/* reset */
	f_vty_set_sccp_max_optional_data(HNBGWVTY);

	f_shutdown_helper();
}

type record Testdata_CR_Limit {
	integer data_len,
	integer max_optional_data,
	boolean expect_separate_sccp_cr
};
type record of Testdata_CR_Limit Testdata_CR_Limits;

testcase TC_sccp_cr_limit() runs on test_CT {
	g_num_hnbs := 1;
	f_init();

	const Testdata_CR_Limits tests := {
		{ data_len := 130, max_optional_data := -1, expect_separate_sccp_cr := false },
		{ data_len := 131, max_optional_data := -1, expect_separate_sccp_cr := true },

		{ data_len := 100, max_optional_data := 100, expect_separate_sccp_cr := false },
		{ data_len := 101, max_optional_data := 100, expect_separate_sccp_cr := true },

		{ data_len := 200, max_optional_data := 200, expect_separate_sccp_cr := false },
		{ data_len := 201, max_optional_data := 200, expect_separate_sccp_cr := true }
	};

	var integer csps;
	for (csps := 0; csps < 2; csps := csps + 1) {
		var boolean ps_domain := (csps > 0);

		var integer i;
		for (i := 0; i < lengthof(tests); i := i + 1) {
			var Testdata_CR_Limit t := tests[i];
			f_logp(HNBGWVTY,
			       "TEST PART TC_sccp_cr_limit ps_domain=" & f_bool2str(ps_domain)
			       & " data_len=" & int2str(t.data_len)
			       & " max_optional_data=" & int2str(t.max_optional_data)
			       & " expect_separate_sccp_cr=" & f_bool2str(t.expect_separate_sccp_cr)
			       );

			f_vty_set_sccp_max_optional_data(HNBGWVTY, t.max_optional_data);
			var ConnHdlr vc_conn;
			vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue),
							     t_pars(100 + i,
								    ps_domain := ps_domain,
								    expect_separate_sccp_cr := t.expect_separate_sccp_cr,
								    tx_sccp_cr_data_len := t.data_len));
			vc_conn.done;
		}
	}

	/* reset */
	f_vty_set_sccp_max_optional_data(HNBGWVTY);

	f_shutdown_helper();
}

/* Reply to a received CRCX with an OK (or the reply configured in cpars), using the given parameters.
 * Return true when an OK reply was sent, false otherwise.
 * Count occurrence of Osmux, include Osmux parameters in the reply if necessary. */
function f_handle_crcx(inout MgcpParameters pars, MgcpCommand mgcp_cmd) return template MgcpResponse {
	var MgwResponse conn := pars.mgw_conn_ran;
	if (pars.got_crcx_count > 0) {
		conn := pars.mgw_conn_cn;
	}
	pars.got_crcx_count := pars.got_crcx_count + 1;

	var MgcpMessage mgcp_msg := {
		command := mgcp_cmd
	}
	var template MgcpResponse mgcp_resp;
	var MgcpOsmuxCID osmux_cid;
	var MgcpCallId call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
	if (ispresent(pars.mgcp_call_id)) {
		if (pars.mgcp_call_id != call_id) {
			setverdict(fail, "CRCX contained unexpected call id. Expected:", pars.mgcp_call_id, " got:", call_id);
			mtc.stop;
		}
	} else {
		pars.mgcp_call_id := call_id;
	}

	/* When the endpoint contains a wildcard we keep the endpoint
	 * identifier we have set up in pars. Otherwise we use the
	 * endpoint name that the call agent has supplied */
	if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
		pars.mgcp_ep := mgcp_cmd.line.ep;
	}

	if (conn.resp == -1) {
		/* Reply with rror */
		var MgcpResponse mgcp_rsp := {
			line := {
				code := "542",
				trans_id := mgcp_cmd.line.trans_id,
				string := "FORCED_FAIL"
			},
			sdp := omit

		}
		var MgcpParameter mgcp_rsp_param := {
			code := "Z",
			val := pars.mgcp_ep
		};
		mgcp_rsp.params[0] := mgcp_rsp_param;
		return mgcp_rsp;
	}

	if (conn.resp == 0) {
		/* Do not reply at all */
		return omit;
	}

	if (conn.resp != 1) {
		setverdict(fail, "Unexpected value for pars.mgw_conn_*.resp, expect -1, 0 or 1");
		mtc.stop;
	}

	var SDP_Message sdp := valueof(ts_SDP(conn.mgw_rtp_ip, conn.mgw_rtp_ip,
						hex2str(pars.mgcp_call_id), "42",
						conn.mgw_rtp_port,
						{ int2str(pars.rtp_payload_type) },
						{ valueof(ts_SDP_rtpmap(pars.rtp_payload_type,
									pars.rtp_sdp_format)),
						  valueof(ts_SDP_ptime(20)) }));

	if (f_mgcp_contains_par(mgcp_msg, "X-OSMUX")) {
		if (not pars.use_osmux) {
			setverdict(fail, "MSC sent X-Osmux parameter in MGCP, but not expecting any Osmux");
			mtc.stop;
		}
		pars.got_osmux_count := pars.got_osmux_count + 1;
		/* we expect MSC to use wildcard here, i.e. osmux_cid == -1 */
		osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
		log("f_handle_crcx(): got Osmux CID: ", osmux_cid);
		if (osmux_cid != -1) {
			setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
			mtc.stop;
		}

		osmux_cid := 0;
		mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, osmux_cid, sdp);
	} else {
		mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, sdp);
	}

	f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(pars.mgcp_ep));

	return mgcp_resp;
}

friend function f_create_rab(inout MgcpParameters pars) runs on ConnHdlr {
	f_rab_ass_req(pars);
	f_rab_ass_resp(pars);
}

friend function f_rab_ass_req(inout MgcpParameters pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	var template RAB_SetupOrModifyList rab_sml;
	timer T := 5.0;

	/* Send RAB Assignment Request */
	rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.cn_rtp_ip), t_RAB_binding_port(pars.cn_rtp_port));
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));
	BSSAP.send(tx);
	T.start;

	/* Handle MGCP CRCX */
	alt {
	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("CRCX1", mgcp_cmd);
		var template MgcpResponse mgcp_rsp := f_handle_crcx(pars, mgcp_cmd);
		MGCP.send(valueof(mgcp_rsp));
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for MGCP");
		}
	}
	T.stop;

	/* Expect RAB Assignment Request with IP/port from CRCX ACK via Iuh */
	rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.mgw_conn_ran.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_ran.mgw_rtp_port));
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));

	f_rua_expect(tx);
}

friend function f_rab_ass_resp(inout MgcpParameters pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	var template RAB_SetupOrModifiedList rab_smdl;

	/* Send back RAB Assignment Response via Iuh */
	rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA(pars.hnb_rtp_ip), t_RAB_binding_port(pars.hnb_rtp_port));
	tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
	RUA.send(tx);

	interleave {
	/* Expect MDCX with IP/port from RAB Assignment Response */
	[] MGCP.receive(tr_MDCX(tr_SDP(pars.hnb_rtp_ip, pars.hnb_rtp_port))) -> value mgcp_cmd {
		var HostName mgw_rtp_ip;
		var boolean exp_rua_rab_reass := false;
		log("MDCX1", mgcp_cmd);
		if (ispresent(pars.mgw_conn_ran.mgw_rtp_ip_mdcx)) {
			mgw_rtp_ip := pars.mgw_conn_ran.mgw_rtp_ip_mdcx;
			if (pars.mgw_conn_ran.mgw_rtp_ip != pars.mgw_conn_ran.mgw_rtp_ip_mdcx) {
				exp_rua_rab_reass := true;
			}
		} else {
			mgw_rtp_ip := pars.mgw_conn_ran.mgw_rtp_ip;
		}

		/* Verify SDP of MDCX */
		var SDP_Message sdp := valueof(ts_SDP(mgw_rtp_ip, mgw_rtp_ip, hex2str(pars.mgcp_call_id), "42", pars.mgw_conn_ran.mgw_rtp_port,
			{ int2str(pars.rtp_payload_type) }, { valueof(ts_SDP_rtpmap(pars.rtp_payload_type, pars.rtp_sdp_format)), valueof(ts_SDP_ptime(20)) } ));
		var template MgcpResponse mgcp_rsp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, pars.mgw_conn_ran.mgcp_connection_id, sdp);
		MGCP.send(valueof(mgcp_rsp));

		/* If IP address changed, we expect HNBGW to Modify the RAB through RAB-Ass-Req: */
		if (exp_rua_rab_reass) {
			var template RAB_SetupOrModifyList rab_sml;
			/* Expect RAB Assignment Request with IP/port from MDCX ACK via Iuh */
			rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.mgw_conn_ran.mgw_rtp_ip_mdcx), t_RAB_binding_port(pars.mgw_conn_ran.mgw_rtp_port));
			tx := valueof(ts_RANAP_RabAssReq(rab_sml));

			f_rua_expect(tx);
			/* Send back RAB Assignment Response via Iuh */
			rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA(pars.hnb_rtp_ip), t_RAB_binding_port(pars.hnb_rtp_port));
			tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
			RUA.send(tx);
			/* This shouldn't trigger any MGCP, since nothing changed on the HNB IP side. Continue below. */
		}
		}
	/* Handle CRCX for second leg of endpoint, answer with IP/port */
	[] MGCP.receive(tr_CRCX(pars.mgcp_ep, tr_SDP(pars.cn_rtp_ip, pars.cn_rtp_port))) -> value mgcp_cmd {
		log("CRCX2", mgcp_cmd);
		/* Verify SDP of CRCX */
		var template MgcpResponse mgcp_rsp := f_handle_crcx(pars, mgcp_cmd);
		MGCP.send(valueof(mgcp_rsp));
	}
	}

	/* Expect RAB Assignment Response with IP/port from second CRCX ACK */
	rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA(pars.mgw_conn_cn.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_cn.mgw_rtp_port));
	tx := valueof(ts_RANAP_RabAssResp(rab_smdl));

	f_bssap_expect(tx);
}

private altstep as_mgcp_dlcx(inout TestHdlrParams pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;

	[] MGCP.receive(tr_DLCX(pars.mgcp_pars.mgcp_ep)) -> value mgcp_cmd {
		log("DLCX", mgcp_cmd);
		MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
		pars.mgcp_pars.got_dlcx_count := pars.mgcp_pars.got_dlcx_count + 1;
		if (pars.mgcp_pars.got_dlcx_count != pars.mgcp_pars.got_crcx_count) {
			repeat;
		}
		setverdict(pass);
	}
}

friend function f_tc_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 5.0;

	f_init_handler(pars);
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);

	f_create_rab(pars.mgcp_pars);

	/* Send Iu Release */
	tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
	f_iu2iuh(tx);

	T.start;
	alt {
	[] as_mgcp_dlcx(pars) {}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for DLCX");
	}
	}

	tx := valueof(ts_RANAP_IuReleaseComplete());
	f_iuh2iu(tx);
}

testcase TC_rab_assignment() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assignment), t_pars(3));
	vc_conn.done;

	f_shutdown_helper();
}

friend function f_tc_rab_assign_fail(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 5.0;

	f_init_handler(pars);
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);

	f_rab_ass_req(pars.mgcp_pars);

	/* Send RAB failed list in response */
	tx := valueof(ts_RANAP_RabAssResp(rab_fl := ts_RAB_FL(t_RAB_id(23), ts_RanapCause_om_intervention)));
	f_iuh2iu(tx);

	T.start;
	alt {
	[] as_mgcp_dlcx(pars) {}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for DLCX");
	}
	}
}

testcase TC_rab_assign_fail() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assign_fail), t_pars(4));
	vc_conn.done;

	f_shutdown_helper();
}

friend function f_tc_rab_release(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 15.0;

	f_init_handler(pars);
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);

	f_create_rab(pars.mgcp_pars);

	/* Send RAB Release */
	tx := valueof(ts_RANAP_RabAssReq(rab_rl := ts_RAB_RL(t_RAB_id(23), ts_RanapCause_om_intervention)));
	BSSAP.send(tx);

	T.start;

	alt {
	[] as_mgcp_dlcx(pars) {}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for DLCX");
	}
	}
	T.stop;

	f_rua_expect(tx);
}

testcase TC_rab_release() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_rab_release), t_pars(5));
	vc_conn.done;

	f_shutdown_helper();
}

friend function f_tc_rab_assign_mgcp_to(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	var template RAB_SetupOrModifyList rab_sml;
	timer T := 15.0;

	T.start;
	f_init_handler(pars);
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);


	/* Send RAB Assignment Request */
	rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.mgcp_pars.cn_rtp_ip), t_RAB_binding_port(pars.mgcp_pars.cn_rtp_port));
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));
	BSSAP.send(tx);

	/* Ignore MGCP CRCX */
	alt {
	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("Ignoreing CRCX1", mgcp_cmd);
		repeat;
		}
	[] BSSAP.receive(tr_RANAP_IuReleaseRequest(?)) { }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for IuRelease");
		}
	}

	/* Send Iu Release */
	tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
	f_iu2iuh(tx);

	tx := valueof(ts_RANAP_IuReleaseComplete());
	f_iuh2iu(tx);
}

testcase TC_rab_assign_mgcp_to() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assign_mgcp_to), t_pars(6));
	vc_conn.done;

	f_shutdown_helper();
}

/* Test case where IuUP IP address announced by HNB and updated through MDCX
 * makes MGW select a new local IuUP address. HNBGW is expected to update the HNB
 * through RAB-Modify-Req. */
testcase TC_rab_assign_mgw_iuup_addr_chg() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();
	var template (value) TestHdlrParams pars := t_pars(3);
	/* Emulate change of local IuUP IP address after rx MDCX: */
	pars.mgcp_pars.mgw_conn_ran.mgw_rtp_ip_mdcx := "127.3.2.1";

	vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assignment), pars);
	vc_conn.done;

	f_shutdown_helper();
}

/* Create an Iuh connection; send InitialUE; transceive data both directions */
friend function f_tc_ranap_bidir(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	f_init_handler(pars);

	/* HNB -> MSC: InitialUE */
	f_iuh2iu_connect(f_build_initial_ue(g_pars));

	/* MSC <- HNB: DirectTransfer */
	f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
	/* MSC -> HNB: DirectTransfer */
	f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));

	/* HNB <- MSC:  CommonID */
	f_iu2iuh(ts_RANAP_CommonId(hex2oct(pars.imsi)));
}
testcase TC_ranap_cs_bidir() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(3));
	vc_conn.done;

	f_shutdown_helper();
}
testcase TC_ranap_ps_bidir() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(4, true));
	vc_conn.done;

	f_shutdown_helper();
}


private function f_tc_ranap_mo_disconnect(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	f_init_handler(pars);

	/* HNB -> MSC: InitialUE */
	f_iuh2iu_connect(f_build_initial_ue(g_pars));

	/* MSC <- HNB: DirectTransfer */
	f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
	/* MSC -> HNB: DirectTransfer */
	f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));

	/* MSC <- HNB: RUA disconnect */
	f_iuh2iu_disconnect(ts_RANAP_IuReleaseComplete, RUA_IEs.Cause:{misc:=processing_overload});
}
testcase TC_ranap_cs_mo_disconnect() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(5));
	vc_conn.done;

	f_shutdown_helper();
}
testcase TC_ranap_ps_mo_disconnect() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(6));
	vc_conn.done;

	f_shutdown_helper();
}

type record FTeid {
	HostName addr,
	OCT4 teid
}

type record FTeids {
	FTeid local,
	FTeid remote
}


/* 'local' and 'remote' refer to the GTP information from the UPF's point of view:
 * HNB                             UPF                 CN
 * access.remote <---> access.local | core.local <---> core.remote
 */
type record GtpParameters {
	FTeids core,
	FTeids access
}

/* HNB                             UPF                 CN
 * access.remote <---> access.local | core.local <---> core.remote
 * 127.0.0.4           127.0.0.3      127.0.0.2        127.0.0.1
 * 0x44004400          0x30303030     0x22002200       0x10101010
 */
template GtpParameters t_GtpParameters := {
	core := {
		local := {
			addr := "127.0.0.2",
			teid := '22002200'O
		},
		remote := {
			addr := "127.0.0.1",
			teid := '10101010'O
		}
	},
	access := {
		local := {
			addr := "127.0.0.3",
			teid := '30303030'O
		},
		remote := {
			addr := "127.0.0.4",
			teid := '44004400'O
		}
	}
}

private function f_pfcp_expect(template (present) PDU_PFCP exp_rx, float wait_time := 5.0) runs on ConnHdlr return PDU_PFCP
{
	var PDU_PFCP rx;
	timer T := wait_time;
	T.start;
	alt {
	[] PFCP.receive(exp_rx) -> value rx {
			setverdict(pass);
		}
	[] PFCP.receive(PDU_PFCP:?) {
			setverdict(fail, "Got an unexpected PFCP message, was waiting for ", exp_rx);
			mtc.stop;
		}
	[] T.timeout {
			setverdict(fail, "Timeout waiting for PFCP ", exp_rx);
			mtc.stop;
		}
	}
	T.stop;
	return rx;
}

friend function f_tc_ps_rab_assignment_with_pfcp(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var RANAP_PDU tx;
	var RANAP_PDU rx;

	f_init_handler(pars);

	f_pfcp_register();

	var PDU_PFCP m;
	var Node_ID upf_node_id := valueof(ts_PFCP_Node_ID_fqdn("\07osmocom\03org"));

	m := f_pfcp_expect(tr_PFCP_Assoc_Setup_Req(), wait_time := 15.0);
	PFCP.send(ts_PFCP_Assoc_Setup_Resp(m.sequence_number, upf_node_id,
					   ts_PFCP_Cause(REQUEST_ACCEPTED), 1234));

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);

	var GtpParameters gtp_pars := valueof(t_GtpParameters);
	var template RAB_SetupOrModifyList rab_sml;

	/* Send RAB Assignment Request */
	rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.remote.addr), gtp_pars.core.remote.teid);
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));
	BSSAP.send(tx);

	/* Expect PFCP Session Establishment Request. */
	m := f_pfcp_expect(tr_PFCP_Session_Est_Req());
	var F_SEID hnbgw_f_seid := m.message_body.pfcp_session_establishment_request.CP_F_SEID;
	var PFCP_Session_Establishment_Request serq := m.message_body.pfcp_session_establishment_request;

	/* Acting as UPF, invent a new PFCP SEID to send to HNBGW. Respond to the Session Establishment.
	 * The PFCP response must have the same sequence_number as the request. */
	var F_SEID up_f_seid := valueof(ts_PFCP_F_SEID_ipv4(f_inet_addr("127.0.0.1"), '1111111111111111'O));
	var template PDU_PFCP r := ts_PFCP_Session_Est_Resp(m.sequence_number, upf_node_id, hnbgw_f_seid.seid);
	r.message_body.pfcp_session_establishment_response := {
		offending_ie := omit,
		UP_F_SEID := up_f_seid,
		created_PDR_list := {
			ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[0].grouped_ie.pdr_id,
					    local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.core.local.teid,
										f_inet_addr(gtp_pars.core.local.addr))),
			ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[1].grouped_ie.pdr_id,
					    local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.access.local.teid,
										f_inet_addr(gtp_pars.access.local.addr)))
		},
		load_control_information := omit,
		overload_control_information := omit,
		node_list := omit,
		failed_rule_id := omit,
		created_traffic_endpoint_list := omit
	};
	PFCP.send(r);

	/* Expect on Iuh: RAB Assignment Request with IP/port from PFCP Session Est Resp */
	rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.local.addr),
				 gtp_pars.access.local.teid);
	rx := valueof(ts_RANAP_RabAssReq(rab_sml));
	f_rua_expect(rx);

	/* Send back RAB Assignment Response via Iuh */
	var template RAB_SetupOrModifiedList rab_smdl;
	rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.remote.addr),
				   gtp_pars.access.remote.teid);
	tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
	RUA.send(tx);

	m := f_pfcp_expect(tr_PFCP_Session_Mod_Req(up_f_seid.seid));
	r := ts_PFCP_Session_Mod_Resp(m.sequence_number, hnbgw_f_seid.seid);
	PFCP.send(r);

	rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.local.addr), gtp_pars.core.local.teid);
	f_bssap_expect(tr_RANAP_RabAssResp(rab_smdl));

	f_sleep(2.0);
	tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
	f_iu2iuh(tx);

	tx := valueof(ts_RANAP_IuReleaseComplete());
	f_iuh2iu(tx);

	m := f_pfcp_expect(tr_PFCP_Session_Del_Req(up_f_seid.seid));
	PFCP.send(ts_PFCP_Session_Del_Resp(m.sequence_number, hnbgw_f_seid.seid));

	f_sleep(2.0);
}

testcase TC_ps_rab_assignment_with_pfcp() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();
	f_sleep(1.0);

	vc_conn := f_start_handler_with_pars(refers(f_tc_ps_rab_assignment_with_pfcp), t_pars(7, ps_domain := true));
	vc_conn.done;

	f_shutdown_helper();
}

altstep as_disallow_pfcp() runs on ConnHdlr {
	[] PFCP.receive(PDU_PFCP:?) {
			setverdict(fail, "Received PFCP message, but no PFCP communication expected");
			mtc.stop;
		}
}

friend function f_tc_ps_rab_assignment_without_pfcp(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var RANAP_PDU tx;
	var RANAP_PDU rx;
	timer T := 5.0;

	f_init_handler(pars);

	f_pfcp_register();
	activate(as_disallow_pfcp());

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);

	var GtpParameters gtp_pars := valueof(t_GtpParameters);
	var template RAB_SetupOrModifyList rab_sml;

	/* Send RAB Assignment Request */
	rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.remote.addr), gtp_pars.core.remote.teid);
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));
	BSSAP.send(tx);

	/* Expect on Iuh: unmodified RAB Assignment Request */
	rx := valueof(ts_RANAP_RabAssReq(rab_sml));
	f_rua_expect(rx);

	/* Send back RAB Assignment Response via Iuh */
	var template RAB_SetupOrModifiedList rab_smdl;
	rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.remote.addr),
				   gtp_pars.access.remote.teid);
	tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
	RUA.send(tx);

	/* Expect on IuPS: unmodified RAB Assignment Response */
	f_bssap_expect(tr_RANAP_RabAssResp(rab_smdl));

	f_sleep(2.0);
	tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
	f_iu2iuh(tx);

	tx := valueof(ts_RANAP_IuReleaseComplete());
	f_iuh2iu(tx);

	f_sleep(2.0);
}

testcase TC_ps_rab_assignment_without_pfcp() runs on test_CT {
	var ConnHdlr vc_conn;
	f_init();
	f_sleep(1.0);

	vc_conn := f_start_handler_with_pars(refers(f_tc_ps_rab_assignment_without_pfcp), t_pars(7, ps_domain := true));
	vc_conn.done;

	f_shutdown_helper();
}

/* Default list of counters for a 'cn' entity to test the cnpool feature. */
const CounterNameVals counternames_cnpool := {
	{ "cnpool:subscr:new", 0 },
	{ "cnpool:subscr:known", 0 },
	{ "cnpool:subscr:reattach", 0 },
	{ "cnpool:subscr:attach_lost", 0 },
	{ "cnpool:subscr:paged", 0 }
};
private function f_ctrs_cn_init(boolean ps_domain, integer cn_count := 0,
				CounterNameVals counternames := counternames_cnpool) runs on test_CT {
	if (ps_domain) {
		g_ctr_cn_node_name := "sgsn";
		if (cn_count == 0) {
			cn_count := NUM_SGSN;
		}
	} else {
		g_ctr_cn_node_name := "msc";
		if (cn_count == 0) {
			cn_count := NUM_MSC;
		}
	}
	g_ctr_cn := f_counter_name_vals_get_n(IPA_CTRL, g_ctr_cn_node_name, cn_count, counternames);
	log("initial " & g_ctr_cn_node_name & " rate counters: ", g_ctr_cn);
}

/*  f_ctrs_cn_init();
 *  f_do_thing(on_cn := 0);
 *  f_do_thing(on_cn := 0);
 *  f_do_other(on_cn := 1);
 *  f_ctrs_cn_add(0, "thing", 2);
 *  f_ctrs_cn_add(1, "other");
 *  f_ctrs_cn_verify();
 */
private function f_ctrs_cn_verify() runs on test_CT {
	log("verifying", g_ctr_cn_node_name, " rate counters: ", g_ctr_cn);
	f_counter_name_vals_expect_n(IPA_CTRL, g_ctr_cn_node_name, g_ctr_cn);
}

/* convenience: f_ctrs_cn_add() and f_ctrs_cn_verify() in one call.
 *  f_ctrs_cn_init();
 *  f_do_thing(on_cn := 0);
 *  f_do_thing(on_cn := 0);
 *  f_do_thing(on_cn := 0);
 *  f_ctrs_cn_expect(0, "thing", 3);
 */
private function f_ctrs_cn_expect(integer cn_nr, charstring countername, integer val := 1) runs on test_CT {
	f_ctrs_cn_add(cn_nr, countername, val);
	f_ctrs_cn_verify();
}

private function f_ctrs_cn_add(integer cn_nr, charstring countername, integer val := 1) runs on test_CT {
	f_counter_name_vals_list_add(g_ctr_cn, cn_nr, countername, val);
}

private function f_perform_compl_l3(octetstring nas, boolean do_clear := true, boolean expect_iu_l3 := true)
runs on ConnHdlr {
	timer T := 10.0;

	/* create an expect on the Iu side for the random NAS portion */
	if (g_pars.expect_separate_sccp_cr) {
		f_ran_register_sccp_cr_without_payload();
	} else {
		f_ran_register_exp(nas);
	}

	/* send Connect via Iuh (creating a RUA connection) */
	var RANAP_PDU tx := f_build_initial_ue_with_nas(g_pars, nas);
	RUA.send(RUA_Conn_Req:{g_pars.ps_domain, tx});

	if (expect_iu_l3) {
		/* Expect same message to arrive at CN */
		f_bssap_expect(tx);
	}
}

private function f_tc_cnpool_compl_l3(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	f_init_handler(pars);
	f_perform_compl_l3(g_pars.nas_pdu);
}

private function f_TC_cnpool_compl_l3(boolean ps_domain, octetstring nas_pdu, integer cn_nr,
				      template (omit) charstring inc_countername := omit) runs on test_CT {
	var ConnHdlr vc_conn;
	var template (value) TestHdlrParams pars := t_pars(0, ps_domain := ps_domain, cn_nr := cn_nr);
	pars.nas_pdu := nas_pdu;
	log("XXX ", pars);
	vc_conn := f_start_handler_with_pars(refers(f_tc_cnpool_compl_l3), pars);
	vc_conn.done;

	if (not istemplatekind(inc_countername, "omit")) {
		f_ctrs_cn_expect(cn_nr, valueof(inc_countername));
	}
}

function f_TC_cnpool_compl_l3_list(boolean ps_domain, ro_octetstring compl3, Osmocom_Types.ro_integer cn_nrs,
				   charstring inc_countername) runs on test_CT {
	var integer n := lengthof(compl3);
	if (n < lengthof(cn_nrs)) {
		n := lengthof(cn_nrs);
	}
	for (var integer i := 0; i < n; i := i + 1) {
		var integer cn_nr := cn_nrs[i mod lengthof(cn_nrs)];
		f_TC_cnpool_compl_l3(ps_domain, compl3[i mod lengthof(compl3)], cn_nr, inc_countername);
	}
}

type enumerated Compl3Type {
	/* CS */
	LU,
	CMSERV,
	PAGRESP,
	IMSIDETACH,

	/* PS */
	ATTACHREQ,
	RAUREQ,
	DETREQ
};

private function f_gen_one_compl_l3(Compl3Type compl3type, template (value) MobileIdentityLV mi,
		integer ps_nri := -1
		) return octetstring
{
	/* CS */
	if (compl3type == LU) {
		return enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(mi), '00F110'O)));
	}
	if (compl3type == CMSERV) {
		return enc_PDU_ML3_MS_NW(valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(mi))));
	}
	if (compl3type == PAGRESP) {
		return enc_PDU_ML3_MS_NW(valueof(ts_PAG_RESP(valueof(mi))));
	}
	if (compl3type == IMSIDETACH) {
		return enc_PDU_ML3_MS_NW(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(mi))));
	}

	/* PS */
	var template (omit) NetworkResourceIdentifierContainerTLV nri := omit;
	if (ps_nri >= 0) {
		nri := valueof(ts_GMM_NRI(ps_nri));
	}

	if (compl3type == ATTACHREQ) {
		return enc_PDU_L3_MS_SGSN(valueof(ts_GMM_ATTACH_REQ(valueof(mi), f_RAI('001'H, '01'H, '2a2a'O, '17'O),
						nri := nri)));
	}
	if (compl3type == RAUREQ) {
		return enc_PDU_L3_MS_SGSN(valueof(ts_GMM_RAU_REQ(valueof(mi), GPRS_UPD_T_PERIODIC,
								 f_RAI('001'H, '01'H, '2a2a'O, '17'O),
								 nri := nri)));
	}
	if (compl3type == DETREQ) {
		return enc_PDU_L3_MS_SGSN(valueof(ts_GMM_DET_REQ_MO_mi(c_GMM_DTT_MO_GPRS, power_off := false,
								       p_tmsi := valueof(ts_MI_TLV(mi.mobileIdentityV)))));
	}

	setverdict(fail, "unknown complete layer 3 type");
	mtc.stop;
}

type record of Compl3Type ro_Compl3Type;
type record of MobileIdentityLV ro_MobileIdentityLV;
type record of octetstring ro_octetstring;

/* Generate a list of n Complete Layer 3 NAS PDUs,
 * rotating through the message kinds listed in 'types' and the mobile identities in mis.
 */
private function f_gen_compl_l3(ro_Compl3Type types, ro_MobileIdentityLV mis, integer n) return ro_octetstring
{
	var ro_octetstring res := {};
	for (var integer i := 0; i < n; i := i + 1) {
		var integer ti := i mod lengthof(types);
		var integer mi := i mod lengthof(mis);
		res[i] := f_gen_one_compl_l3(types[ti], mis[mi]);
	}
	return res;
}

private function f_gen_mi_imsi(integer n) return MobileIdentityLV
{
	return valueof(ts_MI_IMSI_LV(f_gen_imsi(n)));
}

private function f_gen_mi_imsis(integer n) return ro_MobileIdentityLV
{
	var ro_MobileIdentityLV mis := {};
	for (var integer i := 0; i < n; i := i + 1) {
		mis[i] := f_gen_mi_imsi(n);
	}
	return mis;
}

function f_vty_set_roundrobin_next(TELNETasp_PT VTY, boolean ps_domain, integer cn_nr)
{
	var charstring msc_sgsn;
	if (ps_domain) {
		msc_sgsn := "sgsn";
	} else {
		msc_sgsn := "msc";
	}
	f_vty_transceive(VTY, "cnpool roundrobin next " & msc_sgsn & " " & int2str(cn_nr));
}

private function f_gen_compl3_by_domain(boolean ps_domain, integer n, template (omit) ro_MobileIdentityLV mis := omit) return ro_octetstring{
	var ro_Compl3Type types;
	if (ps_domain) {
		types := { ATTACHREQ, RAUREQ, DETREQ };
	} else {
		types := { LU, CMSERV, PAGRESP, IMSIDETACH };
	}
	if (istemplatekind(mis, "omit")) {
		mis := f_gen_mi_imsis(n);
	}
	return f_gen_compl_l3(types, valueof(mis), n);
}

/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
testcase TC_mscpool_L3Compl_on_1_cnlink() runs on test_CT {
	f_TC_cnpool_L3Compl_on_1_cnlink(ps_domain := false);
}
testcase TC_sgsnpool_L3Compl_on_1_cnlink() runs on test_CT {
	f_TC_cnpool_L3Compl_on_1_cnlink(ps_domain := true);
}
function f_TC_cnpool_L3Compl_on_1_cnlink(boolean ps_domain) runs on test_CT {

	f_init();

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 4);
	f_TC_cnpool_compl_l3_list(ps_domain, compl3, {0, 0, 0, 0}, "cnpool:subscr:new");

	f_shutdown_helper();
}

/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
	f_TC_cnpool_L3Complete_by_imsi_round_robin(ps_domain := false);
}
testcase TC_sgsnpool_L3Complete_no_nri_round_robin() runs on test_CT {
	f_TC_cnpool_L3Complete_by_imsi_round_robin(ps_domain := true);
}
function f_TC_cnpool_L3Complete_by_imsi_round_robin(boolean ps_domain) runs on test_CT {

	f_init(nr_msc := 2, nr_sgsn := 2);
	f_sleep(1.0);

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 3);

	f_TC_cnpool_compl_l3_list(ps_domain, compl3,
				  /* Third Complete Layer 3 wraps back to msc 0 */
				  cn_nrs := {0, 1, 0},
				  inc_countername := "cnpool:subscr:new");

	f_shutdown_helper();
}

/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain a NULL-NRI (0, 1)
 * (configured in osmo-hnbgw.cfg). */
testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
	f_TC_cnpool_LU_by_tmsi_null_nri_N_round_robin(ps_domain := false, nri_val := 0);
}
/* For NRI == 1, one of the MSC also has the NULL-NRI as part of its owned NRIs, but the NULL-NRI setting is stronger
 * than that. */
testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
	f_TC_cnpool_LU_by_tmsi_null_nri_N_round_robin(ps_domain := false, nri_val := 1);
}
function f_TC_cnpool_LU_by_tmsi_null_nri_N_round_robin(boolean ps_domain, integer nri_val) runs on test_CT {

	f_init(nr_msc := 2, nr_sgsn := 2);
	f_sleep(1.0);

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_MobileIdentityLV mis := { valueof(ts_MI_TMSI_NRI_LV(nri_val)) };
	var ro_octetstring compl3;
	if (ps_domain) {
		compl3 := {
			f_gen_one_compl_l3(ATTACHREQ, mis[0], nri_val)
		};
	} else {
		compl3 := f_gen_compl_l3({LU}, mis, 1);
	}

	f_TC_cnpool_compl_l3_list(ps_domain, compl3,
				  /* The third Complete Layer 3 wraps back to msc 0 */
				  {0, 1, 0},
				  "cnpool:subscr:reattach");
	f_shutdown_helper();
}

/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
 * assigned to any MSC (configured in osmo-hnbgw.cfg). */
testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
	f_TC_cnpool_L3Complete_by_tmsi_unassigned_nri_round_robin(ps_domain := false);
}
function f_TC_cnpool_L3Complete_by_tmsi_unassigned_nri_round_robin(boolean ps_domain) runs on test_CT {

	f_init(nr_msc := 2, nr_sgsn := 2);
	f_sleep(1.0);

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	/* 3 NRIs that are not assigned to any MSC */
	var ro_MobileIdentityLV mis := {
		valueof(ts_MI_TMSI_NRI_LV(1000)),
		valueof(ts_MI_TMSI_NRI_LV(768)),
		valueof(ts_MI_TMSI_NRI_LV(819))
	};

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 3, mis);
	f_TC_cnpool_compl_l3_list(ps_domain, compl3, { 0, 1, 0 }, "cnpool:subscr:new");

	f_shutdown_helper();
}

/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
 * assigned to a CN link that is currently not connected (configured in osmo-hnbgw.cfg). */
testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
	f_TC_cnpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin(ps_domain := false);
}
function f_TC_cnpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin(boolean ps_domain) runs on test_CT {

	f_init(nr_msc := 2, nr_sgsn := 2);
	f_sleep(1.0);

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	/* 3 NRIs that are assigned to an unconnected MSC */
	var ro_MobileIdentityLV mis := {
		valueof(ts_MI_TMSI_NRI_LV(512)),
		valueof(ts_MI_TMSI_NRI_LV(767)),
		valueof(ts_MI_TMSI_NRI_LV(750))
	};

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 3, mis);

	f_TC_cnpool_compl_l3(ps_domain, compl3[0], cn_nr := 0);
	f_ctrs_cn_add(2, "cnpool:subscr:attach_lost");
	f_ctrs_cn_add(0, "cnpool:subscr:new");
	f_ctrs_cn_verify();

	f_TC_cnpool_compl_l3(ps_domain, compl3[1], cn_nr := 1);
	f_ctrs_cn_add(2, "cnpool:subscr:attach_lost");
	f_ctrs_cn_add(1, "cnpool:subscr:new");
	f_ctrs_cn_verify();

	f_TC_cnpool_compl_l3(ps_domain, compl3[2], cn_nr := 0);
	f_ctrs_cn_add(2, "cnpool:subscr:attach_lost");
	f_ctrs_cn_add(0, "cnpool:subscr:new");
	f_ctrs_cn_verify();

	f_shutdown_helper();
}

/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
 * osmo-hnbgw.cfg). */
testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
	f_TC_cnpool_L3Complete_valid_nri_1(ps_domain := false);
}
testcase TC_sgsnpool_L3Complete_valid_nri_1() runs on test_CT {
	f_TC_cnpool_L3Complete_valid_nri_1(ps_domain := true);
}
function f_TC_cnpool_L3Complete_valid_nri_1(boolean ps_domain) runs on test_CT {

	f_init(nr_msc := 2, nr_sgsn := 2);
	f_sleep(1.0);

	/* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
	 * this is not using round-robin. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_octetstring compl3;

	/* 3 NRIs of the second MSC's range (256-511) */
	var ro_MobileIdentityLV mis := {
		valueof(ts_MI_TMSI_NRI_LV(256)),
		valueof(ts_MI_TMSI_NRI_LV(260)),
		valueof(ts_MI_TMSI_NRI_LV(511))
	};
	if (ps_domain) {
		compl3 := {
			f_gen_one_compl_l3(RAUREQ, mis[0], 256),
			f_gen_one_compl_l3(RAUREQ, mis[1], 260),
			f_gen_one_compl_l3(RAUREQ, mis[2], 511)
		};
	} else {
		compl3 := f_gen_compl3_by_domain(ps_domain, 3, mis);
	}

	f_TC_cnpool_compl_l3_list(ps_domain, compl3, {1, 1, 1}, "cnpool:subscr:known");

	f_shutdown_helper();
}

/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-hnbgw.cfg),
 * while a round-robin remains unaffected by that. */
testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
	f_TC_cnpool_L3Complete_valid_nri_2(ps_domain := false);
}
testcase TC_sgsnpool_L3Complete_valid_nri_2() runs on test_CT {
	f_TC_cnpool_L3Complete_valid_nri_2(ps_domain := true);
}
function f_TC_cnpool_L3Complete_valid_nri_2(boolean ps_domain) runs on test_CT {

	f_init(nr_msc := 3, nr_sgsn := 3);
	f_sleep(1.0);

	/* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
	 * this is not using round-robin. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 1);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_octetstring compl3;

	/* 2 NRIs of the third MSC's range (512-767) */
	var ro_MobileIdentityLV mis := {
		valueof(ts_MI_TMSI_NRI_LV(512)),
		valueof(ts_MI_TMSI_NRI_LV(678))
	};
	if (ps_domain) {
		compl3 := {
			f_gen_one_compl_l3(ATTACHREQ, mis[0], 512),
			f_gen_one_compl_l3(ATTACHREQ, mis[1], 678)
		};
	} else {
		compl3 := f_gen_compl3_by_domain(ps_domain, 2, mis);
	}

	f_TC_cnpool_compl_l3_list(ps_domain, compl3, {2, 2}, "cnpool:subscr:known");

	/* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
	f_TC_cnpool_compl_l3_list(ps_domain, f_gen_compl3_by_domain(ps_domain, 1), {1}, "cnpool:subscr:new");

	f_shutdown_helper();
}

/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
	f_TC_cnpool_nri_from_other_PLMN(ps_domain := false);
}
testcase TC_sgsnpool_nri_from_other_PLMN() runs on test_CT {
	f_TC_cnpool_nri_from_other_PLMN(ps_domain := true);
}
function f_TC_cnpool_nri_from_other_PLMN(boolean ps_domain) runs on test_CT {

	f_init(nr_msc := 3, nr_sgsn := 3);
	f_sleep(1.0);

	/* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
	 * instead, and hits msc 0. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_octetstring compl3;

	var ro_MobileIdentityLV mis := {
		valueof(ts_MI_TMSI_NRI_LV(260)),
		valueof(ts_MI_TMSI_NRI_LV(555))
	};
	if (ps_domain) {
		compl3 := {
			/* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-hnbgw.cfg */
			enc_PDU_L3_MS_SGSN(valueof(ts_GMM_ATTACH_REQ(mis[0], f_RAI('999'H, '99'H, '2a2a'O,
										   '17'O),
								     nri := ts_GMM_NRI(260)
								    ))),
			/* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
			f_gen_one_compl_l3(ATTACHREQ, mis[1], 555)
		}
	} else {
		compl3 :=  {
			/* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-hnbgw.cfg */
			enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, mis[0], '99F999'O))),
			/* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
			enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, mis[1], '00F110'O)))
		};
	}

	/* Foreign NRI: roundrobin */
	f_TC_cnpool_compl_l3(ps_domain, compl3[0], cn_nr := 0, inc_countername := "cnpool:subscr:new");

	/* Local NRI: matching msc */
	f_TC_cnpool_compl_l3(ps_domain, compl3[1], cn_nr := 2, inc_countername := "cnpool:subscr:known");

	f_shutdown_helper();
}

/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
friend function f_tc_mscpool_paging_imsi(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	f_init_handler(pars);

	var hexstring imsi := '001010000000123'H;
	var RANAP_IEs.CN_DomainIndicator domain_ind;
	if (pars.ps_domain) {
		domain_ind := ps_domain;
	} else {
		domain_ind := cs_domain;
	}
	var template (value) RANAP_PDU paging := ts_RANAP_Paging(domain_ind, imsi_hex2oct(imsi));
	BSSAP.send(ts_RANAP_UNITDATA_req(pars.sccp_addr_hnbgw, pars.sccp_addr_msc, paging));
	/* TODO: Expect RUA ConnectionlessTransfer Paging (on all HNB).
	 * We could verify the Paging sent from osmo-hnbgw to RUA with some effort,
	 * but, this test does not care whether the Paging was forwarded to RUA or not, only that osmo-hnbgw *received*
	 * the Paging. In the CN pool decisions, osmo-hnbgw should match up Paging Response to an earlier Paging.
	 */

	f_sleep(1.0);

	/* Despite the round robin pointing at the second MSC ('roundrobin next msc 1'), the earlier Paging for the same IMSI
	 * causes this Paging Response to go to the first MSC ('msc 0'). */
	f_perform_compl_l3(f_gen_one_compl_l3(PAGRESP, ts_MI_IMSI_LV(imsi)));
	f_sleep(1.0);
}

testcase TC_mscpool_paging_imsi() runs on test_CT {
	f_init(nr_msc := 3);
	f_sleep(1.0);

	var boolean ps_domain := false;

	/* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
	 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ConnHdlr vc_conn1;
	var template (value) TestHdlrParams pars1 := t_pars(0, ps_domain := ps_domain, cn_nr := 0);
	pars1.sccp_addr_hnbgw := g_cn[valueof(pars1.cn_idx)].sccp_addr_peer;
	pars1.sccp_addr_msc := g_cn[valueof(pars1.cn_idx)].sccp_addr_own;
	vc_conn1 := f_start_handler_with_pars(refers(f_tc_mscpool_paging_imsi), pars1);
	vc_conn1.done;
	f_ctrs_cn_expect(0, "cnpool:subscr:paged");
	f_shutdown_helper();
}

/* Make sure that whichever MSC paged a subscriber will also get the Paging Response.  Page by TMSI with an NRI value
 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
friend function f_tc_mscpool_paging_tmsi(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	f_init_handler(pars);

	var hexstring imsi := '001010000000124'H;
	var integer nri_v := 300; /* <-- second MSC's NRI */
	var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);

	var RANAP_IEs.CN_DomainIndicator domain_ind;
	if (pars.ps_domain) {
		domain_ind := ps_domain;
	} else {
		domain_ind := cs_domain;
	}
	var template (value) RANAP_PDU paging := ts_RANAP_Paging_temp_id(domain_ind, imsi_hex2oct(imsi),
									 ts_RANAP_TemporaryUE_ID_TMSI(tmsi));
	BSSAP.send(ts_RANAP_UNITDATA_req(pars.sccp_addr_hnbgw, pars.sccp_addr_msc, paging));
	/* TODO: Expect RUA ConnectionlessTransfer Paging (on all HNB).
	 * We could verify the Paging sent from osmo-hnbgw to RUA with some effort,
	 * but, this test does not care whether the Paging was forwarded to RUA or not, only that osmo-hnbgw *received*
	 * the Paging. In the CN pool decisions, osmo-hnbgw should match up Paging Response to an earlier Paging.
	 */

	f_sleep(1.0);

	/* Despite the round robin pointing at the third MSC ('roundrobin next msc 2'), the earlier Paging for the same
	 * TMSI causes this Paging Response to go to the first MSC ('msc 0'). */
	f_perform_compl_l3(f_gen_one_compl_l3(PAGRESP, ts_MI_TMSI_NRI_LV(nri_v)));
	f_sleep(1.0);
}
testcase TC_mscpool_paging_tmsi() runs on test_CT {
	f_init(nr_msc := 3);
	f_sleep(1.0);

	var boolean ps_domain := false;

	/* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
	 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ConnHdlr vc_conn1;
	var template (value) TestHdlrParams pars1 := t_pars(0, ps_domain := ps_domain, cn_nr := 0);
	pars1.sccp_addr_hnbgw := g_cn[valueof(pars1.cn_idx)].sccp_addr_peer;
	pars1.sccp_addr_msc := g_cn[valueof(pars1.cn_idx)].sccp_addr_own;
	vc_conn1 := f_start_handler_with_pars(refers(f_tc_mscpool_paging_tmsi), pars1);
	vc_conn1.done;
	f_ctrs_cn_expect(0, "cnpool:subscr:paged");
	f_shutdown_helper();
}

/* For round-robin, skip a CN link that has 'no allow-attach' set. */
testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {

	f_init(nr_msc := 3);
	f_sleep(1.0);

	var boolean ps_domain := false;

	/* Mark the second MSC as offloading, round-robin should skip this MSC now. */
	f_vty_cnlink_allow_attach(HNBGWVTY, ps_domain, {true, false, true});

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	f_TC_cnpool_compl_l3_list(ps_domain, f_gen_compl3_by_domain(ps_domain, 3),
				  /* msc 1 is skipped */
				  {0, 2, 0},
				  "cnpool:subscr:new");

	f_shutdown_helper();
}

/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
 * TMSI NRI. */
testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {

	f_init(nr_msc := 3);
	f_sleep(1.0);

	var boolean ps_domain := false;

	/* Mark the second MSC as offloading, round-robin should skip this MSC now. */
	f_vty_cnlink_allow_attach(HNBGWVTY, ps_domain, {true, false, true});

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_MobileIdentityLV mis := {
		valueof(ts_MI_TMSI_NRI_LV(260)),
		valueof(ts_MI_IMSI_LV('001010000000002'H)),
		valueof(ts_MI_IMSI_LV('001010000000003'H))
	};

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 3, mis);

	/* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
	f_TC_cnpool_compl_l3(ps_domain, compl3[0], cn_nr := 1, inc_countername := "cnpool:subscr:known");

	/* Normal round robin skips msc 1, because it has 'no allow-attach' */
	f_TC_cnpool_compl_l3(ps_domain, compl3[1], cn_nr := 0, inc_countername := "cnpool:subscr:new");
	f_TC_cnpool_compl_l3(ps_domain, compl3[2], cn_nr := 2, inc_countername := "cnpool:subscr:new");

	f_shutdown_helper();
}

/* When a peer point-code gets an SCCP N-PCSTATE saying it is unreachable, immediately mark the CN link as unusable. */
testcase TC_mscpool_sccp_n_pcstate_detaches_cnlink() runs on test_CT {
	f_TC_cnpool_sccp_n_pcstate_detaches_cnlink(ps_domain := false);
}
testcase TC_sgsnpool_sccp_n_pcstate_detaches_cnlink() runs on test_CT {
	f_TC_cnpool_sccp_n_pcstate_detaches_cnlink(ps_domain := true);
}
function f_TC_cnpool_sccp_n_pcstate_detaches_cnlink(boolean ps_domain) runs on test_CT
{

	f_init(nr_msc := 2, nr_sgsn := 2);
	f_sleep(1.0);

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	f_ctrs_cn_init(ps_domain := ps_domain);

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 3);

	f_TC_cnpool_compl_l3(ps_domain, compl3[0], cn_nr := 0, inc_countername := "cnpool:subscr:new");
	f_TC_cnpool_compl_l3(ps_domain, compl3[1], cn_nr := 1, inc_countername := "cnpool:subscr:new");

	f_logp(HNBGWVTY, "disconnecting msc0");
	f_cn_idx_disconnect(f_cn_idx(ps_domain, 0));

	/* Now round-robin would wrap to the first MSC, but since the first MSC is disconnected, it wraps around to the
	 * second. */
	f_TC_cnpool_compl_l3(ps_domain, compl3[2], cn_nr := 1, inc_countername := "cnpool:subscr:new");

	f_shutdown_helper();
}

/* When a CN link point-code gets an SCCP N-PCSTATE saying it is now reachable, immediately trigger RESET and bring up the
 * MSC. */
testcase TC_mscpool_sccp_n_pcstate_attaches_cnlink() runs on test_CT {
	f_TC_cnpool_sccp_n_pcstate_attaches_cnlink(ps_domain := false);
}
testcase TC_sgsnpool_sccp_n_pcstate_attaches_cnlink() runs on test_CT {
	f_TC_cnpool_sccp_n_pcstate_attaches_cnlink(ps_domain := true);
}
function f_TC_cnpool_sccp_n_pcstate_attaches_cnlink(boolean ps_domain) runs on test_CT
{
	f_init(nr_msc := 1, nr_sgsn := 1);
	f_sleep(1.0);

	/* Control which MSC gets chosen next by the round-robin, otherwise
	 * would be randomly affected by which other tests ran before this. */
	f_vty_set_roundrobin_next(HNBGWVTY, ps_domain, 0);

	var ro_octetstring compl3 := f_gen_compl3_by_domain(ps_domain, 3);

	f_ctrs_cn_init(ps_domain := ps_domain);

	/* There is only one MSC, round robin stays on msc0 */
	f_TC_cnpool_compl_l3(ps_domain := ps_domain, nas_pdu := compl3[0], cn_nr := 0, inc_countername := "cnpool:subscr:new");
	f_TC_cnpool_compl_l3(ps_domain := ps_domain, nas_pdu := compl3[1], cn_nr := 0, inc_countername := "cnpool:subscr:new");

	f_logp(HNBGWVTY, "connecting cnlink 1");
	f_cn_nr_init(ps_domain, 1);
	f_vty_cnlink_allow_attach(HNBGWVTY, ps_domain, { true, true });
	f_sleep(1.0);

	/* This time round-robin wraps to the second MSC, because it is now online. */
	f_TC_cnpool_compl_l3(ps_domain := ps_domain, nas_pdu := compl3[2], cn_nr := 1, inc_countername := "cnpool:subscr:new");

	f_shutdown_helper();
}

private function f_vty_add_sccp_addr(TELNETasp_PT pt, charstring addr_name, charstring pc, integer cs7_nr := 0)
{
	f_vty_enter_config(pt);
	f_vty_transceive(pt, "cs7 instance 0");
	f_vty_transceive(pt, "sccp-address " & addr_name);
	f_vty_transceive(pt, "point-code " & pc);
	f_vty_transceive(pt, "end");
}

private function f_vty_set_cnlink_addr(TELNETasp_PT pt, charstring cnlink_and_nr, charstring addr_name)
{
	f_vty_enter_config(pt);
	f_vty_transceive(pt, cnlink_and_nr);
	f_vty_transceive(pt, "remote-addr " & addr_name);
	f_vty_transceive(pt, "end");
}

private function f_vty_apply_sccp(TELNETasp_PT pt)
{
	f_vty_enter_config(pt);
	f_vty_transceive(pt, "apply sccp");
	f_vty_transceive(pt, "end");
}

template (present) RUA_Disc_Req tr_RUA_Disc_Req := {
	ranap := ?,
	cause := ?
};

/* With a cnlink up, change the SCCP address, and verify that it restarts upon vty 'apply sccp' */
private function f_tc_apply_sccp(charstring id, TestHdlrParams pars) runs on ConnHdlr
{
	f_init_handler(pars);
	f_perform_compl_l3(f_gen_compl3_by_domain(pars.ps_domain, 1)[0]);

	f_sleep(1.0);
	f_logp(HNBGWVTY, "Changing SCCP address, don't apply yet");

	f_vty_add_sccp_addr(HNBGWVTY, "msc-foo", "0.42.4");
	f_vty_set_cnlink_addr(HNBGWVTY, "msc 0", "msc-foo");

	/* No effect yet, link still open both ways */
	f_sleep(1.0);
	f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
	f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));

	f_logp(HNBGWVTY, "Apply SCCP address changes");
	f_vty_apply_sccp(HNBGWVTY);

	/* We modified the SCCP configuration, expect disconnect of UE that was active on the aborted link. */
	RUA.receive(RUA_Disc_Ind:?);
	BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND);

	/* Would be nice to test reconnection on the other point-code, too. That would require another cnlink in
	 * osmo-stp.cfg and module parameters... */

	f_sleep(1.0);
}
testcase TC_apply_sccp() runs on test_CT
{
	f_init();
	f_sleep(1.0);

	var ConnHdlr vc_conn;
	var template (value) TestHdlrParams pars := t_pars(0);
	vc_conn := f_start_handler_with_pars(refers(f_tc_apply_sccp), pars);
	vc_conn.done;

	f_shutdown_helper();
}

/* In the field, we encountered a "normal" RAB Assignment that concludes successfully, followed by another RAB
 * Assignment that has different SDU subflow parameters, and does not contain RTP information. At the time of writing,
 * it seems that the second RAB Assignment causes a crash. Play through this scenario. */
friend function f_tc_second_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 5.0;

	f_init_handler(pars);
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});

	tx := f_build_initial_ue(g_pars);
	f_iuh2iu_connect(tx);

	f_create_rab(pars.mgcp_pars);

	/* Now send a second RAB Assignment with different subflows and omitting transportLayerInformation. (Assuming
	 * the first RAB Assignment's transportLayerInformation remains in use unchanged.) */
	var template RAB_SetupOrModifyList rab_sml;
	rab_sml := ts_RAB_SML2(t_RAB_id(23),
			       ts_RabParams,
			       user_plane_info := omit,
			       transport_layer_info := omit);
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));
	BSSAP.send(tx);
	T.start;

	/* Expect this secondary RAB Assignment to go through unchanged. */
	f_rua_expect(tx);

	/* I'm guessing that the RAB Assignment Response also omits transportLayerInformation, so far not known because
	 * osmo-hnbgw crashed before we could receive the response. */

	/* Send back RAB Assignment Response via Iuh */
	var template RAB_SetupOrModifiedList rab_smdl;
	rab_smdl := ts_RAB_SMdL_no_tla(t_RAB_id(23));
	tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
	RUA.send(tx);
	f_bssap_expect(tx);

	/* Send Iu Release */
	tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
	f_iu2iuh(tx);

	T.start;
	alt {
	[] as_mgcp_dlcx(pars) {}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for DLCX");
	}
	}

	tx := valueof(ts_RANAP_IuReleaseComplete());
	f_iuh2iu(tx);
}

testcase TC_second_rab_assignment() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();

	vc_conn := f_start_handler_with_pars(refers(f_tc_second_rab_assignment), t_pars(3));
	vc_conn.done;

	f_shutdown_helper();
}

control {
	execute(TC_hnb_register());
	execute(TC_hnb_register_duplicate());
	execute(TC_hnb_register_duplicate_reuse_sctp_assoc());
	execute(TC_ranap_cs_initial_ue());
	execute(TC_ranap_ps_initial_ue());
	execute(TC_ranap_cs_initial_ue_empty_cr());
	execute(TC_ranap_ps_initial_ue_empty_cr());
	execute(TC_ranap_cs_bidir());
	execute(TC_ranap_ps_bidir());
	execute(TC_rab_assignment());
	execute(TC_rab_release());
	execute(TC_rab_assign_fail());
	execute(TC_rab_assign_mgcp_to());
	execute(TC_rab_assign_mgw_iuup_addr_chg());
	execute(TC_ranap_cs_mo_disconnect());
	execute(TC_ranap_ps_mo_disconnect());

	if (mp_enable_pfcp_tests) {
		execute(TC_ps_rab_assignment_with_pfcp());
	} else {
		execute(TC_ps_rab_assignment_without_pfcp());
	}

	execute( TC_mscpool_L3Compl_on_1_cnlink() );
	execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
	execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
	execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
	execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
	execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
	execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
	execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
	execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
	execute( TC_mscpool_paging_imsi() );
	execute( TC_mscpool_paging_tmsi() );
	execute( TC_mscpool_no_allow_attach_round_robin() );
	execute( TC_mscpool_no_allow_attach_valid_nri() );
	execute( TC_mscpool_sccp_n_pcstate_detaches_cnlink() );
	execute( TC_mscpool_sccp_n_pcstate_attaches_cnlink() );

	execute( TC_sgsnpool_L3Compl_on_1_cnlink() );
	execute( TC_sgsnpool_L3Complete_no_nri_round_robin() );
	execute( TC_sgsnpool_L3Complete_valid_nri_1() );
	execute( TC_sgsnpool_L3Complete_valid_nri_2() );
	execute( TC_sgsnpool_nri_from_other_PLMN() );
	execute( TC_sgsnpool_sccp_n_pcstate_detaches_cnlink() );
	execute( TC_sgsnpool_sccp_n_pcstate_attaches_cnlink() );

	/* Run only on nightly since it makes osmo-hnbgw <= 1.5.0 crash: OS#6253 */
	if (f_osmo_repo_is("nightly")) {
		execute(TC_second_rab_assignment());
	}

	/* Run at the end since it makes osmo-hnbgw <= 1.3.0 crash: OS#5676 */
	execute(TC_hnb_reregister_reuse_sctp_assoc());

	/* Run at the end since it messes with the SCCP config */
	execute( TC_apply_sccp() );
}

}
