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

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(TestHdlrParams pars) runs on test_CT {
	map(self:LLSK, system:LLSK);
	f_start_hnbllif(LLSK, testcasename(), pars, 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) alive;
	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 (istemplatekind(pars_tmpl, "omit")) {
		pars := valueof(f_gen_test_hdlr_pars());
	} else {
		pars := valueof(pars_tmpl);
	}
	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;
	var template (omit) HNBLLIF_AUDIO_RFCIs rfcis_tpl := omit;

	if (g_pars.hnbllif_sapi_audio_version >= 1) {
		var HNBLLIF_AUDIO_RFCIs rfcis;
		/* generate some unordered RFCI list of 3 elements (the default): */
		rfcis[0] := 1; rfcis[1] := 2; rfcis[2] := 0;
		for (var integer i := 3; i < HNBLLIF_MAX_RFCIS; i := i + 1) {
			rfcis[i] := 0;
		}
		rfcis_tpl := rfcis;
	}

	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),
								rfci := rfcis_tpl)));
	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();
}
/* Same as TC_cs_mo_call, but using AUDIO SAPI version 0 (no rfci param
 * in HNBLLIF_AUDIO_conn_establish_req) */
testcase TC_cs_mo_call_audio_v0() runs on test_CT {
	var HNBGW_ConnHdlr vc_conn;
	var TestHdlrParams pars;

	f_init();
	pars := valueof(f_gen_test_hdlr_pars());
	pars.hnbllif_sapi_audio_version := 0;
	vc_conn := f_start_handler(refers(f_tc_cs_mo_call), pars);
	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_audio_v0() );
	execute( TC_cs_mo_call() );
	execute( TC_ps_mo_gtp_ping_pong() );
}

}
