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

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

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

}
