module BSCNAT_Tests {

/* osmo-bsc_nat test suite in TTCN-3
 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
 * Author: Daniel Willmann
 * 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 Osmocom_Types all;

import from IPL4asp_Types all;

import from IPA_Emulation all;
import from RAN_Emulation all;

import from MTP3asp_Types all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

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

import from MSC_Simulation all;
import from MSC_ConnectionHandler all;
import from BSC_MS_Simulation all;
import from BSC_MS_ConnectionHandler all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

const integer NUM_MSC := 1;
const integer NUM_BSC := 1;

type record BscState {
	BSC_CT BSC,
	MSC_SCCP_MTP3_parameters sccp_pars,
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_peer
}

type record MscState {
	MSC_CT MSC,
	MSC_SCCP_MTP3_parameters sccp_pars,
	SCCP_PAR_Address sccp_addr_own
}

type component test_CT extends CTRL_Adapter_CT {
	var MscState msc[NUM_MSC];
	var BscState bsc[NUM_BSC];

	port TELNETasp_PT BSCNATVTY;

	var boolean g_initialized := false;
	var octetstring g_sio := '83'O;
}

modulepar {
	PortNumber mp_bsc_port := 49999;
	charstring mp_bsc_ip := "127.0.0.1";

	PortNumber mp_msc_port := 5000;
	charstring mp_msc_ip := "127.0.0.1";

	/* port number to which to establish the IPA CTRL connection */
	integer mp_nat_ctrl_port := 4250;
	/* port number to which to establish the SCCPLite connection */
	PortNumber mp_nat_port := 5000;
	charstring mp_nat_ip := "127.0.0.1";

	charstring mp_sccp_service_type := "mtp3_itu";

	integer mp_bsc_pc := 196;
	integer mp_bsc_ssn := 254;

	integer mp_msc_pc := 185;	/* 0.23.1 */
	integer mp_msc_ssn := 254;
}

/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := {
	addressIndicator := {
		pointCodeIndic := '1'B,
		ssnIndicator := '1'B,
		globalTitleIndic := '0000'B,
		routingIndicator := '1'B
	},
	signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O),
	//signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio),
	subsystemNumber := ssn,
	globalTitle := omit
}

template MTP3_Field_sio ts_sio(octetstring sio_in) := {
	ni := substr(oct2bit(sio_in),0,2),
	prio := substr(oct2bit(sio_in),2,2),
	si := substr(oct2bit(sio_in),4,4)
}

template MSC_SCCP_MTP3_parameters ts_SCCP_Pars(octetstring sio, integer opc, integer dpc,
						integer local_ssn) := {
	sio := ts_sio(sio),
	opc := opc,
	dpc := dpc,
	sls := 0,
	sccp_serviceType := mp_sccp_service_type,
	ssn := local_ssn
};

function f_init_BscState(inout BscState bsc_st, integer opc, integer dpc, integer local_ssn, integer remote_ssn)
runs on test_CT {
	bsc_st.sccp_pars := valueof(ts_SCCP_Pars(g_sio, opc, dpc, local_ssn));
	bsc_st.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(opc, local_ssn));
	bsc_st.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(dpc, remote_ssn));
}

function f_init_MscState(inout MscState msc_st, integer opc, integer dpc, integer local_ssn, integer remote_ssn)
runs on test_CT {
	msc_st.sccp_pars := valueof(ts_SCCP_Pars(g_sio, opc, dpc, local_ssn));
	msc_st.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(opc, local_ssn));
}

function f_vty_allow_osmux(boolean allow) runs on test_CT {
	if (allow) {
		f_vty_config(BSCNATVTY, "mgcp", "osmux on");
	} else {
		f_vty_config(BSCNATVTY, "mgcp", "osmux off");
	}
}

function f_init_vty(charstring id := "foo") runs on test_CT {
	if (BSCNATVTY.checkstate("Mapped")) {
		/* skip initialization if already executed once */
		return;
	}
	map(self:BSCNATVTY, system:BSCNATVTY);
	f_vty_set_prompts(BSCNATVTY);
	f_vty_transceive(BSCNATVTY, "enable");
}

function f_init(void_fn_bsc_ms fn_bsc_ms, void_fn_bsc fn_bsc, BssmapCreateCallback cb_msc, boolean use_osmux) runs on test_CT {
	var integer i;
	var charstring id;

	f_init_vty("VirtBSCNAT");
	f_vty_allow_osmux(use_osmux);
	f_ipa_ctrl_start(mp_nat_ip, mp_nat_ctrl_port);

	for (i := 0; i < NUM_MSC; i := i+1) {
		f_init_MscState(msc[i], mp_msc_pc +i, mp_bsc_pc, mp_msc_ssn, mp_bsc_ssn);
		id := "MSC" & int2str(i);
		msc[i].MSC := MSC_CT.create(id);
		msc[i].MSC.start(MSC_Simulation.main(mp_msc_ip, mp_msc_port + i,
						     msc[i].sccp_pars, msc[i].sccp_addr_own,
						     cb_msc, id));
	}

	/* Wait for bsc_nat to attach to MSC. Before that all BSC connections will be dropped */
	f_sleep(5.0);

	for (i := 0; i < NUM_BSC; i := i+1) {
		f_init_BscState(bsc[i], mp_bsc_pc +i, mp_msc_pc, mp_bsc_ssn, mp_msc_ssn);
		id := "BSC" & int2str(i);
		bsc[i].BSC := BSC_CT.create(id);
		var BSC_MS_TestHdlrParams pars;
		pars.sccp_addr_own := bsc[i].sccp_addr_own;
		pars.sccp_addr_remote := bsc[i].sccp_addr_peer;
		pars.use_osmux := use_osmux;
		bsc[i].BSC.start(BSC_MS_Simulation.main(mp_nat_ip, mp_nat_port, mp_bsc_ip, mp_bsc_port+i,
							bsc[i].sccp_pars, pars, fn_bsc_ms, fn_bsc, id));
	}

}

function f_wait_finish(timer T) runs on test_CT {
	var integer i;
	alt {
		/* wait for BSC to stop. The idea is that the BSC components terminate first */
		[] bsc[0].BSC.done { }
		[] T.timeout { setverdict(fail); }
	}

	all component.stop;
	/* terminate the MSCs */
	for (i := 0; i < NUM_MSC; i := i+1) {
		msc[i].MSC.stop;
	}
}


function f_TC_recv_dump(boolean use_osmux := false) runs on test_CT {
	timer T := 30.0;
	T.start;

	f_init(refers(bsc_ms_establish_fully),
	       refers(bsc_do_nothing),
	       refers(CreateCallback_establish_fully),
	       use_osmux);

	f_wait_finish(T);
}

testcase TC_recv_dump() runs on test_CT {
	f_TC_recv_dump();
}

testcase TC_recv_dump_osmux() runs on test_CT {
	f_TC_recv_dump(true);
}

testcase TC_ctrl_location() runs on test_CT {
	timer T := 30.0;
	T.start;

	f_init(refers(bsc_ms_do_nothing),
	       refers(bsc_ctrl_location),
	       refers(CreateCallback_establish_fully),
	       false);

	f_ctrl_exp_trap(IPA_CTRL, "net.0.bsc.0.bts.0.location-state",
			"1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01",
			10.0);
	f_ctrl_set(IPA_CTRL, "net.0.bsc.0.rf_locked", "1");

	f_wait_finish(T);
}

control {
	execute( TC_recv_dump() );
	execute( TC_recv_dump_osmux() );
	execute( TC_ctrl_location() );
}

}
