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 {
	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.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");
		}
	}
	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_1.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_1.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;
	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");
	}
	}
	T.stop;

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

private function f_pfcp_expect(template (present) PDU_PFCP exp_rx) runs on ConnHdlr return PDU_PFCP
{
	var PDU_PFCP rx;
	timer T := 5.0;
	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())
	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);
	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);

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

}
