module HNBGW_Tests {

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

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

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

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

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

import from HNBAP_Templates all;
import from HNBAP_PDU_Descriptions all;

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

import from Iuh_Emulation all;

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

import from RAN_Adapter all;
import from RAN_Emulation all;

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

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

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;

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

	RAN_Configuration mp_msc_cfg := {
		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
	};
	RAN_Configuration mp_sgsn_cfg := {
		transport := RANAP_TRANSPORT_IuCS,
		sccp_service_type := "mtp3_itu",
		sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
		own_pc := 185,	/* 0.23.1 first SGSN emulation */
		own_ssn := 142,
		peer_pc := 189, /* 0.23.5 osmo-hnbgw */
		peer_ssn := 142,
		sio := '83'O,
		rctx := 2
	};

	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";
}

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

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 CrcxResponse {
	integer resp,
	HostName mgw_rtp_ip,
	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,
	CrcxResponse mgw_conn_1,
	CrcxResponse mgw_conn_2,
	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_1 := {
		resp := 1,
		mgw_rtp_ip := "127.1.2.1",
		mgw_rtp_port := 10000,
		mgcp_connection_id := '11111'H
	},
	mgw_conn_2 := {
		resp := 1,
		mgw_rtp_ip := "127.1.2.2",
		mgw_rtp_port := 20000,
		mgcp_connection_id := '22222'H
	},
	rtp_payload_type := 23,
	rtp_sdp_format := "FOO",
	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,
	hexstring imsi,
	boolean ps_domain,
	MgcpParameters mgcp_pars optional,
	HnbConfig hnb optional,
	boolean separate_sccp_cr,
	charstring pfcp_local_addr
}

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

	port TELNETasp_PT HNBGWVTY;
}


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

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


const integer NUM_HNB := 2;

type record HnbConfig {
	LocationAreaIdentification lai,
	integer sac
}

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

	/********************* Iu side */
	var RAN_Adapter g_msc;
	var RAN_Adapter g_sgsn;
	/* SGSN IuPS missing */

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

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

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

friend function f_logp(TELNETasp_PT pt, charstring log_msg)
{
	// log on TTCN3 log output
	log(log_msg);
	// log in stderr log
	f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
}

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

/* global initialization function */
function f_init(charstring id := "HNBGW", float guard_timeout := 30.0) runs on test_CT {

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

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

	/* MSC emulation */
	var RanOps ranops := {
		ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
		ranap_unitdata_cb := omit,
		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
	};
	f_ran_adapter_init(g_msc, mp_msc_cfg, "HNBGW_Test", ranops);
	f_ran_adapter_start(g_msc);

	/* SGSN emulation */
	ranops.ps_domain := true;
	f_ran_adapter_init(g_sgsn, mp_sgsn_cfg, "HNBGW_Test", ranops);
	f_ran_adapter_start(g_sgsn);

	f_init_mgcp(id);
	f_init_vty("VirtHNBGW");
}

friend function f_shutdown_helper() runs on test_CT {
	all component.stop;
	setverdict(pass);
	mtc.stop;
}

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

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

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

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

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

	vc_conn := ConnHdlr.create(id);

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

	if (pars.ps_domain) {
		/* SGSN side */
		connect(vc_conn:BSSAP, g_sgsn.vc_RAN:CLIENT);
		connect(vc_conn:BSSAP_PROC, g_sgsn.vc_RAN:PROC);
	} else {
		/* MSC side */
		connect(vc_conn:BSSAP, g_msc.vc_RAN:CLIENT);
		connect(vc_conn:BSSAP_PROC, g_msc.vc_RAN:PROC);
	}
	/* MGCP part */
	connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
	connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);

	return vc_conn;
}

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

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

/* 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);
	T.start;

	alt {
	[] BSSAP.receive(exp_rx) -> value rx {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iu ", exp_rx);
		}
	}
	return 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 {
	var RANAP_PDU rx;
	timer T := 5.0;

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

	BSSAP.send(tx);
	T.start;

	alt {
	[] RUA.receive(exp_rx) -> value rx {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iuh ", exp_rx);
		}
	}
	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.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.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 */
	T.start;
	alt {
	[] BSSAP.receive(exp_rx) -> value rx {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iu ", exp_rx);
		}
	}
	return 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 := 10.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 */
	T.start;
	alt {
	[] BSSAP.receive(exp_rx) -> value rx {
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iu ", exp_rx);
		return rx;
		}
	}

	/* expect disconnect on the Iu side */
	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;
}

/* build a RANAP InitialUE based on the TestHdlrParams */
friend function f_build_initial_ue(TestHdlrParams pars) return RANAP_PDU {
	var LAI lai := {
		pLMNidentity := hex2oct(pars.hnb.lai.mcc_mnc),
		lAC := int2oct(pars.hnb.lai.lac, 2),
		iE_Extensions := omit
	};
	var SAI sai := {
		pLMNidentity := lai.pLMNidentity,
		lAC := lai.lAC,
		sAC := int2oct(pars.hnb.sac, 2),
		iE_Extensions := omit
	}
	var octetstring nas;
	if (pars.separate_sccp_cr) {
		/* 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. */
		nas := f_rnd_octstring(131);
	} else {
		nas := f_rnd_octstring(10);
	}
	var IuSignallingConnectionIdentifier sigc_id := int2bit(f_rnd_int(1000), 24);
	var GlobalRNC_ID grnc_id := {
		pLMNidentity := lai.pLMNidentity,
		rNC_ID := 2342
	}

	if (pars.ps_domain) {
		var RAC rac := '00'O;
		return valueof(ts_RANAP_initialUE_PS(lai, rac, sai, nas, sigc_id, grnc_id));
	} else {
		return valueof(ts_RANAP_initialUE_CS(lai, sai, nas, sigc_id, grnc_id));
	}
}

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

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

	return valueof(ts_RANAP_RabAssResp(rab_sml));
}


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


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

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

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

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

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

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

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

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

private template (value) TestHdlrParams
t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
       boolean separate_sccp_cr := false) := {
	hnb_idx := hnb_idx,
	imsi := f_gen_imsi(imsi_suffix),
	ps_domain := ps_domain,
	hnb := omit,	/* filled in later */
	separate_sccp_cr := separate_sccp_cr,
	pfcp_local_addr := mp_pfcp_ip_local
}

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

	vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1));
	vc_conn.done;
}
testcase TC_ranap_ps_initial_ue() runs on test_CT {
	var ConnHdlr vc_conn;

	g_num_hnbs := 1;
	f_init();
	f_start_hnbs();

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

private function f_vty_set_sccp_cr_max_payload_len(TELNETasp_PT pt, integer val := 999999)
{
	f_vty_enter_config(pt);
	f_vty_transceive(pt, "hnbgw");
	f_vty_transceive(pt, "sccp cr max-payload-len " & int2str(val));
	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_start_hnbs();

	f_vty_set_sccp_cr_max_payload_len(HNBGWVTY, 0);

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

	/* reset */
	f_vty_set_sccp_cr_max_payload_len(HNBGWVTY);
}
testcase TC_ranap_ps_initial_ue_empty_cr() runs on test_CT {
	var ConnHdlr vc_conn;

	g_num_hnbs := 1;
	f_init();
	f_start_hnbs();

	f_vty_set_sccp_cr_max_payload_len(HNBGWVTY, 0);

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

	/* reset */
	f_vty_set_sccp_cr_max_payload_len(HNBGWVTY);
}

/* 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 CrcxResponse conn := pars.mgw_conn_1;
	if (pars.got_crcx_count > 0) {
		conn := pars.mgw_conn_2;
	}
	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");
		}
	}

	/* 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_1.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_1.mgw_rtp_port));
	tx := valueof(ts_RANAP_RabAssReq(rab_sml));

	alt {
	[] RUA.receive(tx) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iuh ", 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;
	timer T := 5.0;

	/* 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);
	T.start;

	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 {
		log("MDCX1", mgcp_cmd);
		/* Verify SDP of MDCX */
		var SDP_Message sdp := valueof(ts_SDP(pars.mgw_conn_1.mgw_rtp_ip, pars.mgw_conn_1.mgw_rtp_ip, hex2str(pars.mgcp_call_id), "42", pars.mgw_conn_1.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_1.mgcp_connection_id, sdp);
		MGCP.send(valueof(mgcp_rsp));
		}
	/* 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_2.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_2.mgw_rtp_port));
	tx := valueof(ts_RANAP_RabAssResp(rab_smdl));

	alt {
	[] BSSAP.receive(tx) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iuh ", tx);
		}
	}
}

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

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

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

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

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

	f_create_rab(pars.mgcp_pars);

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

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

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

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

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

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

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

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

	f_rab_ass_req(pars.mgcp_pars);

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

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

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

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

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

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

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

	f_create_rab(pars.mgcp_pars);

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

	T.start;

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

	alt {
	[] RUA.receive(tx) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Iuh ", tx);
		}
	}

}

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

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

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

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

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


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

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

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

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

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

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

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

	vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(3));
	vc_conn.done;
}
testcase TC_ranap_ps_bidir() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();
	f_start_hnbs();

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


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();
	f_start_hnbs();

	vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(5));
	vc_conn.done;
}
testcase TC_ranap_ps_mo_disconnect() runs on test_CT {
	var ConnHdlr vc_conn;
	g_num_hnbs := 1;
	f_init();
	f_start_hnbs();

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

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

friend function f_tc_ps_rab_assignment_with_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();

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

	PFCP.receive(tr_PFCP_Assoc_Setup_Req()) -> value m;
	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. */
	PFCP.receive(tr_PFCP_Session_Est_Req()) -> value m;
	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));
	RUA.receive(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);
	T.start;

	PFCP.receive(tr_PFCP_Session_Mod_Req(up_f_seid.seid)) -> value m;
	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);
	BSSAP.receive(tr_RANAP_RabAssResp(rab_smdl));

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

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

	PFCP.receive(tr_PFCP_Session_Del_Req(up_f_seid.seid)) -> value m;
	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_start_hnbs();
	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;
}

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));
	RUA.receive(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 */
	BSSAP.receive(tr_RANAP_RabAssResp(rab_smdl));

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

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

	f_sleep(2.0);
}

testcase TC_ps_rab_assignment_without_pfcp() runs on test_CT {
	var ConnHdlr vc_conn;
	f_init();
	f_start_hnbs();
	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;
}

control {
	execute(TC_hnb_register());
	execute(TC_hnb_register_duplicate());
	execute(TC_hnb_register_duplicate_reuse_sctp_assoc());
	execute(TC_ranap_cs_initial_ue());
	execute(TC_ranap_ps_initial_ue());
	execute(TC_ranap_cs_initial_ue_empty_cr());
	execute(TC_ranap_ps_initial_ue_empty_cr());
	execute(TC_ranap_cs_bidir());
	execute(TC_ranap_ps_bidir());
	execute(TC_rab_assignment());
	execute(TC_rab_release());
	execute(TC_rab_assign_fail());
	execute(TC_rab_assign_mgcp_to());
	execute(TC_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());
	}

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

}
