module NS_Tests {

/* Osmocom NS test suite for NS over framerelay or udp ip.access style in TTCN-3
 * (C) 2021 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * Author: Alexander Couzens <lynxis@fe80.eu>
 * 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
 */

import from General_Types all;
import from Osmocom_Types all;
import from Osmocom_Gb_Types all;
import from NS_Types all;
import from BSSGP_Types all;
import from UD_Types all;
import from NS_Emulation all;
import from Native_Functions all;
import from IPL4asp_Types all;
import from RAW_NS all;
import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

modulepar {
	OsmoNsDialect mp_dialect := NS2_DIALECT_IPACCESS;
	NSConfiguration mp_nsconfig := {
		nsei := 96,
		role_sgsn := false,
		handle_sns := false,
		nsvc := {
			{
				provider := {
					ip := {
						address_family := AF_INET,
						local_udp_port := 21000,
						local_ip := "127.0.0.1",
						remote_udp_port := 23000,
						remote_ip := "127.0.0.1",
						data_weight := 2,
						signalling_weight := 2
					}
				},
				nsvci := 97
			}
		}
	};
}

type component RAW_Test_CT extends RAW_NS_CT {
	port TELNETasp_PT NSVTY;
}

private function f_init_vty() runs on RAW_Test_CT {
	map(self:NSVTY, system:NSVTY);
	f_vty_set_prompts(NSVTY);
	f_vty_transceive(NSVTY, "enable");
	f_vty_transceive(NSVTY, "nsvc nsei " & int2str(mp_nsconfig.nsei) & " force-unconfigured");
}

/* ensure no matching message is received within 'tout' */
function f_ensure_no_ns(integer idx := 0, boolean answer_alive := false, float tout := 3.0)
runs on RAW_Test_CT {
	var PDU_NS nrf;

	timer T := tout;
	var default d := activate(ax_rx_fail_on_any_ns(idx));
	T.start;
	alt {
	[answer_alive] as_rx_alive_tx_ack();
	[] T.timeout {
		setverdict(pass);
		}
	}
	deactivate(d);
}

function f_fails_except_reset(integer idx := 0, float tout := 15.0)
runs on RAW_Test_CT {
	var PDU_NS nrf;
	timer T := 15.0;
	T.start;
	alt {
	[] NSCP[idx].receive(tr_NS_RESET(*, *, *)) {
		repeat;
	}
	[] NSCP[idx].receive(PDU_NS: ?) -> value nrf {
		setverdict(fail, "Received unexpected NS: ", nrf);
		mtc.stop;
	}
	[] T.timeout {
		setverdict(pass);
		}
	}
}

testcase TC_tx_reset() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 10.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();

	setverdict(pass);
	f_sleep(1.0);
}

testcase TC_tx_reset_tx_alive() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 10.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();

	/* check outgoing NS procedure */
	f_outgoing_ns_alive();

	setverdict(pass);
	f_sleep(1.0);
}

testcase TC_tx_reset_rx_alive() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 10.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();

	activate(as_rx_ns_unblock_ack());
	/* check outgoing NS procedure */
	as_rx_alive_tx_ack(oneshot := true);

	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.2 unblock procedure
 *
 * TTCN  -> NS: reset
 * TTCN <-  NS: reset ack
 * TTCN  -> NS: unblock
 * TTCN <-  NS: unblock ack
 */
testcase TC_tx_unblock() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();
	/* send alive acks */
	activate(as_rx_alive_tx_ack());

	f_outgoing_ns_unblock();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.2 tx unblock retries
 *
 * TTCN  -> NS: reset
 * TTCN <-  NS: reset ack
 * TTCN  -> NS: unblock
 * TTCN <-  NS: unblock ack
 * TTCN  -> NS: unblock
 * TTCN <-  NS: unblock ack
 * TTCN  -> NS: unblock
 * TTCN <-  NS: unblock ack
 */
testcase TC_tx_unblock_retries() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();
	/* send alive acks */
	activate(as_rx_alive_tx_ack());

	f_outgoing_ns_unblock();
	f_outgoing_ns_unblock();
	f_outgoing_ns_unblock();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.2 block procedure
 *
 * TTCN  -> NS: reset
 * TTCN <-  NS: reset ack
 * TTCN  -> NS: unblock
 * TTCN <-  NS: unblock ack
 * TTCN  -> NS: block
 * TTCN <-  NS: block ack
 */
testcase TC_tx_block() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();
	activate(as_rx_alive_tx_ack());

	f_outgoing_ns_unblock();
	f_sleep(1.0);

	f_outgoing_ns_block(NS_CAUSE_EQUIPMENT_FAILURE);
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.2 block procedure by vty
 *
 * TTCN  -> NS: reset
 * TTCN <-  NS: reset ack
 * TTCN  -> NS: unblock
 * TTCN <-  NS: unblock ack
 * vty: block nsvc
 * TTCN <-  NS: block
 * TTCN  -> NS: block ack
 */
function tx_block_by_vty(float guard_secs := 30.0) runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := guard_secs);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();
	activate(as_rx_alive_tx_ack());

	f_outgoing_ns_unblock();
	f_sleep(1.0);

	f_vty_transceive(NSVTY, "nsvc " & int2str(mp_nsconfig.nsvc[0].nsvci) & " block");

	alt {
	[] as_rx_ns_block_ack(oneshot := true, nsvci := mp_nsconfig.nsvc[0].nsvci);
	}
	setverdict(pass);
}

testcase TC_tx_block_by_vty() runs on RAW_Test_CT {
	tx_block_by_vty(30.0);
	f_sleep(1.0);
}

/* 48.016 7.2 block precedure by vty and reset the NSVC.
 *            The NSVC should be still blocked after the reset.
 */
testcase TC_tx_block_by_vty_reset() runs on RAW_Test_CT {
	timer T := 10.0;

	tx_block_by_vty(60.0);
	f_outgoing_ns_reset();

	var default d := activate(ax_rx_fail_on_any_ns());
	T.start;
	alt {
	[] as_rx_alive_tx_ack();
	[] T.timeout { setverdict(pass); }
	}
	deactivate(d);
}

/* 48.016 7.4.1 ignore unexpected NS_ALIVE ACK */
testcase TC_no_reset_alive_ack() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].send(t_NS_ALIVE_ACK);
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 NS_RESET with wrong nsei */
testcase TC_reset_wrong_nsei() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei + 20));
	NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 NS_RESET with wrong nsvci */
testcase TC_reset_wrong_nsvci() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei));
	NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 NS_RESET with wrong nsvci + nsei */
testcase TC_reset_wrong_nsei_nsvci() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei + 20));
	NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 NS_RESET_ACK with wrong nsei */
testcase TC_reset_ack_wrong_nsei() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei + 20));
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 NS_RESET_ACK with wrong nsvci */
testcase TC_reset_ack_wrong_nsvci() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei));
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 NS_RESET_ACK with wrong nsvci + nsei */
testcase TC_reset_ack_wrong_nsei_nsvci() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei + 20));
	f_fails_except_reset();
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3.1 ignore unexpected NS_RESET_ACK after NS_RESET+ALIVE */
testcase TC_ignore_reset_ack() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();

	/* unblock and alive */
	alt {
	[] as_rx_ns_unblock_ack(oneshot := true);
	[] as_rx_alive_tx_ack();
	}

	NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	f_ensure_no_ns(answer_alive := true, tout := 15.0);
	setverdict(pass);
	f_sleep(1.0);
}

/* 48.016 7.3 NS_RESET retries */
testcase TC_reset_retries() runs on RAW_Test_CT {
	var integer reset := 0;

	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	alt {
	[] NSCP[0].receive(tr_NS_RESET(*, *, *)) {
		reset := reset + 1;
		if (reset <= 3) {
			repeat;
		} else {
			setverdict(pass);
		}
	}
	}

	f_sleep(1.0);
}

/* 48.016 behave RESET_ACK got dropped
 * TTCN  -> NS: reset
 * TTCN <-  NS: reset ack
 * TTCN <-  NS: unblock
 * TTCN  -> NS: reset
 * TTCN <-  NS: reset ack
 * TTCN <-  NS: unblock
 */
testcase TC_reset_on_block_reset() runs on RAW_Test_CT {
	var integer i := 0;

	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);

	f_outgoing_ns_reset();
	activate(as_rx_alive_tx_ack());

	alt {
	[] NSCP[0].receive(t_NS_UNBLOCK) {
		NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
		i := i + 1;
		if (i < 3) {
			repeat;
		} else {
			setverdict(pass);
		}
	}
	[] NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei)) { repeat; }
	}

	f_sleep(1.0);
}

/* 48.016 7.4 test procedure for frame relay with a single nsvci */
function f_alive_retries_single(boolean reset := false) runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig, guard_secs := 60.0);

	/* do a NS Reset procedure */
	f_outgoing_ns_reset();

	alt {
	[] as_rx_ns_unblock_ack(oneshot := true);
	[] as_rx_alive_tx_ack();
	}

	/* wait for one alive and answer it */
	as_rx_alive_tx_ack(oneshot := true);
	NSCP[0].receive(t_NS_ALIVE);
	NSCP[0].receive(t_NS_ALIVE);
	NSCP[0].receive(t_NS_ALIVE);
	NSCP[0].receive(t_NS_ALIVE);
	if (reset) {
		NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
	} else {
		f_ensure_no_ns(tout := 10.0);
	}

	setverdict(pass);
	f_sleep(1.0);
}

testcase TC_alive_retries_single_reset() runs on RAW_Test_CT {
	f_alive_retries_single(reset := true);
}

testcase TC_alive_retries_single_no_resp() runs on RAW_Test_CT {
	f_alive_retries_single(reset := false);
}

/* 48.016 SNS test cases */

/* do a succesful SNS configuration */
testcase TC_sns_config_success() runs on RAW_Test_CT {
	f_init_vty();
	f_init_ns_codec(mp_nsconfig);
	f_incoming_sns_size();
	f_incoming_sns_config();
	f_outgoing_sns_config();
	setverdict(pass);
	f_clean_ns_codec();
}

testcase TC_sns_bss_change_weight() runs on RAW_Test_CT {
	g_handle_rx_alive := true;
	f_init_vty();
	f_init_ns_codec(mp_nsconfig);
	f_incoming_sns_size();
	f_incoming_sns_config();
	f_outgoing_sns_config();
	activate(as_rx_alive_tx_ack());
	f_vty_config2(NSVTY, {"ns", "bind udp local"}, "ip-sns signalling-weight 99 data-weight 99");
	f_incoming_sns_chg_weight();
	setverdict(pass);
	f_clean_ns_codec();
}

/* receive 3x SNS_CHG_WEIGHT but never answer on it */
testcase TC_sns_bss_change_weight_timeout() runs on RAW_Test_CT {
	var integer i := 0;
	var template PDU_NS rx;
	var NSVCConfiguration nsvc_cfg;

	g_handle_rx_alive := true;
	f_init_vty();
	f_init_ns_codec(mp_nsconfig);
	f_incoming_sns_size();
	f_incoming_sns_config();
	f_outgoing_sns_config();
	activate(as_rx_alive_tx_ack());
	f_vty_config2(NSVTY, {"ns", "bind udp local"}, "ip-sns signalling-weight 99 data-weight 99");

	nsvc_cfg := g_nsconfig.nsvc[0];
	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
		var template IP4_Elements v4_elem := { tr_SNS_IPv4(nsvc_cfg.provider.ip.remote_ip,
								   nsvc_cfg.provider.ip.remote_udp_port) };

		rx := tr_SNS_CHG_WEIGHT(g_nsconfig.nsei, ?, v4 := v4_elem);
	} else {
		var template IP6_Elements v6_elem := { tr_SNS_IPv6(nsvc_cfg.provider.ip.remote_ip,
								   nsvc_cfg.provider.ip.remote_udp_port) };
		rx := tr_SNS_CHG_WEIGHT(g_nsconfig.nsei, ?, v4 := omit, v6 := v6_elem);
	}

	for (i := 0; i < 3; i := i + 1) {
		f_ns_exp(rx);
	}

	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
		/* expect one single SNS-SIZE with RESET flag; 4x v4 EP; no v6 EP */
		rx := f_ns_exp(tr_SNS_SIZE(g_nsconfig.nsei, rst_flag := true, max_nsvcs := ?,
					   num_v4 := ?, num_v6 := omit), 0);
	} else {
		/* expect one single SNS-SIZE with RESET flag; no v4 EP; 4x v6 EP */
		rx := f_ns_exp(tr_SNS_SIZE(g_nsconfig.nsei, rst_flag := true, max_nsvcs := ?,
					   num_v4 := omit, num_v6 := ?), 0);
	}

	setverdict(pass);
	f_clean_ns_codec();
}

control {
	if (mp_dialect == NS2_DIALECT_STATIC_RESETBLOCK or mp_dialect == NS2_DIALECT_IPACCESS) {
		execute( TC_tx_reset() );

		/* 48.016 7.2 Block procedure */
		execute( TC_tx_block() );
		execute( TC_tx_block_by_vty() );
		execute( TC_tx_block_by_vty_reset() );
		// execute( TC_block_other_nsvc() ); // reset, unblock, sleep(1), block over another nsvci
		/* 48.016 7.2 Unblock procedure */
		execute( TC_tx_unblock() );
		execute( TC_tx_unblock_retries() );
		// execute( TC_rx_unblock_tx_unblock() ); // wait for an rx unblock pdu, send an unblock pdu, expect unblock ack pdu
		// execute( TC_unblockable() ); // block a NS-VCI via vty, try block procedure

		/* 48.016 7.2.1 Block Abnormal Condition */
		/* 48.016 7.2.1 Unblock Abnormal Condition */
		/* 48.016 7.3.1 Abnormal Condition */
		execute( TC_reset_wrong_nsei() );
		execute( TC_reset_wrong_nsvci() );
		execute( TC_reset_wrong_nsei_nsvci() );
		execute( TC_reset_ack_wrong_nsei() );
		execute( TC_reset_ack_wrong_nsvci() );
		execute( TC_reset_ack_wrong_nsei_nsvci() );
		execute( TC_reset_retries() );
		execute( TC_reset_on_block_reset() );
		execute( TC_ignore_reset_ack() );

		/* 48.016 7.4 Test procedure on frame relay */
		execute( TC_tx_reset_tx_alive() );
		execute( TC_tx_reset_rx_alive() );

		/* 48.016 7.4.1 Abnormal Condition */
		if (mp_dialect == NS2_DIALECT_STATIC_RESETBLOCK) {
			// execute( TC_alive_retries_multi() ); // check if alive retries works and block over an alive nsvc
			execute( TC_alive_retries_single_reset() );
		} else if (mp_dialect == NS2_DIALECT_IPACCESS) {
			execute( TC_alive_retries_single_no_resp() );
		}

		execute( TC_no_reset_alive_ack() );
	}

	if (mp_dialect == NS2_DIALECT_SNS) {
		execute( TC_sns_config_success() );
		execute( TC_sns_bss_change_weight() );
		execute( TC_sns_bss_change_weight_timeout() );
	}
}

}
