module STP_Tests_IPA {

/* Osmocom STP test suite in in TTCN-3
 * (C) 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
 */

friend module STP_Tests;

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

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

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

import from IPA_Emulation all;

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

import from STP_Tests_Common all;

private const integer NR_IPA := 7;

type record of charstring AspNameArray;

modulepar {
	integer mp_stp_ipa_port := 5000;
	integer mp_local_ipa_port := 20000;
	AspNameArray mp_ipa_as_names := {"ipa-as-loadshare-sender",
					 "ipa-as-loadshare-receiver",
					 "ipa-as-loadshare-receiver",
					 "ipa-as-dynamic-asp",
					 "ipa-as-override-sender",
					 "ipa-as-override-receiver",
					 "ipa-as-override-receiver"
					 };
}

type component IPA_CT extends Test_CT {
	/* for IPA we use the IPA_Emulation and not directly IPA_CodecPort to avoid
	 * having to re-invent IPA CCM handling here */
	port MTP3asp_PT IPA[NR_IPA];
	var IPA_Emulation_CT vc_IPA[NR_IPA];
	var IPA_CCM_Parameters g_ccm_pars[NR_IPA];
}

friend function f_IPA_send(integer idx, octetstring data) runs on IPA_CT {
	var MTP3_Field_sio sio := { ni := '00'B, prio := '00'B, si := '0011'B };
	IPA[idx].send(t_ASP_MTP3_TRANSFERreq(sio, 0, 0, 0, data));
}

friend function f_IPA_exp(integer idx, template (present) octetstring data) runs on IPA_CT {
	alt {
	[] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, data)) {
		setverdict(pass);
		}
	[] IPA[idx].receive {
		setverdict(fail, "Received unexpected data on IPA port while waiting for ", data);
		mtc.stop;
		}
	}
}

private function f_rnd_ipa_len() runs on IPA_CT return integer {
	var integer rnd_len := f_rnd_int(100);
	/* We need at least 1 byte of data, othewise osmocom IPA stack will discard and close the socket */
	if (rnd_len == 0) {
		rnd_len := 1;
	}
	return rnd_len;
}

/* Test if traffic is routed from idx_tx to idx_rx */
private function f_test_traffic(integer idx_tx, integer idx_rx)
runs on IPA_CT {
	var octetstring data := f_rnd_octstring(f_rnd_ipa_len());
	f_IPA_send(idx_tx, data);
	f_IPA_exp(idx_rx, data);
}

friend function f_init_ipa() runs on IPA_CT {
	var integer i;

	f_init_common();

	for (i := 0; i < NR_IPA; i:=i+1) {
		vc_IPA[i] := IPA_Emulation_CT.create("IPA" & int2str(i));
		map(vc_IPA[i]:IPA_PORT, system:IPA_CODEC_PT);
		connect(self:IPA[i], vc_IPA[i]:MTP3_SP_PORT);
		g_ccm_pars[i] := c_IPA_default_ccm_pars;
		g_ccm_pars[i].name := mp_ipa_as_names[i];
	}
}

friend function f_connect_ipa(integer idx, boolean use_unknown_asp_port := false) runs on IPA_CT {
	var integer port_offset := 0;
	if (use_unknown_asp_port) {
		/* Add 100 to the port since we know that port is not configured in any
		  ASP only up to NR_IPA are configured. */
		port_offset := 100;
	}
	vc_IPA[idx].start(IPA_Emulation.main_client(mp_stp_ip, mp_stp_ipa_port, mp_local_ip,
			mp_local_ipa_port + idx + port_offset, g_ccm_pars[idx]));
}


/* "accept-asp-connections pre-configured" and client from unknown source */
testcase TC_unknown_client_nodynamic() runs on IPA_CT {
	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
		      "accept-asp-connections pre-configured");
	f_init_ipa();
	f_connect_ipa(0, true);
	f_sleep(1.0);
	if (IPA[0].checkstate("Connected")) {
		setverdict(fail, "Expected IPA port to be disconnected");
	} else {
		setverdict(pass);
	}
	/* switch back to default */
	f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
		      "accept-asp-connections dynamic-permitted");
}

/* "accept-asp-connections pre-configured" and client from known source */
testcase TC_known_client_nodynamic() runs on IPA_CT {
	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
		      "accept-asp-connections pre-configured");
	f_init_ipa();
	f_connect_ipa(0, false);
	f_sleep(1.0);
	if (not IPA[0].checkstate("Connected")) {
		setverdict(fail, "Expected IPA port to be connected");
	} else {
		setverdict(pass);
	}
	/* switch back to default */
	f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
		      "accept-asp-connections dynamic-permitted");
}


/* "accept-asp-connections dynamic-permitted" and client from unknown source */
testcase TC_unknown_client_dynamic() runs on IPA_CT {
	f_init_common();
	f_init_ipa();
	f_connect_ipa(0, true);
	f_sleep(1.0);
	if (not IPA[0].checkstate("Connected")) {
		setverdict(fail, "Expected IPA port to be connected");
	} else {
		setverdict(pass);
	}
}

private function f_tc_tmt_override(boolean unknwon_dynamic_asp)
runs on IPA_CT {
	f_init_ipa();

	/* bring up the 'sender' side (single ASP in AS) */
	f_connect_ipa(4, unknwon_dynamic_asp);
	/* activate the first 'receiver' side ASP */
	f_connect_ipa(5, unknwon_dynamic_asp);
	f_sleep(1.0);

	/* verify traffic is routed from sender to [sole] receiver */
	f_test_traffic(4, 5);

	/* activate the second 'receiver' side ASP */
	f_connect_ipa(6, unknwon_dynamic_asp);
	f_sleep(1.0);

	/* verify traffic is routed from sender to new receiver */
	f_test_traffic(4, 6);
}

/* test "traffic-mode override" behavior */
testcase TC_tmt_override() runs on IPA_CT {
	f_tc_tmt_override(false);
}

/* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */
testcase TC_unknown_client_dynamic_tmt_override() runs on IPA_CT {
	f_tc_tmt_override(true);
}

private altstep as_count_rx(integer idx, template (present) octetstring exp, inout integer counter)
runs on IPA_CT {
	[] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, exp)) {
		counter := counter + 1;
		}
}

private function f_tc_tmt_loadshare(boolean unknwon_dynamic_asp)
runs on IPA_CT {
	var integer i;

	f_init_ipa();

	/* bring up the 'sender' side (single ASP in AS) */
	f_connect_ipa(0, unknwon_dynamic_asp);
	/* activate the first 'receiver' side ASP */
	f_connect_ipa(1, unknwon_dynamic_asp);
	f_sleep(1.0);

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

	/* activate the second 'receiver' side ASP */
	f_connect_ipa(2, unknwon_dynamic_asp);
	f_sleep(1.0);

	/* verify traffic is routed from sender to new receiver */
	const integer iter_per_asp := 5;
	var integer num_rx[3] := { 0, 0, 0 };
	for (i := 0; i < 2*iter_per_asp; i := i+1) {
		var octetstring data := f_rnd_octstring(f_rnd_ipa_len());
		f_IPA_send(0, data);
		alt {
		[] as_count_rx(1, data, num_rx[1])
		[] as_count_rx(2, data, 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,
				   "DATA messages at IPA port ", i);
		}
	}
	setverdict(pass);
}

/* test "traffic-mode load-share" behavior */
testcase TC_tmt_loadshare() runs on IPA_CT {
	f_tc_tmt_loadshare(false);
}

/* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */
testcase TC_unknown_client_dynamic_tmt_loadshare() runs on IPA_CT {
	f_tc_tmt_override(true);
}

control {
	execute( TC_unknown_client_nodynamic() );
	execute( TC_known_client_nodynamic() );
	execute( TC_unknown_client_dynamic() );
	execute( TC_tmt_override() );
	execute( TC_unknown_client_dynamic_tmt_override() );
	execute( TC_tmt_loadshare() );
	execute( TC_unknown_client_dynamic_tmt_loadshare() );
}


}
