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_IEs 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 SDP_Templates 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;

	/* Our emulated StatsD server: */
	charstring mp_local_statsd_ip := "127.0.0.1";
	integer mp_local_statsd_port := 8125;

	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,
	/* RAB release cause */
	RANAP_IEs.Cause rab_rel_cause
}

/* 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)
   * StatsD_ConnHdlr (for the statsd interface, verifying counters)
 */
type component ConnHdlr extends RAN_ConnHdlr, MGCP_ConnHdlr, RUA_ConnHdlr, PFCP_ConnHdlr, StatsD_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, StatsD_Checker_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;
	var StatsD_Checker_CT vc_STATSD;
	/* 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());

	f_init_statsd("VirtHNBGW", vc_STATSD, mp_local_statsd_ip, mp_local_statsd_port);

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

	connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_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 RANAP_IEs.LAI lai := {
		pLMNidentity := hex2oct(pars.hnb.lai.mcc_mnc),
		lAC := int2oct(pars.hnb.lai.lac, 2),
		iE_Extensions := omit
	};
	var RANAP_IEs.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 RANAP_IEs.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_hnb_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)),
					hex2oct(g_hnb_cfg[hnb_idx].lai.mcc_mnc),
					int2bit(1 + cell_id, 28),
					int2oct(g_hnb_cfg[hnb_idx].lai.lac, 2),
					int2oct(0, 1),
					int2oct(g_hnb_cfg[hnb_idx].sac, 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");
	}
	}
}

function f_hnbap_ue_register(integer hnb_idx := 0, template (present) UE_Identity ue_id, boolean expect_reject := false) runs on test_CT
{
	timer T := 2.0;

	HNBAP[hnb_idx].send(ts_HNBAP_UERegisterRequest(ue_id));

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


testcase TC_hnb_register() runs on test_CT {
	g_num_hnbs := 1;
	f_init(start_hnb := false);
	f_hnbap_hnb_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);

	/* Make HNB REQ look as if it came from the same HnodeB (LAI+SAC),
	 * but from different IP address (underlaying link): */
	g_hnb_cfg[1] := g_hnb_cfg[0];
	f_hnbap_hnb_register(0);
	f_hnbap_hnb_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_hnb_register(0);
	f_hnbap_hnb_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_hnb_register(0);
	HNBAP[0].send(ts_HNBAP_HNBDe_Register(ts_HnbapCause(unspecified)));
	f_hnbap_hnb_register(0);
	f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
	f_shutdown_helper();
}

/* regular UE registration */
testcase TC_ue_register() runs on test_CT {
	var UE_Identity ue_id := { iMSI := imsi_hex2oct(f_gen_imsi(1)) };
	g_num_hnbs := 1;
	f_init(start_hnb := true);
	f_hnbap_ue_register(0, ue_id);
	f_shutdown_helper();
}

/* regular UE registration (UE Identity: TMSI+LAI) */
testcase TC_ue_register_tmsi_lai() runs on test_CT {
	var UE_Identity ue_id := { tMSILAI := { tMSI := oct2bit(f_gen_tmsi(0)),
						lAI := { pLMNID := '00F110'O, lAC := '2342'O }
					      }
				 };
	g_num_hnbs := 1;
	f_init(start_hnb := true);
	f_hnbap_ue_register(0, ue_id);
	f_shutdown_helper();
}


/* UE registration from unregistered HNB */
testcase TC_ue_register_before_hnb_register() runs on test_CT {
	var UE_Identity ue_id := { iMSI := imsi_hex2oct(f_gen_imsi(1)) };
	g_num_hnbs := 1;
	f_init(start_hnb := false);
	f_hnbap_ue_register(0, ue_id, expect_reject := true);
	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, template (value) RANAP_IEs.Cause rab_rel_cause := ts_RanapCause_nas_normal) := {
	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,
	rab_rel_cause := rab_rel_cause
}

/* 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 {
	const charstring hnb0_ctr_prefix := "TTCN3.hnb.001-01-L2342-R0-S55-C1.";
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 5.0;

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

	f_statsd_reset();

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

	/* Expect stats to be 0 */
	var StatsDExpects expect := {
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.req", mtype := "c", min := 0, max := 0},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.cnf", mtype := "c", min := 0, max := 0},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.fail", mtype := "c", min := 0, max := 0}
	};
	if (f_osmo_repo_is("nightly")) {
		f_statsd_expect(expect);
	}

	f_create_rab(pars.mgcp_pars);

	expect := {
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.req", mtype := "c", min := 1, max := 1},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.cnf", mtype := "c", min := 1, max := 1},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.fail", mtype := "c", min := 0, max := 0}
	};
	if (f_osmo_repo_is("nightly")) {
		f_statsd_expect(expect);
	}

	/* Send Iu Release */
	tx := valueof(ts_RANAP_IuReleaseCommand(pars.rab_rel_cause));
	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 {
	const charstring hnb0_ctr_prefix := "TTCN3.hnb.001-01-L2342-R0-S55-C1.";
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 5.0;

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

	f_statsd_reset();

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

	/* Expect stats to be 0 */
	var StatsDExpects expect := {
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.req", mtype := "c", min := 0, max := 0},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.cnf", mtype := "c", min := 0, max := 0},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.fail", mtype := "c", min := 0, max := 0}
	};
	if (f_osmo_repo_is("nightly")) {
		f_statsd_expect(expect);
	}

	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), pars.rab_rel_cause)));
	f_iuh2iu(tx);

	expect := {
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.req", mtype := "c", min := 1, max := 1},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.cnf", mtype := "c", min := 0, max := 0},
		{name := hnb0_ctr_prefix & "ranap.cs.rab_act.fail", mtype := "c", min := 1, max := 1}
	};
	if (f_osmo_repo_is("nightly")) {
		f_statsd_expect(expect);
	}


	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, rab_rel_cause := ts_RanapCause_radio_conn_lost));
	vc_conn.done;

	f_shutdown_helper();
}

friend function f_tc_rab_release(charstring id, TestHdlrParams pars) runs on ConnHdlr {
	const charstring hnb0_ctr_prefix := "TTCN3.hnb.001-01-L2342-R0-S55-C1.";
	var MgcpCommand mgcp_cmd;
	var RANAP_PDU tx;
	timer T := 15.0;

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

	f_statsd_reset();

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

	f_create_rab(pars.mgcp_pars);

	var charstring ctr_name;
	if (pars.rab_rel_cause == valueof(ts_RanapCause_nas_normal)) {
		ctr_name := "ranap.cs.rab_rel.req.normal";
	} else {
		ctr_name := "ranap.cs.rab_rel.req.abnormal";
	}

	/* Expect stats to be 0 */
	var StatsDExpects expect := {
		{name := hnb0_ctr_prefix & ctr_name, mtype := "c", min := 0, max := 0}
	};
	if (f_osmo_repo_is("nightly")) {
		f_statsd_expect(expect);
	}

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

	expect := {
		{name := hnb0_ctr_prefix & ctr_name, mtype := "c", min := 1, max := 1}
	};
	if (f_osmo_repo_is("nightly")) {
		f_statsd_expect(expect);
	}

	T.start;

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

	f_rua_expect(tx);
}

/* RAB release with Cause NAS/Normal (successful/orderly release) */
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();
}

/* RAB release with Cause abnormal */
testcase TC_rab_release_abnormal() 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(8, rab_rel_cause := ts_RanapCause_radio_conn_lost));
	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(pars.rab_rel_cause));
	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(pars.rab_rel_cause));
	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(pars.rab_rel_cause));
	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(pars.rab_rel_cause));
	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_ue_register());
	execute(TC_ue_register_tmsi_lai());
	execute(TC_ue_register_before_hnb_register());
	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_release_abnormal());
	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() );
}

}
