module IPA_Test {

import from Osmocom_Types all;

import from IPL4asp_Types all;

import from IPA_Emulation all;

import from MTP3asp_Types all;

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

import from MSC_Simulation all;
import from BSC_MS_Simulation 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 {
	var MscState msc[NUM_MSC];
	var BscState bsc[NUM_BSC];

	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";

	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_init() runs on test_CT {
	var integer i;
	var charstring id;

	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);
		msc[i].MSC := MSC_CT.create;
		id := "MSC" & int2str(i);
		msc[i].MSC.start(MSC_Simulation.main(mp_msc_ip, mp_msc_port + i, msc[i].sccp_pars, msc[i].sccp_addr_own, id));
	}

	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);
		bsc[i].BSC := BSC_CT.create;
		id := "BSC" & int2str(i);
		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, bsc[i].sccp_addr_own,
							bsc[i].sccp_addr_peer, id));
	}

}

testcase TC_recv_dump() runs on test_CT {
	var integer i;
	timer T := 30.0;

	f_init();

	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;
	}
}

control {
	execute( TC_recv_dump() );
}

}
