module PCU_Tests_SNS {

/* Osmocom PCU test suite for IP Sub-Network-Service (SNS) in TTCN-3
 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * 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 Osmocom_Types all;
import from PCU_Tests_NS all;
import from SGSN_Components all;
import from Osmocom_Gb_Types all;
import from NS_CodecPort all;
import from NS_Types all;
import from RAW_NS all;

/**********************************************************************************
 * Modern Gb/IP bring-up test cases using IP Sub-Network Service (SNS)
 **********************************************************************************/

/* perform inbound SNS-SIZE procedure */
function f_incoming_sns_size(template (omit) NsCause cause := omit, integer idx := 0)
runs on RAW_NS_CT {
	log("f_incoming_sns_size(idx=", idx, ")");
	var PDU_NS rx;
	/* expect one single SNS-SIZE with RESET flag; one remote v4 EP; no v6 EP */
	rx := f_ns_exp(tr_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 8,
				   num_v4 := 4, num_v6 := omit), idx);
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE_ACK(g_nsconfig[idx].nsei, cause)));
}

/* perform outbound SNS-SIZE procedure */
function f_outgoing_sns_size(template (omit) NsCause cause := omit, integer idx:= 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_size(idx=", idx, ")");
	var PDU_NS rx;
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 1,
							num_v4 := 1, num_v6 := omit)
				));
	/* expect one single SNS-SIZE with RESET flag; one remote v4 EP; no v6 EP */
	rx := f_ns_exp(tr_SNS_SIZE_ACK(g_nsconfig[idx].nsei, cause), idx);
}

/* perform inbound SNS-CONFIG procedure */
function f_incoming_sns_config(template (omit) NsCause cause := omit, integer idx := 0)
runs on RAW_NS_CT {
	log("f_incoming_sns_config(idx=", idx, ")");
	var PDU_NS rx;
	var template IP4_Elements v4_elem := { tr_SNS_IPv4(mp_nsconfig.provider.ip.remote_ip,
							   mp_nsconfig.provider.ip.remote_udp_port) };
	rx := f_ns_exp(tr_SNS_CONFIG(g_nsconfig[idx].nsei, end_flag := true, v4 := v4_elem), idx);
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause)));
}

/* perform outbound SNS-CONFIG procedure */
function f_outgoing_sns_config(template (omit) NsCause cause := omit, integer idx := 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_config(idx=", idx, ")");
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx].provider.ip.local_ip,
							     g_nsconfig[idx].provider.ip.local_udp_port) }
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4)));
	rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx);
}

/* perform outbound SNS-CONFIG procedure (separate endpoints: 1 for control, 1 for user */
function f_outgoing_sns_config_1c1u(template (omit) NsCause cause := omit, integer idx := 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_config_1c1u(idx=", idx, ")");
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[0].provider.ip.local_ip,
							     g_nsconfig[0].provider.ip.local_udp_port, 1, 0),
						 ts_SNS_IPv4(g_nsconfig[1].provider.ip.local_ip,
							     g_nsconfig[1].provider.ip.local_udp_port, 0, 1) };
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4)));
	rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx);
}

/* perform outbound SNS-CONFIG procedure (separate endpoints: 1 for control, 1 for user */
function f_outgoing_sns_config_1c1u_separate(template (omit) NsCause cause := omit, integer idx := 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_config_1c1u_separate(idx=", idx, ")");
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[1].provider.ip.local_ip,
							     g_nsconfig[1].provider.ip.local_udp_port, 1, 0),
						 ts_SNS_IPv4(g_nsconfig[2].provider.ip.local_ip,
							     g_nsconfig[2].provider.ip.local_udp_port, 0, 1) };
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4)));
	rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx);
}

function f_outgoing_sns_add(integer idx_add, uint8_t w_sig := 1, uint8_t w_user := 1, integer idx := 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_add(idx_add=", idx_add, ")");
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_add].provider.ip.local_ip,
							     g_nsconfig[idx_add].provider.ip.local_udp_port,
							     w_sig, w_user) };
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_ADD(g_nsconfig[idx].nsei, 23, v4)));
	rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 23, omit, v4));
}

function f_outgoing_sns_del(integer idx_del, uint8_t w_sig := 1, uint8_t w_user := 1, integer idx := 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_del(idx_del=", idx_del, ")");
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_del].provider.ip.local_ip,
							     g_nsconfig[idx_del].provider.ip.local_udp_port,
							     w_sig, w_user) };
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_DEL(g_nsconfig[idx].nsei, 24, omit, v4)));
	rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 24, omit, v4));
}

function f_outgoing_sns_chg_weight(integer idx_chg, uint8_t w_sig, uint8_t w_user, integer idx := 0)
runs on RAW_NS_CT {
	log("f_outgoing_sns_chg_weight(idx_chg=", idx_chg, ")");
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_chg].provider.ip.local_ip,
							     g_nsconfig[idx_chg].provider.ip.local_udp_port,
							     w_sig, w_user) };
	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CHG_WEIGHT(g_nsconfig[idx].nsei, 25, v4)));
	rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 25, omit, v4));
}





/* PCU-originated SNS-SIZE: successful case */
testcase TC_sns_po_size_success() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();
	f_incoming_sns_size();
	f_sleep(1.0);
	setverdict(pass);
}

/* PCU-originated SNS-SIZE: NACK from our side */
testcase TC_sns_po_size_nack() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();
	f_incoming_sns_size(NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED);
	/* FIXME: ensure we don't get a SNS-CONFIG */
	/* FIXME: ensure we get re-transmitted SNS-SIZE attempts */
	f_sleep(10.0);
	setverdict(pass);
}

/* PCU-originated SNS-CONFIG: successful case */
testcase TC_sns_po_config_success() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();
	f_incoming_sns_size();
	f_incoming_sns_config();
	f_sleep(1.0);
	setverdict(pass);
}

/* PCU-originated SNS-CONFIG: successful case */
testcase TC_sns_po_config_nack() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();
	f_incoming_sns_size();
	f_incoming_sns_config(NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED);
	/* FIXME: ensure we get re-transmitted SNS-CONFIG attempts */
	f_sleep(10.0);
	setverdict(pass);
}


/* SGSN-originated SNS-SIZE: successful case */
testcase TC_sns_so_config_success() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();
	f_incoming_sns_size();
	f_incoming_sns_config();
	f_outgoing_sns_config();

	/* wait for one ALIVE cycle, then ACK any further ALIVE in the background */
	as_rx_alive_tx_ack(oneshot := true);
	activate(as_rx_alive_tx_ack());

	f_outgoing_ns_alive();

	/* Expect BVC-RESET for signaling (0) and ptp BVCI */
	as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
	as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
	as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);

	/* wait for one FLOW-CONTROL BVC and then ACK any further in the future */
	as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
	activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci));
	setverdict(pass);
}

private function f_sns_bringup_1c1u(boolean sgsn_originated_reset := false) runs on RAW_Test_CT {
	/* Activate two NS codec ports */
	f_init_ns_codec(mp_nsconfig);
	f_init_ns_codec(mp_nsconfig, 1);
	f_init_pcuif();
	/* Perform Size + BSS-originated config */
	f_incoming_sns_size();
	f_incoming_sns_config();
	/* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */
	f_outgoing_sns_config_1c1u();

	/* wait for one ALIVE cycle, then ACK any further ALIVE in the background
	 * for both NS-VCs */
	as_rx_alive_tx_ack(oneshot := true, idx := 0);
	activate(as_rx_alive_tx_ack(idx := 0));
	as_rx_alive_tx_ack(oneshot := true, idx := 1);
	activate(as_rx_alive_tx_ack(idx := 1));

	/* perform outgoing ALIVE procedure for both NS-VCs */
	f_outgoing_ns_alive(0);
	f_outgoing_ns_alive(1);

	if (sgsn_originated_reset) {
		f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.bvc[0].cell_id);
		f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id);
	} else {
		/* Expect BVC-RESET for signaling (0) and ptp BVCI */
		as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
		as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
	}
	/* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==0) */
	as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);

	/* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow
	 * control happens on the p-t-p BVCI and hence on index 1 */
	as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true, idx := 1);
	activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, idx := 1));
}

/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only */
testcase TC_sns_1c1u() runs on RAW_Test_CT {
	f_sns_bringup_1c1u();
	setverdict(pass);
}

private function f_sns_bringup_1c1u_separate(boolean sgsn_originated_reset := false) runs on RAW_Test_CT {
	/* Activate two NS codec ports */
	f_init_ns_codec(mp_nsconfig);
	f_init_ns_codec(mp_nsconfig, 1);
	f_init_ns_codec(mp_nsconfig, 2);
	f_init_pcuif();
	/* Perform Size + BSS-originated config */
	f_incoming_sns_size();
	f_incoming_sns_config();
	/* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */
	f_outgoing_sns_config_1c1u_separate();

	/* wait for one ALIVE cycle, then ACK any further ALIVE in the background
	 * for both NS-VCs */
	as_rx_alive_tx_ack(oneshot := true, idx := 1);
	activate(as_rx_alive_tx_ack(idx := 1));
	as_rx_alive_tx_ack(oneshot := true, idx := 2);
	activate(as_rx_alive_tx_ack(idx := 2));
	/* ensure there's no NS-ALIVE received on idx==0 */
	f_ensure_no_ns(t_NS_ALIVE, idx := 0);

	/* perform outgoing ALIVE procedure for both NS-VCs */
	f_outgoing_ns_alive(1);
	f_outgoing_ns_alive(2);
	/* ensure there's no response to NS-ALIVE sent on idx==0 */
	f_outgoing_ns_alive_no_ack(idx := 0);

	if (sgsn_originated_reset) {
		f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.bvc[0].cell_id, idx := 1);
		f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, idx := 1);
	} else {
		/* Expect BVC-RESET for signaling BVCI=0 and ptp BVCI */
		as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true, idx := 1);
		as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true, idx := 1);
	}
	/* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==1) */
	as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true, idx := 1);

	/* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow
	 * control happens on the p-t-p BVCI and hence on index 1 */
	as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true, idx := 2);
	activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, idx := 2));
}

/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only - and where
 * the initial IP/port for the SNS procedure is *not* part of the NS-VCs later */
testcase TC_sns_1c1u_separate() runs on RAW_Test_CT {
	f_sns_bringup_1c1u_separate();
	setverdict(pass);
}

/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only and use
 * SGSN-originated BVC-RESET rather than BSS-originated */
testcase TC_sns_1c1u_so_bvc_reset() runs on RAW_Test_CT {
	f_sns_bringup_1c1u_separate(sgsn_originated_reset := true);
	setverdict(pass);
}

/* Transmit BVC-RESET before NS-ALIVE of PCU was ACKed: expect no response */
testcase TC_sns_1c1u_so_bvc_reset_too_early() runs on RAW_Test_CT {
	/* Activate two NS codec ports */
	f_init_ns_codec(mp_nsconfig);
	f_init_ns_codec(mp_nsconfig, 1);
	f_init_ns_codec(mp_nsconfig, 2);
	f_init_pcuif();
	/* Perform Size + BSS-originated config */
	f_incoming_sns_size();
	f_incoming_sns_config();
	/* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */
	f_outgoing_sns_config_1c1u_separate();

	/* DON'T ACK ANY INBOUND NS-ALIVE HERE! */

	/* perform outgoing ALIVE procedure for both NS-VCs */
	f_outgoing_ns_alive(1);
	f_outgoing_ns_alive(2);
	/* ensure there's no response to NS-ALIVE sent on idx==0 */
	f_outgoing_ns_alive_no_ack(idx := 0);

	/* Transmit BVC-RESET and expect no ACK*/
	f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.bvc[0].cell_id, idx := 1, exp_ack := false);
	f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, idx := 1, exp_ack := false);
}

/* Test adding new IP endpoints at runtime */
testcase TC_sns_add() runs on RAW_Test_CT {
	f_sns_bringup_1c1u();

	/* crate another NS codec port on the tester side */
	f_init_ns_codec(mp_nsconfig, 2);

	f_outgoing_sns_add(idx_add := 2, w_sig := 0, w_user := 1, idx := 0);

	/* wait for one ALIVE cycle, then ACK any further ALIVE in the background */
	as_rx_alive_tx_ack(oneshot := true, idx := 2);
	activate(as_rx_alive_tx_ack(idx := 2));

	f_outgoing_ns_alive(2);
	/* TODO: Should we expect FLOW-CONTROL BVC here too? */
	setverdict(pass);
}

/* Test deleting IP endpoints at runtime */
testcase TC_sns_del() runs on RAW_Test_CT {
	f_sns_bringup_1c1u();

	f_outgoing_sns_del(idx_del := 1, w_sig := 0, w_user := 1, idx := 0);
	/* FIXME: ensure we don't receive anything on just-deleted NS-VC anymore */
	setverdict(pass);
}

/* Test changing weights at runtime */
testcase TC_sns_chg_weight() runs on RAW_Test_CT {
	f_sns_bringup_1c1u();

	/* change w_user from 1 to 200 */
	f_outgoing_sns_chg_weight(idx_chg := 1, w_sig := 0, w_user := 200, idx := 0);
	setverdict(pass);
}

import from PCUIF_Types all;
import from PCUIF_CodecPort all;

altstep as_pcu_activate() runs on RAW_PCU_CT {
	var PCUIF_send_data sd;
	[] PCU.receive(t_SD_PCUIF(g_pcu_conn_id,  tr_PCUIF_ACT_REQ(?, ?, ?))) -> value sd { repeat; }

}

testcase TC_pcuif_rach() runs on RAW_Test_CT {
	f_sns_bringup_1c1u();
	activate(as_pcu_activate());

	f_pcuif_tx(ts_PCUIF_RACH_IND(bts_nr:=0, trx_nr:=0, ts_nr:=0, ra:=23,
				     is_11bit:=0, burst_type:=BURST_TYPE_0,
				     fn:=42, arfcn:=871, qta:=0));
	PCU.receive(t_SD_PCUIF(g_pcu_conn_id,
			       tr_PCUIF_DATA_REQ(bts_nr:=0, trx_nr:=0, ts_nr:=0, block_nr:=?, fn:=?,
						 sapi:=PCU_IF_SAPI_AGCH, data:=?)));
	setverdict(pass);
}



control {
	execute( TC_sns_po_size_success() );
	execute( TC_sns_po_size_nack() );
	execute( TC_sns_po_config_success() );
	execute( TC_sns_po_config_nack() );
	execute( TC_sns_so_config_success() );
	execute( TC_sns_1c1u() );
	execute( TC_sns_1c1u_separate() );
	execute( TC_sns_1c1u_so_bvc_reset() );
	execute( TC_sns_1c1u_so_bvc_reset_too_early() );
	execute( TC_sns_add() );
	execute( TC_sns_del() );
	execute( TC_sns_chg_weight() );

	execute( TC_pcuif_rach() );
}

}
