module HNB_Tests {

/* Integration Tests for OsmoHNodeB
 * (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 OsmoHNodB while emulating both multiple UE as
 * well as the HNBGW. See README for more details.
 *
 * There are test cases that run in so-called 'handler mode' and test cases
 * that run directly on top of the BSSAP and RSL CodecPorts.  The "handler mode"
 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
 * and/or RSL channels and are hence suitable for higher-level test cases, while
 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
 * level testing.
 */

import from Misc_Helpers all;
import from General_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 RUA_IEs all;
import from RUA_Templates all;

import from HNBGW_ConnectionHandler all;
import from Iuh_Emulation all;

import from RTP_Types all;
import from RTP_Emulation all;

import from HNBLLIF_CodecPort all;
import from HNBLLIF_Types all;
import from HNBLLIF_Templates all;

import from GTPU_Types all;
import from GTP_Templates all;
import from GTP_Emulation all;

import from IuUP_Types all;

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

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

	charstring mp_hnbllif_sk_path := HNBLL_SOCK_DEFAULT;
}

const hexstring ranap_cm_service_req := '001340400000060003400100000f40060000f11028b6003a40080000f110ffffffff0010400e0d052411035758a605f44e9d4aef004f400300001c0056400500f1100017'H;
const hexstring ranap_auth_req := '00144032000002001040262505120217dc146aeac56cb5ff6d5fb51f47f19220108ca5a6d0c8110000b9e9272498872764003b400100'H;
const hexstring ranap_auth_resp := '001440140000010010400d0c0554ccbdd0302104002f3ae4'H;
const hexstring ranap_paging := '000e401e0000030003400100001740095000010100000000f10040400500b6cf4773'H;
const hexstring ranap_rab_ass_req := '0000005900000100364052000001003500487824cd80102fa7201a2c0000f44c080a028000514000272028140067400000222814003c40000000503d02000227c03500010a0901a200000000000000000000000000401f4a0000400100'H;
const hexstring iu_release_compl := '20010003000000'H;

type component test_CT extends CTRL_Adapter_CT {
	port TELNETasp_PT HNBVTY;

	/* HNBLLIF Interface of HNodeB */
	port HNBLLIF_CODEC_PT LLSK;
	var integer g_llsk_conn_id;

	/* 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 (HNBVTY.checkstate("Mapped")) {
		/* skip initialization if already executed once */
		return;
	}
	map(self:HNBVTY, system:HNBVTY);
	f_vty_set_prompts(HNBVTY);
	f_vty_transceive(HNBVTY, "enable");
}

private function f_init_hnbllif() runs on test_CT {
	map(self:LLSK, system:LLSK);
	f_start_hnbllif(LLSK, testcasename(), mp_hnbllif_sk_path, g_llsk_conn_id);
}

/* global initialization function */
function f_init(float guard_timeout := 30.0) runs on test_CT {
	var integer bssap_idx;

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

	f_init_vty("VirtHNBGW");
}

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

private function f_gen_test_hdlr_pars() runs on test_CT return TestHdlrParams {

	var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
	pars.hnbllif_sk_path := mp_hnbllif_sk_path;
	pars.hnodeb_addr := mp_hnodeb_ip;
	pars.hnbgw_addr := mp_hnbgw_iuh_ip;
	pars.hnbgw_port := mp_hnbgw_iuh_port;
	return pars;
}

type function void_fn(charstring id) runs on HNBGW_ConnHdlr;

/* helper function to create and connect a HNBGW_ConnHdlr component */
private function f_connect_handler(inout HNBGW_ConnHdlr vc_conn, TestHdlrParams pars) runs on test_CT {
	if (pars.hnbllif_sk_path != "") {
		map(vc_conn:LLSK, system:LLSK);
	}
}

function f_start_handler_create(TestHdlrParams pars)
runs on test_CT return HNBGW_ConnHdlr {
	var charstring id := testcasename();
	var HNBGW_ConnHdlr vc_conn;
	vc_conn := HNBGW_ConnHdlr.create(id);
	f_connect_handler(vc_conn, pars);
	return vc_conn;
}

function f_start_handler_run(HNBGW_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars)
runs on test_CT return HNBGW_ConnHdlr {
	var charstring id := testcasename();
	/* Emit a marker to appear in the SUT's own logging output */
	f_logp(HNBVTY, id & "() start");
	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit)
runs on test_CT return HNBGW_ConnHdlr {
	var TestHdlrParams pars;
	if (isvalue(pars)) {
		pars := valueof(pars_tmpl);
	} else {
		pars := valueof(f_gen_test_hdlr_pars());
	}
	return f_start_handler_run(f_start_handler_create(pars), fn, pars);
}

/* first function inside ConnHdlr component; sets g_pars + starts function */
private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars)
runs on HNBGW_ConnHdlr {
	f_HNBGW_ConnHdlr_init(id, pars);
	HNBAP.receive(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* Wait for HNB to connect to us */
	fn.apply(id);
}

private function f_tc_hnb_register_request_accept(charstring id) runs on HNBGW_ConnHdlr {
	f_handle_hnbap_hnb_register_req();
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
						  g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
	f_sleep(1.0);
}
testcase TC_hnb_register_request_accept() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;

	f_init();
	vc_conn := f_start_handler(refers(f_tc_hnb_register_request_accept));
	vc_conn.done;
	f_shutdown_helper();
}

private function f_tc_hnb_register_reject(charstring id) runs on HNBGW_ConnHdlr {
	HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
						  f_enc_mcc_mnc(g_pars.mcc, g_pars.mnc),
						  int2bit(g_pars.cell_identity, 28),
						  int2oct(g_pars.lac, 2),
						  int2oct(g_pars.rac, 1),
						  int2oct(g_pars.sac, 2)
						 ));
	HNBAP.send(ts_HNBAP_HNBRegisterReject(ts_HnbapCause(overload)));
	f_sleep(1.0);
}
testcase TC_hnb_register_request_reject() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;

	f_init();
	vc_conn := f_start_handler(refers(f_tc_hnb_register_reject));
	vc_conn.done;
	f_shutdown_helper();
}

private function f_tc_mo_conn(charstring id) runs on HNBGW_ConnHdlr {
	const integer context_id := 30;
	const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
	const Establishment_Cause est_cause := normal_call;
	f_handle_hnbap_hnb_register_req();

	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
						  g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));

	/* Now an UE attempts CM Service Request: */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
	/* The related RUA Connect + RANAP message is received on Iuh: */
	RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));

	/* Now HNBGW answers with RUA-DirectTransfer(RANAP-AuthenticationRequest) */
	RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_auth_req)));

	/* Now on LLSK first the Conn establishment is confirmed and then we receive data */
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0)));
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_auth_req))));

	/* UE answers with RANAPAuthenticationResponse: */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_DATA_REQ(context_id, 1, hex2oct(ranap_auth_resp))));
	RUA.receive(tr_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_auth_resp)));

	/* UE sends Iu Release Complete to release the conn */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl))));
	RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
}
testcase TC_mo_conn() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;

	f_init();
	vc_conn := f_start_handler(refers(f_tc_mo_conn));
	vc_conn.done;
	f_shutdown_helper();
}


private function f_tc_paging(charstring id) runs on HNBGW_ConnHdlr {
	const integer context_id := 30;
	const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
	f_handle_hnbap_hnb_register_req();

	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
						  g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));

	/* HNBGW sends RUA-ConnectionlessTransfer(RANAP-Paging) */
	RUA.send(ts_RUA_ConnectionlessTransfer(hex2oct(ranap_paging)));

	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_UNITDATA_IND(hex2oct(ranap_paging))));

	/* Here it would continue with UE-side answers with RUA-Connect(RANAP-PagingResponse) */
}
testcase TC_paging() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;

	f_init();
	vc_conn := f_start_handler(refers(f_tc_paging));
	vc_conn.done;
	f_shutdown_helper();
}

private function f_tc_cs_mo_call(charstring id) runs on HNBGW_ConnHdlr {
	const integer context_id := 30;
	const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
	const Establishment_Cause est_cause := normal_call;
	var HNBLLIF_send_data sd;
	var PDU_RTP rtp_pdu;
	var octetstring rtp_payload;
	var HostName hnodeb_rtp_addr;
	var PortNumber hnodeb_rtp_port;
	timer Tu;
	var uint32_t audio_conn_id;
	var IuUP_FQC fqc := IuUP_FQC_GOOD;

	rtp_payload := f_rnd_octstring(6);
	f_HNBGW_rtpem_activate(rtp_payload);

	f_handle_hnbap_hnb_register_req();

	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
						  g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));

	/* Now an UE attempts CM Service Request: */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 0, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
	/* The related RUA Connect + RANAP message is received on Iuh: */
	RUA.receive(tr_RUA_Connect(cs_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));

	/* Now HNBGW answers with RUA-DirectTransfer(RANAP-RabASsReq) */
	RUA.send(ts_RUA_DirectTransfer(cs_domain, context_id_bstr, hex2oct(ranap_rab_ass_req)));

	/* Now on LLSK first the Conn establishment is confirmed and then we receive data */
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 0, 0)));
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 0, hex2oct(ranap_rab_ass_req))));

	/* Now LLSK provides the remote TransportLayerAddress from RabAssReq and asks SUT to provide a local address: */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_AUDIO_CONN_ESTABLISH_REQ(context_id, g_pars.hnbgw_rtp_port, HNBLL_IF_ADDR_TYPE_IPV4,
								f_HNBLLIF_Addr(HNBLL_IF_ADDR_TYPE_IPV4, g_pars.hnbgw_addr))));
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_AUDIO_CONN_ESTABLISH_CNF(context_id, ?, 0, ?, HNBLL_IF_ADDR_TYPE_IPV4, ?))) -> value sd;

	audio_conn_id := sd.data.u.audio.u.conn_establish.u.cnf.audio_conn_id;
	hnodeb_rtp_addr := f_inet_ntoa(sd.data.u.audio.u.conn_establish.u.cnf.local_addr);
	if (not match(g_pars.hnodeb_addr, hnodeb_rtp_addr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "hnodeb RTP local address doesn't match expectations");
	}
	hnodeb_rtp_port := sd.data.u.audio.u.conn_establish.u.cnf.local_rtp_port;
	f_HNBGW_rtpem_connect(hnodeb_rtp_addr, hnodeb_rtp_port);

	/* We should eventually receive some RTP/IUUP from the HNBGW once Init phase goes on: */
	Tu.start(2.0);
	alt {
	[] LLSK.receive(f_llsk_rx(tr_HNBLLIF_AUDIO_CONN_DATA_IND(audio_conn_id, ?, enum2int(fqc), ?, rtp_payload)));
	[] Tu.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for Downlink speech frames");
		}
	}
	Tu.stop;
	f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_RXONLY);

	/* Make sure that Uplink frames are received at the HNBGW */
	RTPEM_DATA.clear;
	LLSK.send(f_llsk_tx(ts_HNBLLIF_AUDIO_CONN_DATA_REQ(audio_conn_id, 1, enum2int(fqc), 0, rtp_payload)));
	Tu.start(2.0);
	alt {
	[] RTPEM_DATA.receive(PDU_RTP:?) -> value rtp_pdu {
		if (rtp_pdu.data != rtp_payload) {
				log("Unexpected RTP payload received!");
				repeat;
			}
		}
	[] RTPEM_DATA.receive { repeat; }
	[] Tu.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for Uplink speech frames");
		}
	}
	Tu.stop;

	f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_NONE);
	f_sleep(0.5); /* give some time to RTP_Emu to stop sending RTP packets... */

	LLSK.send(f_llsk_tx(ts_HNBLLIF_AUDIO_CONN_RELEASE_REQ(audio_conn_id)));

	/* UE sends Iu Release Complete to release the conn */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 0, 0, 0, hex2oct(iu_release_compl))));
	RUA.receive(tr_RUA_Disconnect(cs_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
}
testcase TC_cs_mo_call() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;

	f_init();
	vc_conn := f_start_handler(refers(f_tc_cs_mo_call));
	vc_conn.done;
	f_shutdown_helper();
}

private function f_tc_ps_mo_gtp_ping_pong(charstring id) runs on HNBGW_ConnHdlr {
	const integer context_id := 30;
	const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
	const Establishment_Cause est_cause := normal_call;
	var uint32_t remote_tei := 8888;
	var uint32_t local_tei;
	var octetstring gtp_payload := f_rnd_octstring(40);
	var HNBLLIF_send_data sd;
	var uint32_t gtp_conn_id;

	f_gtp_register_teid(int2oct(remote_tei, 4));

	f_handle_hnbap_hnb_register_req();

	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
						  g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));

	/* Now an UE attempts CM Service Request: */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
	/* The related RUA Connect + RANAP message is received on Iuh: */
	RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));

	/* Now HNBGW answers with RUA-DirectTransfer(RANAP-RabASsReq) */
	RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_rab_ass_req)));

	/* Now on LLSK first the Conn establishment is confirmed and then we receive data */
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0)));
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_rab_ass_req))));

	/* Now LLSK provides the remote TransportLayerAddress from RabAssReq and asks SUT to provide a local address: */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_ESTABLISH_REQ(context_id, remote_tei, HNBLL_IF_ADDR_TYPE_IPV4,
							      f_HNBLLIF_Addr(HNBLL_IF_ADDR_TYPE_IPV4, g_pars.hnbgw_addr))));
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_ESTABLISH_CNF(context_id, ?, ?, 0,
								 HNBLL_IF_ADDR_TYPE_IPV4, ?))) -> value sd;
	gtp_conn_id := sd.data.u.gtp.u.conn_establish.u.cnf.gtp_conn_id;
	local_tei := sd.data.u.gtp.u.conn_establish.u.cnf.local_tei;

	/* Forward GTP data in both directions */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_DATA_REQ(gtp_conn_id, gtp_payload)));
	GTP.receive(tr_GTPU_GPDU(ts_GtpPeerU(g_pars.hnodeb_addr), int2oct(remote_tei, 4), gtp_payload));
	f_gtpu_send(local_tei, gtp_payload);
	LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_DATA_IND(gtp_conn_id, gtp_payload)));

	/* Done, release GTP conn */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_RELEASE_REQ(gtp_conn_id)));

	/* UE sends Iu Release Complete to release the conn */
	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl))));
	RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
}
testcase TC_ps_mo_gtp_ping_pong() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;

	f_init();
	vc_conn := f_start_handler(refers(f_tc_ps_mo_gtp_ping_pong));
	vc_conn.done;
	f_shutdown_helper();
}

control {
	execute( TC_hnb_register_request_accept() );
	execute( TC_hnb_register_request_reject() );
	execute( TC_mo_conn() );
	execute( TC_paging() );
	execute( TC_cs_mo_call() );
	execute( TC_ps_mo_gtp_ping_pong() );
}

}
