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 Osmocom_VTY_Functions all;
import from PCU_Tests_NS all;
import from SGSN_Components all;
import from Osmocom_Gb_Types all;
import from NS_Emulation all;
import from NS_Types all;
import from RAW_NS all;
import from BSSGP_Types all;

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

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

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

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

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


/* 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, omit, omit, oneshot := true);
	as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, omit, 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);
	f_clean_ns_codec();
}

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) {
		/* Expect BVC-RESET, but ignore it to prevent a race condition of BVC RESETs */
		var template PDU_NS pdu := tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BVC_RESET(?, 0, omit));
		f_ns_exp(pdu);
		/* SGSN originated BVC-RESET on an uninitialized signalling BVC */
		f_tx_bvc_reset_rx_ack(0, omit, omit);

		/* Expect BVC-RESET PTP BVC, but ignore it to prevent a race condition of BVC RESETs */
		pdu := tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BVC_RESET(?, mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id));
		f_ns_exp(pdu);
		/* SGSN originated BVC-RESET on an uninitialized PTP BVC */
		f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, omit, mp_gb_cfg.bvc[0].cell_id);
	} else {
		/* Expect BVC-RESET for signaling BVCI=0 */
		as_rx_bvc_reset_tx_ack(0, omit, omit, oneshot := true);
		/* Expect BVC-RESET from the PCU on PTP BVC */
		as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, omit, 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);
	f_clean_ns_codec();
}

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) {
		/* Expect BVC-RESET, but ignore it to prevent a race condition of BVC RESETs */
		var template PDU_NS pdu := tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BVC_RESET(?, 0, omit));
		f_ns_exp(pdu, idx := 1);
		/* SGSN originated BVC-RESET on an uninitialized sign BVC */
		f_tx_bvc_reset_rx_ack(0, omit, omit, idx := 1);

		/* Expect BVC-RESET PTP BVC, but ignore it to prevent a race condition of BVC RESETs */
		pdu := tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BVC_RESET(?, mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id));
		f_ns_exp(pdu, idx := 1);
		f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, omit, mp_gb_cfg.bvc[0].cell_id, idx := 1);
	} else {
		/* Expect BVC-RESET for signaling BVCI=0 */
		as_rx_bvc_reset_tx_ack(0, omit, omit, oneshot := true, idx := 1);
		/* Expect BVC-RESET from the PCU on PTP BVC */
		as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, omit, 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);
	f_clean_ns_codec();
}

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

/* Test full IP_SNS bring-up over an initial NS-VC with two NS-VCs */
testcase TC_sns_1c1u_unconfigured_nsvc() runs on RAW_Test_CT {
	f_init_vty(testcasename());
	f_sns_bringup_1c1u_separate();
	f_vty_transceive_not_match(PCUVTY, "show ns entities", pattern "*UNCONFIGURED*");
	setverdict(pass);
	f_clean_ns_codec();
}

/* 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, omit, omit, idx := 1, exp_ack := false);
	f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, omit, mp_gb_cfg.bvc[0].cell_id, idx := 1, exp_ack := false);
	f_clean_ns_codec();
}

/* Do an SGSN originated BSSGP-Reset of a not-configured BVCI.
 *
 * PCU  -X SGSN: BVCI  0 BSSGP-RESET (ignores reset)
 * PCU <-  SGSN: BVCI  0 BSSGP-RESET
 * PCU  -> SGSN: BVCI  0 BSSGP-RESET-ACK (with cell information)
 * PCU  -X SGSN: BVCI 23 BSSGP-RESET (ignores reset, 23 is configured on PCU, 24 is not configured)
 * PCU <-  SGSN: BVCI 24 BSSGP-RESET (unconfigured BVCI)
 * PCU  -> SGSN: BVCI 24 BSSGP-STATUS Unknown BVCI
 */
testcase TC_sns_so_bvc_reset_unknown_bvci() runs on RAW_Test_CT {
	g_handle_rx_alive := true;
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();
	f_incoming_sns_size();
	f_incoming_sns_config();
	f_outgoing_sns_config();

	/* Expect BVC-RESET, but ignore it to prevent a race condition of BVC RESETs */
	var template PDU_NS pdu := tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BVC_RESET(?, 0, omit));
	f_ns_exp(pdu, idx := 0);
	/* SGSN originated BVC-RESET on an uninitialized sign BVC */
	f_tx_bvc_reset_rx_ack(0, omit, omit, idx := 0);

	/* Expect BVC-RESET PTP BVC, but ignore it to prevent a race condition of BVC RESETs */
	pdu := tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BVC_RESET(?, mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id));
	f_ns_exp(pdu);

	/* Send a BVC-RESET on the wrong BVC */
	var BssgpCellId cell_id := mp_gb_cfg.bvc[0].cell_id;
	cell_id.cell_id := cell_id.cell_id + 1;
	var PDU_BSSGP bssgp_tx := valueof(ts_BVC_RESET(BSSGP_CAUSE_NET_SV_CAP_MOD_GT_ZERO_KBPS,
							mp_gb_cfg.bvc[0].bvci + 1, cell_id));
	NSCP[0].send(ts_NS_UNITDATA(t_SduCtrlB, 0, enc_PDU_BSSGP(bssgp_tx)));
	NSCP[0].receive(tr_NS_UNITDATA(t_SduCtrlB, 0, decmatch tr_BSSGP_STATUS(mp_gb_cfg.bvc[0].bvci + 1, BSSGP_CAUSE_BVCI_UNKNOWN, *)));
	setverdict(pass);

	f_clean_ns_codec();
}

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

	/* create 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);
	setverdict(pass);
	f_clean_ns_codec();
}

/* Test adding an already present IP endpoint at runtime */
testcase TC_sns_add_nack() runs on RAW_Test_CT {
	f_sns_bringup_1c1u();

	f_outgoing_sns_add(idx_add := 0, w_sig := 0, w_user := 1, idx := 0, cause := NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED);
	setverdict(pass);
	f_clean_ns_codec();
}

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

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

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);
	f_clean_ns_codec();
}



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_1c1u_unconfigured_nsvc() );
	execute( TC_sns_so_bvc_reset_unknown_bvci() );
	execute( TC_sns_add() );
	execute( TC_sns_add_nack() );
	execute( TC_sns_del() );
	execute( TC_sns_chg_weight() );

	execute( TC_pcuif_rach() );
}

}
