module STP_Tests_M3UA {

/* Osmocom STP test suite in in TTCN-3
 * (C) 2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * 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
 */

friend module STP_Tests;

import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from Misc_Helpers all;

import from Osmocom_VTY_Functions all;

import from M3UA_Types all;
import from M3UA_Templates all;
import from M3UA_CodecPort all;
import from M3UA_CodecPort_CtrlFunct all;

import from M3UA_Emulation all;
import from MTP3asp_Types all;
import from MTP3asp_PortType all;

import from SCCP_Types all;
import from SCCP_Templates all;
import from SCCPasp_Types all;
import from SCCP_Emulation all;

import from STP_Tests_Common all;

private const integer NR_M3UA := 4;	/* number of M3UA clients in ATS */
private const integer NR_M3UA_SRV := 4;	/* number of M3UA servres in ATS */

modulepar {
	/* STP-side IP addresses */
	HostList mp_stp_m3ua_ip := { "127.0.0.1", "::1" };
	/* local IP addresses */
	HostList mp_local_m3ua_ip := { "127.0.0.1", "::1" };
	M3uaConfigs mp_m3ua_configs := {
		/* as-sender: One ASP within AS */
		{
			use_tcp := false,
			remote_port := 2905,
			local_port := 9999,
			point_code := 23,
			routing_ctx := 1023
		},
		/* as-receiver: Two ASP within AS */
		{
			use_tcp := false,
			remote_port := 2905,
			local_port := 10000,
			point_code := 42,
			routing_ctx := 1042
		}, {
			use_tcp := false,
			remote_port := 2905,
			local_port := 10001,
			point_code := 42,
			routing_ctx := 1042
		},
		/* as-sender-tcp: One ASP within AS */
		{
			use_tcp := true,
			remote_port := 2905,
			local_port := 9999,
			point_code := 123,
			routing_ctx := 1123
		},
		/* as-client: One ASP within AS */
		{
			use_tcp := false,
			remote_port := 2906,
			local_port := 10002,
			point_code := 55,
			routing_ctx := 1055
		},
		/* as-client60-norctx */
		{
			use_tcp := false,
			remote_port := 2907,
			local_port := 11060,
			point_code := 60,
			routing_ctx := -
		},
		/* as-client61-norctx */
		{
			use_tcp := false,
			remote_port := 2907,
			local_port := 11061,
			point_code := 61,
			routing_ctx := -
		},
		/* as-client-tcp: One ASP within AS */
		{
			use_tcp := true,
			remote_port := 2906,
			local_port := 10002,
			point_code := 155,
			routing_ctx := 1155
		}
	};
	integer mp_recovery_timeout_msec := 2000;
	charstring mp_sccp_service_type := "mtp3_itu";
}

type record M3uaConfig {
	/* use TCP (true) or SCTP (false) */
	boolean use_tcp,
	/* STP-side SCTP (or TCP) port for M3UA */
	integer remote_port,
	/* local M3UA base port on TTCN3 side */
	integer local_port,
	/* point code routed via this M3U */
	integer point_code,
	/* associated routing context */
	integer routing_ctx
};
type record length (NR_M3UA+NR_M3UA_SRV) of M3uaConfig M3uaConfigs;

private function M3UA_SRV(integer idx) return integer {
	return NR_M3UA+idx;
}

private function f_m3ua_cli_config(integer idx) return M3uaConfig {
	if (idx < 0 or idx >= NR_M3UA) {
		setverdict(fail, "f_m3ua_cli_config(): unexpected idx");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
	}
	return mp_m3ua_configs[idx];
}

private function f_m3ua_srv_config(integer idx) return M3uaConfig {
	if (idx < 0 or idx >= NR_M3UA_SRV) {
		setverdict(fail, "f_m3ua_srv_config(): unexpected idx");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
	}
	return mp_m3ua_configs[M3UA_SRV(idx)];
}

type component RAW_M3UA_CT extends Test_CT {
	port M3UA_CODEC_PT M3UA[NR_M3UA+NR_M3UA_SRV];
	var integer g_m3ua_conn_id[NR_M3UA+NR_M3UA_SRV];
}

private template PortEvent tr_SctpAssocChange := {
	sctpEvent := {
		sctpAssocChange := ?
	}
}
private template PortEvent tr_SctpPeerAddrChange := {
	sctpEvent := {
		sctpPeerAddrChange := ?
	}
}
private template PortEvent tr_ConnOpened := {
	connOpened := ?
}


private altstep as_m3ua_sctp() runs on RAW_M3UA_CT {
	[] any from M3UA.receive(tr_SctpAssocChange) { repeat; }
	[] any from M3UA.receive(tr_SctpPeerAddrChange) { repeat; }
}

private altstep as_m3ua_ssnm_ignore() runs on RAW_M3UA_CT {
	var M3UA_RecvFrom rx;
	[] any from M3UA.receive(t_M3UA_RecvFrom(tr_M3UA_SSNM)) -> value rx {
		log("Ignoring M3UA SSNM", rx);
		repeat;
		}
}

friend function f_M3UA_send(integer idx, template (present) PDU_M3UA msg, integer stream := 0)
runs on RAW_M3UA_CT {
	if (mp_m3ua_configs[idx].use_tcp) {
		M3UA[idx].send(t_M3UA_Send(g_m3ua_conn_id[idx], msg, omit));
	} else {
		M3UA[idx].send(t_M3UA_Send(g_m3ua_conn_id[idx], msg, stream));
	}
}

friend function f_M3UA_exp(integer idx, template (present) PDU_M3UA msg) runs on RAW_M3UA_CT {
	var M3UA_RecvFrom rx;
	timer T := 5.0;
	T.start;
	alt {
	[] M3UA[idx].receive(t_M3UA_RecvFrom(msg)) {
		setverdict(pass);
		}
	[] M3UA[idx].receive(t_M3UA_RecvFrom(?)) -> value rx {
		setverdict(fail, "Received unexpected M3UA[", idx, "] ", rx,
			   "while waiting for ", msg);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for M3UA[", idx, "] ", msg);
		mtc.stop;
		}
	}
}

/* flush any number of queued messages matching 'msg' */
friend function f_M3UA_flush(integer idx, template (present) PDU_M3UA msg) runs on RAW_M3UA_CT {
	var M3UA_RecvFrom rx;
	timer T := 0.01;
	T.start;
	alt {
	/* this should normally be possible with something like M3UA[idx].check(receive(...)) but somehow
	 * TITAN complains about the 'check' token, so it looks that feature of TTCN3 is not supported? */
	[] M3UA[idx].receive(t_M3UA_RecvFrom(msg)) {
		repeat;
		}
	[] T.timeout {
		}
	}
}

private template (value) Socket ts_Socket(HostName hostName, PortNumber portNumber) := {
	hostName := hostName,
        portNumber := portNumber
};

private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := 3,
					   template (omit) integer stream := 0,
					   template (omit) SocketList remSocks := omit) := {
	sinfo_stream := stream,
	sinfo_ppid := ppid,
	remSocks := remSocks,
	assocId := omit
};

friend function f_M3UA_connect_sctp(integer i) runs on RAW_M3UA_CT {
	var Result res;
	var Option opt_add_local_addrs;
	var OptionList opt_list := {};
	var template SocketList opt_add_remote_addrs;
	var M3uaConfig m3cfg := mp_m3ua_configs[i];

	if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
		setverdict(fail, "Empty local or remote address trying to connect SCTP socket: ",
			   mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
		mtc.stop;
	}

	if (lengthof(mp_local_m3ua_ip) > 1) {
		opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
								           lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
		opt_list := {opt_add_local_addrs};
	}

	if (lengthof(mp_stp_m3ua_ip) > 1) {
		for (var integer j := 1; j < lengthof(mp_stp_m3ua_ip); j := j + 1) {
			var Socket sk := valueof(ts_Socket(mp_stp_m3ua_ip[j], m3cfg.remote_port));
			opt_add_remote_addrs[j - 1] := sk;
		}
	} else {
		opt_add_remote_addrs := omit;
	}

	res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], m3cfg.remote_port,
						       mp_local_m3ua_ip[0], m3cfg.local_port, 0,
						       {sctp:=valueof(ts_SCTP(3, 0, opt_add_remote_addrs))},
						       opt_list);
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect M3UA socket, check your configuration");
		mtc.stop;
	}
	g_m3ua_conn_id[i] := res.connId;
}

friend function f_M3UA_connect_tcp(integer i) runs on RAW_M3UA_CT {
	var M3uaConfig m3cfg := mp_m3ua_configs[i];
	var Result res;

	/* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
	if (not Misc_Helpers.f_osmo_repo_is("nightly")) {
		log("Not connect()ing m3cfg := ", m3cfg, " (not supported by IUT)");
		g_m3ua_conn_id[i] := -1;
		return;
	}

	if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
		setverdict(fail, "Empty local or remote address trying to connect TCP socket: ",
			   mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
		mtc.stop;
	}

	res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], m3cfg.remote_port,
						       mp_local_m3ua_ip[0], m3cfg.local_port, 0,
						       {tcp:={}});
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect M3UA socket, check your configuration");
		mtc.stop;
	}
	g_m3ua_conn_id[i] := res.connId;
	M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
}

friend function f_M3UA_close(integer i) runs on RAW_M3UA_CT {
	var Result res;
	if (g_m3ua_conn_id[i] < 0) {
		log("Not close()ing m3cfg := ", mp_m3ua_configs[i], " (not connected)");
		/* not connected */
		return;
	}
	if (mp_m3ua_configs[i].use_tcp) {
		res := M3UA_CodecPort_CtrlFunct.f_IPL4_close(M3UA[i], g_m3ua_conn_id[i], {tcp:={}});
	} else {
		res := M3UA_CodecPort_CtrlFunct.f_IPL4_close(M3UA[i], g_m3ua_conn_id[i], {sctp:=valueof(ts_SCTP)});
	}
	g_m3ua_conn_id[i] := -1;
}

friend function f_M3UA_listen(integer i) runs on RAW_M3UA_CT {
	var Result res;
	var Option opt_add_local_addrs;
	var OptionList opt_list := {};
	var M3uaConfig m3cfg := mp_m3ua_configs[i];

	/* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
	if (not Misc_Helpers.f_osmo_repo_is("nightly") and m3cfg.use_tcp) {
		log("Not listen()ing m3cfg := ", m3cfg, " (not supported by IUT)");
		return;
	}

	if (lengthof(mp_local_m3ua_ip) == 0 ) {
		setverdict(fail, "Empty local address trying to bind SCTP socket: ",
			   mp_local_m3ua_ip);
		mtc.stop;
	}

	if (lengthof(mp_local_m3ua_ip) > 1) {
		opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
								           lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
		opt_list := {opt_add_local_addrs};
	}

	if (m3cfg.use_tcp) {
		res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
							      {tcp:={}});
	} else {
		res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
							      {sctp:=valueof(ts_SCTP)}, opt_list);
	}
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not bind M3UA socket, check your configuration");
		mtc.stop;
	}
	if (m3cfg.use_tcp) {
		M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
	}
}

friend function f_init_m3ua(boolean ignore_ssnm := true) runs on RAW_M3UA_CT {
	var integer i;

	f_init_common();

	activate(as_m3ua_sctp());
	if (ignore_ssnm) {
		activate(as_m3ua_ssnm_ignore());
	}

	for (i := 0; i < NR_M3UA; i:=i+1) {
		/* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
		if (not Misc_Helpers.f_osmo_repo_is("nightly") and mp_m3ua_configs[i].use_tcp) {
			log("Not connect()ing m3cfg := ", mp_m3ua_configs[i], " (not supported by IUT)");
			g_m3ua_conn_id[i] := -1;
			continue;
		}
		map(self:M3UA[i], system:M3UA_CODEC_PT);
		if (mp_m3ua_configs[i].use_tcp) {
			f_M3UA_connect_tcp(i);
		} else {
			f_M3UA_connect_sctp(i);
		}
	}
}

friend function f_clear_m3ua() runs on RAW_M3UA_CT {
	var integer i;

	log("Clearing M3UA...");

	for (i := 0; i < NR_M3UA; i:=i+1) {
		f_M3UA_close(i);
	}
	/* Wait for recovery timer to trigger and shutdown all AS: */
	f_sleep(int2float(mp_recovery_timeout_msec)/1000.0 + 0.5);
	setverdict(pass, "M3UA cleared");
}

friend function f_init_m3ua_srv() runs on RAW_M3UA_CT {
	var integer i;
	var PortEvent port_evt;

	for (i := NR_M3UA; i < NR_M3UA+NR_M3UA_SRV; i:=i+1) {
		/* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
		if (not Misc_Helpers.f_osmo_repo_is("nightly") and mp_m3ua_configs[i].use_tcp) {
			log("Not listen()ing m3cfg := ", mp_m3ua_configs[i], " (not supported by IUT)");
			g_m3ua_conn_id[i] := -1;
			continue;
		}
		map(self:M3UA[i], system:M3UA_CODEC_PT);
		/* bind+ listen */
		f_M3UA_listen(i);
		/* wait for accept() */
		M3UA[i].receive(tr_ConnOpened) -> value port_evt {
			g_m3ua_conn_id[i] := port_evt.connOpened.connId;
		}
	}
}


/***********************************************************************
 * Test the STP in M3UA SG role (we are ASP)
 ***********************************************************************/

/* perform an outbound ASP-UP procedure */
friend function f_M3UA_asp_up(integer idx, template (omit) OCT4 aspid := omit) runs on RAW_M3UA_CT {
	f_M3UA_send(idx, ts_M3UA_ASPUP(aspid));
	f_M3UA_exp(idx, tr_M3UA_ASPUP_ACK);
}

/* perform an outbound BEAT procedure */
friend function f_M3UA_beat(integer idx, template (omit) octetstring hbd) runs on RAW_M3UA_CT {
	if (istemplatekind(hbd, "omit")) {
		f_M3UA_send(idx, ts_M3UA_BEAT(omit));
		f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(omit));
	} else {
		f_M3UA_send(idx, ts_M3UA_BEAT(ts_M3UA_hb_data(hbd)));
		f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(tr_M3UA_hb_data(hbd)));
	}
}

/* perform an outbound ASP-ACTIVATE procedure */
friend function f_M3UA_asp_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
				template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
	f_M3UA_send(idx, ts_M3UA_ASPAC(tmt, rctx));
	f_M3UA_exp(idx, tr_M3UA_ASPAC_ACK(tmt, rctx));
}

/* perform an outbound ASP-INACTIVATE procedure */
friend function f_M3UA_asp_inact(integer idx, template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
	f_M3UA_send(idx, ts_M3UA_ASPIA(rctx));
	f_M3UA_exp(idx, tr_M3UA_ASPIA_ACK(rctx));
}

/* perform outbound ASP-UP and ASP-ACT, optionally expect interemittent NOTIFY */
friend function f_M3UA_asp_up_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
				   template (omit) OCT4 rctx := omit,
				   template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
				   template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
runs on RAW_M3UA_CT {
	f_M3UA_asp_up(idx, omit);
	if (not istemplatekind(ntfy_after_up, "omit")) {
		f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, *));
	}
	f_M3UA_asp_act(idx, tmt, rctx);
	if (not istemplatekind(ntfy_after_act, "omit")) {
		f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, *));
	}
}


/* Test the ASP-UP procedure */
testcase TC_connect_asp_up() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up(0);
	f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
	f_clear_m3ua();
}

/* Test the heartbeat procedure without optional heartbeat data payload */
testcase TC_beat() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up(0);
	f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
	f_M3UA_beat(0, omit);
	f_clear_m3ua();
}

/* Test the heartbeat procedure with optional heartbeat data payload */
testcase TC_beat_payload() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up(0);
	f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
	f_M3UA_beat(0, 'a1a2a3a4a5'O);
	f_clear_m3ua();
}

/* Test the ASP-ACTIVATE procedure (without traffic-mode or routing ctx) */
testcase TC_asp_act() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up_act(0);
	f_clear_m3ua();
}

/* Test the ASP-ACTIVATE procedure with traffic-mode override */
testcase TC_asp_act_override() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up_act(0, c_M3UA_TMT_override, omit);
	f_clear_m3ua();
}

/* Test the ASP-ACTIVATE procedure with traffic-mode override */
testcase TC_asp_act_loadshare() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up_act(0, c_M3UA_TMT_loadshare, omit);
	f_clear_m3ua();
}

/* Test the ASP-ACTIVATE procedure with traffic-mode broadcast */
testcase TC_asp_act_broadcast() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_asp_up_act(0, c_M3UA_TMT_broadcast, omit);
	f_clear_m3ua();
}

/* test whether the STP accepts M3UA DATA without Routing Context IE */
testcase TC_act_rctx_data_no_rctx() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);

	f_init_m3ua();
	/* bring up the sender specifying a routing context */

	f_M3UA_asp_up_act(0, rctx := rctx_sender);
	f_M3UA_asp_up_act(1);

	/* check if DATA is accepted without Routing Context IE */
	f_test_traffic(0, omit, pc_sender, 1, rctx_receiver, pc_receiver);

	f_clear_m3ua();
}

/* Test if traffic is routed from idx_tx/pc_tx to idx_rx/pc_rx */
private function f_test_traffic(integer idx_tx, template (omit) OCT4 rctx_sender, OCT4 pc_tx,
				integer idx_rx, template (omit) OCT4 rctx_receiver, OCT4 pc_rx,
				OCT1 si := '23'O, OCT1 ni := '00'O, OCT1 mp := '00'O, OCT1 sls := '00'O)
runs on RAW_M3UA_CT {
	var octetstring data := f_rnd_octstring_rnd_len(100);
	f_M3UA_send(idx_tx, ts_M3UA_DATA(rctx_sender,
					 ts_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)), 1);
	f_M3UA_exp(idx_rx, tr_M3UA_DATA(rctx_receiver,
					tr_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)));
}


/* test "traffic-mode override" behavior */
testcase TC_tmt_override() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);

	f_init_m3ua();

	/* bring up the 'sender' side (single ASP in AS) */
	f_M3UA_asp_up_act(0, omit, omit);

	/* activate the first 'receiver' side ASP */
	f_M3UA_asp_up_act(1, c_M3UA_TMT_override, rctx_receiver);

	/* verify traffic is routed from sender to [sole] receiver */
	f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);

	/* activate the second 'receiver' side ASP (no NOTIFY as AS state doesn't change) */
	f_M3UA_asp_up_act(2, c_M3UA_TMT_override, rctx_receiver, omit, omit);

	/* we expect a NOTIFY to the *other* ASP Other/Alternat-ASP-Active */
	f_M3UA_exp(1, tr_M3UA_NOTIFY(c_M3UA_ST_T_OTHER, c_M3UA_ST_I_ALTERNATE_ASP, *));

	/* verify traffic is routed from sender to new receiver */
	f_test_traffic(0, rctx_sender, pc_sender, 2, rctx_receiver, pc_receiver);

	f_clear_m3ua();
}

private altstep as_count_rx(integer idx, template (present) PDU_M3UA exp, inout integer counter)
runs on RAW_M3UA_CT {
	[] M3UA[idx].receive(t_M3UA_RecvFrom(exp)) {
		counter := counter + 1;
		}
}

/* test "traffic-mode load-share" behavior */
testcase TC_tmt_loadshare() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
	var integer i;

	f_init_m3ua();

	/* FIXME: configure the STP via VTY to set traffic-mode */

	/* bring up the 'sender' side (single ASP in AS) */
	f_M3UA_asp_up_act(0, omit, rctx_sender);

	/* activate the first 'receiver' side ASP */
	f_M3UA_asp_up_act(1, c_M3UA_TMT_loadshare, omit); // TODO: rctx

	/* verify traffic is routed from sender to [sole] receiver */
	for (i := 0; i < 10; i := i+1) {
		f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
	}

	/* activate the second 'receiver' side ASP (no NOTIFY) */
	f_M3UA_asp_up_act(2, c_M3UA_TMT_loadshare, omit, omit, omit); // TODO: rctx

	/* verify traffic is routed from sender to new receiver */
	const integer iter_per_asp := 5;
	var integer num_rx[NR_M3UA] := { 0, 0, 0, 0 };
	for (i := 0; i < 2*iter_per_asp; i := i+1) {
		var octetstring data := f_rnd_octstring_rnd_len(100);
		var template (value) M3UA_Protocol_Data tx_pd;
		var template (present) M3UA_Protocol_Data rx_pd;
		tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
		rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
		f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
		alt {
		[] as_count_rx(1, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[1]);
		[] as_count_rx(2, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[2]);
		}
	}
	/* FIXME: check for extraneous messages? */
	for (i := 1; i <= 2; i := i+1) {
		if (num_rx[i] != iter_per_asp) {
			setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp,
				   "M3UA DATA messages at M3UA port ", i);
		}
	}
	setverdict(pass);

	f_clear_m3ua();
}

/* test "traffic-mode broadcast" behavior */
testcase TC_tmt_broadcast() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
	var integer i;

	f_init_m3ua();

	/* FIXME: configure the STP via VTY to set traffic-mode */

	/* bring up the 'sender' side (single ASP in AS) */
	f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx

	/* activate the first 'receiver' side ASP */
	f_M3UA_asp_up_act(1, c_M3UA_TMT_broadcast, omit); // TODO: rctx

	/* verify traffic is routed from sender to [sole] receiver */
	for (i := 0; i < 10; i := i+1) {
		f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
	}

	/* activate the second 'receiver' side ASP */
	f_M3UA_asp_up_act(2, c_M3UA_TMT_broadcast, omit, omit, omit); // TODO: rctx

	/* verify traffic is routed from sender to new receiver */
	for (i := 0; i < 10; i := i+1) {
		var octetstring data := f_rnd_octstring_rnd_len(100);
		var template (value) M3UA_Protocol_Data tx_pd;
		var template (present) M3UA_Protocol_Data rx_pd;
		tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
		rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
		f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
		/* each message must be received both on 1 and 2 */
		f_M3UA_exp(1, tr_M3UA_DATA(rctx_receiver, rx_pd));
		f_M3UA_exp(2, tr_M3UA_DATA(rctx_receiver, rx_pd));
	}
	setverdict(pass);

	f_clear_m3ua();
}

private function f_M3UA_rkm_register(OCT4 id, OCT3 dpc, OCT4 rctx,
				     template (present) OCT4 exp_status := c_M3UA_REGSTS_SUCCESS)
runs on RAW_M3UA_CT
{
	f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:=id, dpc:=dpc, rctx:=rctx)}));
	f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:=id, status:=exp_status, rctx:=rctx)}));
}

/* Send RKM registration; expect -EPERM as RCTX doesn't match config and dynamic not permitted */
testcase TC_rkm_reg_static_notpermitted() runs on RAW_M3UA_CT {
	f_init_m3ua();

	f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='00000099'O, dpc:='aabbcc'O)}));
	f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='00000099'O, status:=c_M3UA_REGSTS_ERR_EPERM,
						       rctx:=?)}));

	f_clear_m3ua();
}

/* Send RKM registration; expect OK as RCTX does match config */
testcase TC_rkm_reg_static_permitted() runs on RAW_M3UA_CT {
	var OCT3 dpc := int2oct(f_m3ua_cli_config(0).point_code, 3); // must match config
	var OCT4 rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);  // must match config

	f_init_m3ua();

	f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='10000099'O, dpc:=dpc, rctx:=rctx)}));
	f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='10000099'O, status:=c_M3UA_REGSTS_SUCCESS,
						       rctx:=rctx)}));

	f_clear_m3ua();
}

/* Send RKM registration; expect OK as dynamic not permitted */
testcase TC_rkm_reg_dynamic_permitted() runs on RAW_M3UA_CT {
	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
	f_init_m3ua();

	f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='20000099'O, dpc:='aabbcc'O)}));
	f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='20000099'O, status:=c_M3UA_REGSTS_SUCCESS,
						       rctx:=?)}));

	f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");

	f_clear_m3ua();
}

/* try to de-register a routing key that was never registered -> error */
testcase TC_rkm_unreg_never_registered() runs on RAW_M3UA_CT {
	f_init_m3ua();
	var octetstring rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
	f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_ERR_NOT_REG)}));
	f_clear_m3ua();
}

/* try to de-register a routing key that is invalid (non-existant) -> error */
testcase TC_rkm_unreg_invalid() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(int2oct(1234,4))));
	f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_ERR_INVAL_RCTX)}));
	f_clear_m3ua();
}

/* try to de-register a routing key that was registered -> OK */
testcase TC_rkm_unreg_registered() runs on RAW_M3UA_CT {
	var OCT3 dpc := int2oct(123, 3);
	var OCT4 rctx := int2oct(1234, 4);

	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
	f_init_m3ua();

	/* first register the routing key */
	f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);

	/* then try to de-register */
	f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
	f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));

	f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
	f_clear_m3ua();
}

/* try to de-register a routing key for an active ASP -> ERROR */
testcase TC_rkm_unreg_active() runs on RAW_M3UA_CT {
	var OCT3 dpc := int2oct(123, 3);
	var OCT4 rctx := int2oct(1234, 4);

	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
	f_init_m3ua();

	/* first register the routing key */
	f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);

	/* then activate the ASP */
	f_M3UA_asp_up_act(0);
	f_M3UA_exp(0, tr_M3UA_DAVA({*}, rctx));
	f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_ACTIVE, *));
	f_M3UA_exp(0, tr_M3UA_DAVA({*}, *));

	/* then try to de-register -> ERR_ASP_ACTIVE */
	f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
	f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_ERR_ASP_ACTIVE)}));

	/* deactivate ASP and properly de-register to clean up */
	f_M3UA_asp_inact(0);
	f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
	f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
	f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
	f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));

	f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
	f_clear_m3ua();
}

/***********************************************************************
 * Test the STP in M3UA ASP role (we are SG)
 ***********************************************************************/

/* expect/perform an inbound ASP-UP procedure */
friend function f_M3UA_CLNT_asp_up(integer idx, template OCT4 aspid := omit) runs on RAW_M3UA_CT {
	f_M3UA_exp(idx, tr_M3UA_ASPUP(aspid));
	/* there might have been multiple re-transmissions that have queued up in the ATS between
	 * the SCTP connection establishment and this function execution, so let's flush those copies. */
	f_M3UA_flush(idx, tr_M3UA_ASPUP(aspid));
	f_M3UA_send(idx, ts_M3UA_ASPUP_ACK);
}

/* expect/perform an inbound ASP-ACTIVATE procedure */
friend function f_M3UA_CLNT_asp_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
				template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
	f_M3UA_exp(idx, tr_M3UA_ASPAC(tmt, rctx));
	f_M3UA_send(idx, ts_M3UA_ASPAC_ACK(tmt, rctx));
}

/* expect/perform inbound ASP-UP and ASP-ACT, optionally send interemittent NOTIFY */
friend function f_M3UA_CLNT_asp_up_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
				   template OCT4 rctx := omit,
				   template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
				   template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
runs on RAW_M3UA_CT {
	f_M3UA_CLNT_asp_up(idx, omit);
	if (not istemplatekind(ntfy_after_up, "omit")) {
		f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, rctx));
	}
	f_M3UA_CLNT_asp_act(idx, tmt, rctx);
	if (not istemplatekind(ntfy_after_act, "omit")) {
		f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, rctx));
	}
}


/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP */
testcase TC_clnt_connect_asp_up() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_init_m3ua_srv();

	f_M3UA_CLNT_asp_up(M3UA_SRV(0));

	f_clear_m3ua();
}

/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
testcase TC_clnt_asp_act() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_init_m3ua_srv();

	var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);

	f_clear_m3ua();
}

/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
testcase TC_clnt_asp_act_tmt_loadshare() runs on RAW_M3UA_CT {
	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0", "as as-client m3ua"}, "traffic-mode loadshare");
	f_init_m3ua();
	f_init_m3ua_srv();

	var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), tmt := c_M3UA_TMT_loadshare, rctx := rctx);

	f_clear_m3ua();
}

/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
 * side STP (M3UA ASP) */
testcase TC_clnt_sg_to_asp() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 rctx_receiver := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(0).point_code, 4);

	f_init_m3ua();
	f_M3UA_asp_up_act(0);

	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_receiver);

	f_sleep(1.0);

	/* verify traffic is routed from sender to [sole] receiver */
	f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(0), rctx_receiver, pc_receiver);

	f_clear_m3ua();
}

/* Test traffic being routed through "client" side STP (M3UA ASP), coming back in "server"
 * side STP (M3UA SG) */
testcase TC_clnt_asp_to_sg() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_srv_config(0).point_code, 4);
	var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);

	f_init_m3ua();
	f_M3UA_asp_up_act(0);

	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_sender);

	f_sleep(1.0);

	/* verify traffic is routed from sender to [sole] receiver */
	f_test_traffic(M3UA_SRV(0), rctx_sender, pc_sender, 0, rctx_receiver, pc_receiver);
	f_clear_m3ua();
}

/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
 * side STP (M3UA ASP) which has no routing context set */
testcase TC_clnt_sg_to_asp_norctx() runs on RAW_M3UA_CT {
	var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(1).point_code, 4);
	var OCT4 pc_receiver2 := int2oct(f_m3ua_srv_config(2).point_code, 4);

	/* activate the sender side (ATS is client to STP in SG role) */
	f_init_m3ua();
	f_M3UA_asp_up_act(0);

	/* activate the receiver side (ATS is server to STP in ASP role) */
	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
	/* activate another instance of STP in ASP role with no routing context */
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);

	f_sleep(1.0);

	/* verify traffic is routed from sender to [sole] receiver for each PC */
	f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(1), omit, pc_receiver);
	f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(2), omit, pc_receiver2);

	f_clear_m3ua();
}

/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
 * side STP (M3UA ASP) which has no routing context set */
testcase TC_clnt_asp_to_sg_norctx() runs on RAW_M3UA_CT {
	var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
	var OCT4 pc_sender := int2oct(f_m3ua_srv_config(1).point_code, 4);
	var OCT4 pc_sender2 := int2oct(f_m3ua_srv_config(2).point_code, 4);

	/* activate the sender side (ATS is client to STP in SG role) */
	f_init_m3ua();
	f_M3UA_asp_up_act(0);

	/* activate the receiver side (ATS is server to STP in ASP role) */
	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
	/* activate another instance of STP in ASP role with no routing context */
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);

	f_sleep(1.0);

	/* verify traffic is routed from sender to [sole] receiver for each PC */
	f_test_traffic(M3UA_SRV(1), omit, pc_sender, 0, rctx_receiver, pc_receiver);
	f_test_traffic(M3UA_SRV(2), omit, pc_sender2, 0, rctx_receiver, pc_receiver);

	f_clear_m3ua();
}

/* Test if ASPAC / ASPIA of one ASP generates DAVA / DUNA on other ASP */
testcase TC_ssnm_aspac_dava_aspia_duna() runs on RAW_M3UA_CT {
	var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var integer pc0 := f_m3ua_cli_config(1).point_code;

	f_init_m3ua(ignore_ssnm := false);
	/* activate the first ASP */
	f_M3UA_asp_up_act(0);

	/* activate the second ASP */
	f_M3UA_asp_up_act(1, c_M3UA_TMT_override, omit);
	/* expect DAVA for PC of second ASP on first ASP */
	f_M3UA_exp(0, tr_M3UA_DAVA({ts_M3UA_PC(pc0, 0)}, rctx0));
	/* TODO: expect no DAVA on second ASP */

	/* deactivate the second ASP */
	f_M3UA_asp_inact(1);
	/* expect DUNA for PC of second ASP on first ASP */
	f_M3UA_exp(0, tr_M3UA_DUNA({ts_M3UA_PC(pc0, 0)}, rctx0));
	/* TODO: expect no DUNA on second ASP */

	f_clear_m3ua();
}

/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
testcase TC_ssnm_distribution_dava_duna() runs on RAW_M3UA_CT {
	var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	/* some random point code whose availability we advertise */
	var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);

	f_init_m3ua(ignore_ssnm := false);

	/* activate the first ASP */
	f_M3UA_asp_up_act(0);

	/* activate SG-role ASP (ASP on STP) */
	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);

	/* transmit a DAVA to the remote ASP */
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA({adv_pc}, rctxS0));
	/* expect that to show up on other ASP */
	f_M3UA_exp(0, tr_M3UA_DAVA({adv_pc}, rctx0));

	/* transmit a DUNA to the remote ASP */
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA({adv_pc}, rctxS0));
	/* expect that to show up on other ASP */
	f_M3UA_exp(0, tr_M3UA_DUNA({adv_pc}, rctx0));
}

/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
testcase TC_ssnm_distribution_dava_duna_multipc() runs on RAW_M3UA_CT {
	var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	/* some random point code whose availability we advertise */
	var template (value) M3UA_Point_Codes adv_pcs := { ts_M3UA_PC(1234, 0), ts_M3UA_PC(5678, 0) };

	f_init_m3ua(ignore_ssnm := false);

	/* activate the first ASP */
	f_M3UA_asp_up_act(0);

	/* activate SG-role ASP (ASP on STP) */
	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);

	/* transmit a DAVA to the remote ASP */
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA(adv_pcs, rctxS0));
	/* expect that to show up on other ASP */
	f_M3UA_exp(0, tr_M3UA_DAVA(adv_pcs, rctx0));

	/* transmit a DUNA to the remote ASP */
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA(adv_pcs, rctxS0));
	/* expect that to show up on other ASP */
	f_M3UA_exp(0, tr_M3UA_DUNA(adv_pcs, rctx0));
}

/* Test if DUPU sent from SG to ASP-role STP gets forwarded to other ASP */
testcase TC_ssnm_distribution_dupu() runs on RAW_M3UA_CT {
	var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	/* some random point code whose availability we advertise */
	var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);

	f_init_m3ua(ignore_ssnm := false);

	/* activate the first ASP */
	f_M3UA_asp_up_act(0);

	/* activate SG-role ASP (ASP on STP) */
	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);

	/* transmit a DUPU to the remote ASP */
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctxS0));
	/* expect that to show up on other ASP */
	f_M3UA_exp(0, tr_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctx0));
}

/* Test if SCON sent from SG to ASP-role STP gets forwarded to other ASP */
testcase TC_ssnm_distribution_scon() runs on RAW_M3UA_CT {
	var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
	var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	/* some random point code whose availability we advertise */
	var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);

	f_init_m3ua(ignore_ssnm := false);

	/* activate the first ASP */
	f_M3UA_asp_up_act(0);

	/* activate SG-role ASP (ASP on STP) */
	f_init_m3ua_srv();
	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);

	/* transmit a SCON to the remote ASP */
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_SCON({adv_pc}, rctxS0));
	/* expect that to show up on other ASP */
	f_M3UA_exp(0, tr_M3UA_SCON({adv_pc}, rctx0));
}

private function f_asp_cfg_str(charstring asp_name, in M3uaConfig cfg)
return charstring {
	var charstring str;

	str := "asp " & asp_name;
	str := str & " " & int2str(cfg.local_port);
	str := str & " " & int2str(cfg.remote_port);
	str := str & " m3ua";

	if (cfg.use_tcp) {
		str := str & " tcp";
	}

	return str;
}

private function f_quirk(charstring quirk) runs on RAW_M3UA_CT {
	var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
	f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "quirk " & quirk);
}

private function f_no_quirk(charstring quirk) runs on RAW_M3UA_CT {
	var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
	f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "no quirk " & quirk);
}

/* quirk 'no_notify': Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
testcase TC_clnt_quirk_no_notify_asp_act() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_quirk("no_notify");
	f_init_m3ua_srv();

	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4),
			       ntfy_after_up := omit, ntfy_after_act := omit);
	f_no_quirk("no_notify");
	f_clear_m3ua();
}

/* ensure that DAUD is not supported in ASP role, as required by RFC */
testcase TC_clnt_no_daud_in_asp() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_no_quirk("daud_in_asp");
	f_init_m3ua_srv();

	var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	var integer pc := f_m3ua_srv_config(0).point_code;

	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);

	var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
	f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000004'O, omit));
	setverdict(pass);

	f_clear_m3ua();
}

/* quirk 'daud_in_asp': allowing inbound DAUD from SG in ASP role */
testcase TC_clnt_quirk_daud_in_asp() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_quirk("daud_in_asp");
	f_init_m3ua_srv();

	var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
	var integer pc := f_m3ua_srv_config(0).point_code;

	f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);

	var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
	f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
	setverdict(pass);

	f_no_quirk("daud_in_asp");
	f_clear_m3ua();
}

/* Expect a normal ASP to reject any [S]SNM messages in ASP-INACTIVE state */
testcase TC_clnt_no_snm_inactive() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_quirk("no_notify");
	f_quirk("daud_in_asp");
	f_no_quirk("snm_inactive");
	f_init_m3ua_srv();

	/* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
	f_M3UA_CLNT_asp_up(M3UA_SRV(0));
	f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));

	var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(f_m3ua_srv_config(0).point_code) };
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
	f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000006'O, omit));
	setverdict(pass);

	f_no_quirk("no_notify");
	f_no_quirk("daud_in_asp");
	f_clear_m3ua();
}

/* quirk 'snm_inactive': Process [S]SNM in ASP-INACTIVE state */
testcase TC_clnt_quirk_snm_inactive() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_quirk("no_notify");
	f_quirk("daud_in_asp");
	f_quirk("snm_inactive");
	f_init_m3ua_srv();

	/* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
	f_M3UA_CLNT_asp_up(M3UA_SRV(0));
	f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));

	var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(f_m3ua_srv_config(0).point_code) };
	f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
	f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
	setverdict(pass);

	f_no_quirk("no_notify");
	f_no_quirk("daud_in_asp");
	f_no_quirk("snm_inactive");
	f_clear_m3ua();
}

private function f_TC_m3ua_tcp(integer idx_a, integer idx_b) runs on RAW_M3UA_CT {
	var M3uaConfig cfg_a := mp_m3ua_configs[idx_a];
	var M3uaConfig cfg_b := mp_m3ua_configs[idx_b];
	var OCT4 rctx_a := int2oct(cfg_a.routing_ctx, 4);
	var OCT4 rctx_b := int2oct(cfg_b.routing_ctx, 4);
	var OCT4 pc_a := int2oct(cfg_a.point_code, 4);
	var OCT4 pc_b := int2oct(cfg_b.point_code, 4);

	/* establish connection with ASP 'A' */
	if (idx_a < NR_M3UA) {
		f_M3UA_asp_up_act(idx_a, rctx := rctx_a);
	} else {
		f_M3UA_CLNT_asp_up_act(idx_a, rctx := rctx_a);
	}

	/* establish connection with ASP 'B' */
	if (idx_b < NR_M3UA) {
		f_M3UA_asp_up_act(idx_b, rctx := rctx_b);
	} else {
		f_M3UA_CLNT_asp_up_act(idx_b, rctx := rctx_b);
	}

	/* In the case when ASP[idx_b] is configured as the client (i.e. osmo-stp connects to
	 * the testsuite; idx_b >= NR_M3UA), in f_M3UA_CLNT_asp_up_act() we're expecting to
	 * receive ASPACT and then sending ASPACT_ACK to it.  Right after that, we're sending
	 * some random data via ASP[idx_a], which we then expect to receive via ASP[idx_b].
	 *
	 * There is a chance that the random data sent via ASP[idx_a] would reach osmo-stp
	 * earlier than the ASPUP_ACK we sent for ASP[idx_b].  This is happening most of the
	 * times when running TC_m3ua_tcp_cli_srv.  Using f_sleep() helps to avoid this. */
	f_sleep(1.0);

	/* M3UA/A -> M3UA/B */
	f_test_traffic(idx_a, rctx_a, pc_a,
		       idx_b, rctx_b, pc_b);
	/* M3UA/B -> M3UA/A */
	f_test_traffic(idx_b, rctx_b, pc_b,
		       idx_a, rctx_a, pc_a);

	f_clear_m3ua();
}

/* test routing between M3UA/SCTP (client) and M3UA/TCP (client) */
testcase TC_m3ua_tcp_cli() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_TC_m3ua_tcp(0, 3); /* 'asp-sender' <-> 'asp-sender-tcp' */
}

/* test routing between M3UA/SCTP (client) and M3UA/TCP (server) */
testcase TC_m3ua_tcp_cli_srv() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_init_m3ua_srv();
	f_TC_m3ua_tcp(0, M3UA_SRV(3)); /* 'asp-sender' <-> 'asp-client-tcp' */
}

/* test routing between M3UA/SCTP (server) and M3UA/TCP (server) */
testcase TC_m3ua_tcp_srv() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_init_m3ua_srv();
	f_TC_m3ua_tcp(M3UA_SRV(0), M3UA_SRV(3)); /* 'asp-client' <-> 'asp-client-tcp' */
}

/* test routing between M3UA/SCTP (server) and M3UA/TCP (client) */
testcase TC_m3ua_tcp_srv_cli() runs on RAW_M3UA_CT {
	f_init_m3ua();
	f_init_m3ua_srv();
	f_TC_m3ua_tcp(M3UA_SRV(0), 3); /* 'asp-client' <-> 'asp-sender-tcp' */
}


control {
	/* M3UA Tests */
	execute( TC_connect_asp_up() );
	execute( TC_beat() );
	execute( TC_beat_payload() );
	execute( TC_asp_act() );
	execute( TC_asp_act_override() );
	execute( TC_asp_act_loadshare() );
	execute( TC_asp_act_broadcast() );
	execute( TC_tmt_override() );
	execute( TC_tmt_loadshare() );
	execute( TC_tmt_broadcast() );
	execute( TC_act_rctx_data_no_rctx() );

	execute( TC_m3ua_tcp_cli() );
	execute( TC_m3ua_tcp_cli_srv() );
	execute( TC_m3ua_tcp_srv() );
	execute( TC_m3ua_tcp_srv_cli() );

	/* M3UA RKM tests */
	execute( TC_rkm_reg_static_notpermitted() );
	execute( TC_rkm_reg_static_permitted() );
	execute( TC_rkm_reg_dynamic_permitted() );
	execute( TC_rkm_unreg_never_registered() );

	execute( TC_rkm_unreg_invalid() );
	execute( TC_rkm_unreg_registered() );
	execute( TC_rkm_unreg_active() );
	/* TODO: test RKM with unsupported routing keys: NA, SI, OPC */
	/* TODO: register/unregister multiple routing contexts in one message; including mixed
	         success/failure situations */

	/* Test STP as SCTP client + M3UA ASP role */
	execute( TC_clnt_connect_asp_up() );
	execute( TC_clnt_asp_act() );
	execute( TC_clnt_sg_to_asp() );
	execute( TC_clnt_asp_to_sg() );

	execute( TC_clnt_sg_to_asp_norctx() );
	execute( TC_clnt_asp_to_sg_norctx() );

	execute( TC_clnt_quirk_no_notify_asp_act() );
	execute( TC_clnt_no_daud_in_asp() );
	execute( TC_clnt_quirk_daud_in_asp() );
	execute( TC_clnt_no_snm_inactive() );
	execute( TC_clnt_quirk_snm_inactive() );


	/* M3UA SSNM tests */
	execute( TC_ssnm_aspac_dava_aspia_duna() );
	execute( TC_ssnm_distribution_dava_duna() );
	execute( TC_ssnm_distribution_dava_duna_multipc() );
	execute( TC_ssnm_distribution_dupu() );
	execute( TC_ssnm_distribution_scon() );

	/* put this one last as it changes the stp side config */
	execute( TC_clnt_asp_act_tmt_loadshare() );
}



}
