module STP_Tests {

/* 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
 */

import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types 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 IPA_Emulation all;

import from STP_Tests_Common all;
import from STP_Tests_IPA all;
import from STP_Tests_M3UA all;


type component IPA_M3UA_CT extends RAW_M3UA_CT, IPA_CT {
};

const OCT1 c_M3UA_SI_SCCP := '03'O;

template (value) PDU_SCCP ts_SCCP_UDT(SCCP_PAR_Address called, SCCP_PAR_Address calling,
					template (value) octetstring data,
					template (value) BIT4 msg_hdl := '0000'B) := {
	unitdata := {
		messageType := udt,
		protClass := {'0000'B, msg_hdl},
		pointer1 := 0,
		pointer2 := 0,
		pointer3 := 0,
		calledPAddress := ConvertASPAddressToEncodedAddress_itu(called),
		callingPAddress := ConvertASPAddressToEncodedAddress_itu(calling),
		data := {
			paramLength := 0,
			data := data
		}
	}
}

/* Test routing of SCCP between an M3UA and an IPA ASP */
testcase TC_m3ua_to_ipa() runs on IPA_M3UA_CT {
	var OCT4 rctx_sender := int2oct(1023, 4);
	var OCT4 pc_sender := int2oct(23, 4);
	var OCT4 pc_receiver := int2oct(5, 4);

	f_init_m3ua();
	f_init_ipa();

	f_connect_ipa(3);
	f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx

	/* send a well-formed, encoded SCCP message via M3UA */
	var octetstring data := f_rnd_octstring_rnd_len(100);
	var SCCP_PAR_Address called := valueof(ts_SccpAddr_GT('1234'H));
	var SCCP_PAR_Address calling := valueof(ts_SccpAddr_GT('5678'H));
	var PDU_SCCP sccp := valueof(ts_SCCP_UDT(called, calling, data));
	var octetstring sccp_enc := enc_PDU_SCCP(sccp);
	var template (value) M3UA_Protocol_Data tx_pd;
	tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, c_M3UA_SI_SCCP, '00'O, '00'O, '00'O, sccp_enc);
	f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);

	/* expect to receive it via IPA */
	f_IPA_exp(3, sccp_enc);

	f_clear_m3ua();
}

/* test routing an SCCP message from IPA ASP to M3UA ASP */
testcase TC_ipa_to_m3ua() runs on IPA_M3UA_CT {
	var OCT4 pc_sender := int2oct(5, 4);
	var OCT4 rctx_receiver := int2oct(1023, 4);
	var OCT4 pc_receiver := int2oct(23, 4);

	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0", "as ipa-as-dynamic-asp ipa"},
		      "point-code override patch-sccp disabled");

	f_init_m3ua();
	f_init_ipa();

	f_connect_ipa(3);
	f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx

	/* send a well-formed, encoded SCCP message via IPA */
	var octetstring data := f_rnd_octstring_rnd_len(100);
	var SCCP_PAR_Address called := valueof(ts_SccpAddr_GT('1234'H));
	var SCCP_PAR_Address calling := valueof(ts_SccpAddr_GT('5678'H));
	var PDU_SCCP sccp := valueof(ts_SCCP_UDT(called, calling, data));
	var octetstring sccp_enc := enc_PDU_SCCP(sccp);
	f_IPA_send(3, sccp_enc);

	/* expect to receive it via M3UA */
	var template (present) M3UA_Protocol_Data rx_pd;
	rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, c_M3UA_SI_SCCP, '00'O, '00'O, ?, sccp_enc);
	f_M3UA_exp(0, tr_M3UA_DATA(rctx_receiver, rx_pd));

	f_clear_m3ua();
}

/* test routing an SCCP message from IPA ASP to M3UA ASP using national network indicator */
testcase TC_ipa_to_m3ua_ni() runs on IPA_M3UA_CT {
	var OCT4 pc_sender := int2oct(5, 4);
	var OCT4 rctx_receiver := int2oct(1023, 4);
	var OCT4 pc_receiver := int2oct(23, 4);

	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0", "as ipa-as-dynamic-asp ipa"},
		      "point-code override patch-sccp disabled");

	f_init_m3ua();
	f_init_ipa();

	f_connect_ipa(3);
	f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx

	/* send a well-formed, encoded SCCP message via IPA */
	var octetstring data := f_rnd_octstring_rnd_len(100);
	var SCCP_PAR_Address called := valueof(ts_SccpAddr_GT('1234'H));
	var SCCP_PAR_Address calling := valueof(ts_SccpAddr_GT('5678'H));
	var PDU_SCCP sccp := valueof(ts_SCCP_UDT(called, calling, data));
	var octetstring sccp_enc := enc_PDU_SCCP(sccp);
	f_vty_config2(VTY, {"cs7 instance 0"}, "network-indicator national");
	f_IPA_send(3, sccp_enc);

	/* expect to receive it via M3UA */
	var template (present) M3UA_Protocol_Data rx_pd;
	rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, c_M3UA_SI_SCCP, c_M3UA_NI_NATIONAL,
					'00'O, ?, sccp_enc);
	f_M3UA_exp(0, tr_M3UA_DATA(rctx_receiver, rx_pd));
	f_vty_config2(VTY, {"cs7 instance 0"}, "network-indicator international");
	f_clear_m3ua();
}


/* test routing an SCCP message from IPA ASP to M3UA ASP while patching PC into SCCP addresses */
testcase TC_ipa_to_m3ua_patch_sccp() runs on IPA_M3UA_CT {
	var OCT4 pc_sender := int2oct(5, 4);
	var OCT4 rctx_receiver := int2oct(1023, 4);
	var OCT4 pc_receiver := int2oct(23, 4);

	f_init_common();
	f_vty_config2(VTY, {"cs7 instance 0", "as ipa-as-dynamic-asp ipa"},
			"point-code override patch-sccp both");

	f_init_m3ua();
	f_init_ipa();

	f_connect_ipa(3);
	f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx

	/* send a well-formed, encoded SCCP message via IPA */
	var octetstring data := f_rnd_octstring_rnd_len(100);
	var SCCP_PAR_Address called := valueof(ts_SccpAddr_GT('1234'H));
	var SCCP_PAR_Address calling := valueof(ts_SccpAddr_GT('5678'H));
	var PDU_SCCP sccp := valueof(ts_SCCP_UDT(called, calling, data));
	f_IPA_send(3, enc_PDU_SCCP(sccp));

	/* patch point codes into addresses */
	called := valueof(ts_SccpAddr_PC_GT(oct2int(pc_receiver), '83'O, "mtp3_itu", '1234'H));
	calling := valueof(ts_SccpAddr_PC_GT(oct2int(pc_sender), '83'O, "mtp3_itu", '5678'H));
	var PDU_SCCP sccp_exp := valueof(ts_SCCP_UDT(called, calling, data));

	/* expect to receive it via M3UA */
	var template (present) M3UA_Protocol_Data rx_pd;
	rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, c_M3UA_SI_SCCP, '00'O, '00'O, ?,
					enc_PDU_SCCP(sccp_exp));
	f_M3UA_exp(0, tr_M3UA_DATA(rctx_receiver, rx_pd));

	f_clear_m3ua();
}



control {
	/* M3UA <-> IPA Tests */
	execute( TC_m3ua_to_ipa() );
	execute( TC_ipa_to_m3ua() );
	execute( TC_ipa_to_m3ua_ni() );
	execute( TC_ipa_to_m3ua_patch_sccp() );
}



}
