module PCU_Tests_RAW_SNS {

import from Osmocom_Types all;
import from PCU_Tests all;
import from PCU_Tests_RAW all;
import from Osmocom_Gb_Types all;
import from NS_CodecPort all;
import from NS_Types 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 {
	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 {
	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 {
	var PDU_NS rx;
	rx := f_ns_exp(tr_SNS_CONFIG(g_nsconfig[idx].nsei, end_flag := true, v4 := ?), 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 {
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx].local_ip,
							     g_nsconfig[idx].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 {
	var PDU_NS rx;
	var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[0].local_ip,
							     g_nsconfig[0].local_udp_port, 1, 0),
						 ts_SNS_IPv4(g_nsconfig[1].local_ip,
							     g_nsconfig[1].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);
}


/* PCU-originated SNS-SIZE: successful case */
testcase TC_sns_po_size_success() runs on RAW_NS_CT {
	f_init_ns_codec();
	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_NS_CT {
	f_init_ns_codec();
	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_NS_CT {
	f_init_ns_codec();
	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_NS_CT {
	f_init_ns_codec();
	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_NS_CT {
	f_init_ns_codec();
	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, oneshot := true);
	as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, oneshot := true);
	as_rx_bvc_unblock_tx_ack(mp_gb_cfg.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.bvci, oneshot := true);
	activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci));
	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() );
}

}
