module STP_Tests_M3UA_TCP {

/* Osmocom STP test suite in in TTCN-3
 * (C) 2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2024-2025 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
 */

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;
import from STP_Tests_M3UA all;

private function f_TC_m3ua_tcp(integer idx_a, integer idx_b) runs on RAW_M3UA_CT {
	var M3uaConfig cfg_a := g_m3ua_configs[idx_a];
	var M3uaConfig cfg_b := g_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 (g_m3ua_configs[idx_a].is_server) {
		f_M3UA_CLNT_asp_up_act(idx_a, rctx := rctx_a);
	} else {
		f_M3UA_asp_up_act(idx_a, rctx := rctx_a);
	}

	/* establish connection with ASP 'B' */
	if (g_m3ua_configs[idx_b].is_server) {
		f_M3UA_CLNT_asp_up_act(idx_b, rctx := rctx_b);
	} else {
		f_M3UA_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), 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 {
	var Misc_Helpers.ro_charstring asps := { "asp-sender", "asp-sender-tcp" };
	var M3uaConfigs m3ua_configs := m3ua_build_configs(asps);

	f_init_m3ua(m3ua_configs := m3ua_configs);
	f_TC_m3ua_tcp(0, 1);
}

/* test routing between M3UA/SCTP (client) and M3UA/TCP (server) */
testcase TC_m3ua_tcp_cli_srv() runs on RAW_M3UA_CT {
	var Misc_Helpers.ro_charstring asps := { "asp-sender", "asp-client0-tcp" };
	var M3uaConfigs m3ua_configs := m3ua_build_configs(asps);

	f_init_m3ua(m3ua_configs := m3ua_configs);
	f_init_m3ua_srv();
	f_TC_m3ua_tcp(0, 1);
}

/* test routing between M3UA/SCTP (server) and M3UA/TCP (server) */
testcase TC_m3ua_tcp_srv() runs on RAW_M3UA_CT {
	var Misc_Helpers.ro_charstring asps := { "asp-client0", "asp-client0-tcp" };
	var M3uaConfigs m3ua_configs := m3ua_build_configs(asps);

	f_init_m3ua(m3ua_configs := m3ua_configs);
	f_init_m3ua_srv();
	f_TC_m3ua_tcp(0, 1);
}

/* test routing between M3UA/SCTP (server) and M3UA/TCP (client) */
testcase TC_m3ua_tcp_srv_cli() runs on RAW_M3UA_CT {
	var Misc_Helpers.ro_charstring asps := { "asp-client0", "asp-sender-tcp" };
	var M3uaConfigs m3ua_configs := m3ua_build_configs(asps);

	f_init_m3ua(m3ua_configs := m3ua_configs);
	f_init_m3ua_srv();
	f_TC_m3ua_tcp(0, 1);
}

/* Test the IUT sends heartbeat procedure when needed. */
testcase TC_m3ua_tcp_beat_timeout() runs on RAW_M3UA_CT {
	var Misc_Helpers.ro_charstring asps := { "asp-sender-tcp" };
	f_TC_beat_timeout(asps);
}

/* Test the IUT sends heartbeat procedure when needed. */
testcase TC_m3ua_tcp_clnt_beat_timeout() runs on RAW_M3UA_CT {
	var Misc_Helpers.ro_charstring asps := { "asp-client0-tcp" };
	f_TC_beat_timeout(asps);
}

control {
	/* M3UA TCP Tests */
	execute( TC_m3ua_tcp_cli() );
	execute( TC_m3ua_tcp_cli_srv() );
	execute( TC_m3ua_tcp_srv() );
	execute( TC_m3ua_tcp_srv_cli() );

	execute( TC_m3ua_tcp_beat_timeout() );
	execute( TC_m3ua_tcp_clnt_beat_timeout() );
}

}