module IPA_Test {

import from IPL4asp_Types all;

import from IPA_Emulation all;

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

import from MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from L3_Templates all;

import from BSSAP_Types all;
import from BSSMAP_Templates all;

type component test_CT {
	/* component references */
	var IPA_Emulation_CT vc_IPA;
	var SCCP_CT vc_SCCP;
	/* test port to SCCP emulation */
	port SCCPasp_PT SCCP;

	var boolean g_initialized := false;
	var octetstring g_sio;
	var MSC_SCCP_MTP3_parameters g_sccp_pars;
	var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer;

	var ConnectionId g_ipa_conn_id := -1;
}

modulepar {
	PortNumber mp_local_port := 0;
	charstring mp_local_ip := "127.0.0.1";
	PortNumber mp_remote_port := 3002;
	charstring mp_remote_ip := "127.0.0.1";

	charstring mp_sccp_service_type := "mtp3_itu";

	integer mp_own_pc := 196;
	integer mp_own_ssn := 254;

	integer mp_peer_pc := 185;	/* 0.23.1 */
	integer mp_peer_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
}


function f_gen_cl3() return PDU_BSSAP {
	var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV('901770123456789'H));
	var PDU_ML3_MS_NW l3 := valueof(ts_CM_SERV_REQ('0001'B, mi));
	var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellID_LAC_CI(23, 42));
	var PDU_BSSAP bssap := valueof(ts_BSSMAP_ComplL3(cell_id, enc_PDU_ML3_MS_NW(l3)));
	return bssap;
}

function f_send_bssap_cc(PDU_BSSAP bssap) runs on test_CT {
	var ASP_SCCP_N_CONNECT_req prim;
	prim := valueof(t_ASP_N_CONNECT_req(g_sccp_addr_peer, g_sccp_addr_own, omit, omit,
				    enc_PDU_BSSAP(bssap), 23, omit));
	SCCP.send(prim);
}

function init_pars() runs on test_CT {
	g_sio := '83'O;
	g_sccp_pars := {
		sio := {
			ni := substr(oct2bit(g_sio),0,2),
			prio := substr(oct2bit(g_sio),2,2),
			si := substr(oct2bit(g_sio),4,4)
		},
		opc := mp_own_pc,
		dpc := mp_peer_pc,
		sls := 0,
		sccp_serviceType := mp_sccp_service_type,
		ssn := mp_own_ssn
	};
	g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn));
	g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn));
}

private function f_init() runs on test_CT {
	var Result res;

	if (g_initialized == true) {
		return;
	}
	g_initialized := true;

	init_pars();

	/* create components */
	vc_IPA := IPA_Emulation_CT.create;
	vc_SCCP := SCCP_CT.create;

	map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);

	/* connect MTP3 service provider (IPA) to lower side of SCCP */
	connect(vc_IPA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);

	/* connect us to upper side of SCCP */
	connect(self:SCCP, vc_SCCP:SCCP_SP_PORT);

	vc_IPA.start(IPA_Emulation.ScanEvents());
	vc_SCCP.start(SCCPStart(g_sccp_pars));

	//IPA_Emulation.f_connect(mp_remote_ip, mp_remote_port, mp_local_ip, mp_local_port);
}

testcase TC_recv_dump() runs on test_CT {
	f_init();

	var PDU_BSSAP bssap := f_gen_cl3();
	f_send_bssap_cc(bssap);

	while (true) {
		SCCP.receive;
	}
}

control {
	execute( TC_recv_dump() );
}

}
