module DIA2GSUP_Tests {

import from Misc_Helpers all;
import from General_Types all;
import from Osmocom_Types all;
import from L3_Common all;

import from IPA_Emulation all;
import from GSUP_Types all;
import from GSUP_Templates all;
import from GSUP_Emulation all;

import from DIAMETER_Types all;
import from DIAMETER_Templates all;
import from DIAMETER_ts29_272_Templates all;
import from DIAMETER_Emulation all;

type component MTC_CT {
	var DIAMETER_Emulation_CT vc_DIAMETER;
	port DIAMETER_PT DIAMETER_UNIT;
	port DIAMETEREM_PROC_PT DIAMETER_PROC;

	var GSUP_Emulation_CT vc_GSUP;
	var IPA_Emulation_CT vc_GSUP_IPA;
	port IPA_CTRL_PT GSUP_IPA_EVENT;

	timer g_Tguard;
};

type component D2G_ConnHdlr extends DIAMETER_ConnHdlr, GSUP_ConnHdlr {
	var D2G_ConnHdlrPars g_pars;
};

type record D2G_ConnHdlrPars {
	hexstring imsi,
	AuthVector vec optional
};

private function f_init_pars(integer imsi_suffix := 1)
runs on MTC_CT return D2G_ConnHdlrPars {
	var D2G_ConnHdlrPars pars := {
		imsi := f_gen_imsi(imsi_suffix),
		vec := f_gen_auth_vec_3g()
	};
	return pars;
}


modulepar {
	/* our emulated GSUP HLR */
	charstring mp_hlr_ip := "127.0.0.1";
	integer mp_hlr_port := 4222;

	/* our emulated MME */
	charstring mp_s6_local_ip := "127.0.0.100";
	integer mp_s6_local_port := 3868;

	/* IUT behaving as HSS */
	charstring mp_hss_ip := "127.0.0.4";
	integer mp_hss_port := 3868;

	charstring mp_diam_realm := "localdomain";
}

private altstep as_Tguard() runs on MTC_CT {
	[] g_Tguard.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Tguard timeout");
	}
}

private function f_init_gsup(charstring id) runs on MTC_CT {
	id := id & "-GSUP";
	var GsupOps ops := {
		create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
	};

	vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
	vc_GSUP := GSUP_Emulation_CT.create(id);

	map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
	connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
	/* we use this hack to get events like ASP_IPA_EVENT_UP */
	connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);

	vc_GSUP.start(GSUP_Emulation.main(ops, id));
	vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));

	/* wait for incoming connection to GSUP port before proceeding */
	timer T := 10.0;
	T.start;
	alt {
	[] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
	[] T.timeout {
		setverdict(fail, "No connection to GSUP Port");
		mtc.stop;
		}
	}
}

private type function void_fn(charstring id) runs on D2G_ConnHdlr;

private function f_init_handler(void_fn fn, charstring id, D2G_ConnHdlrPars pars) runs on D2G_ConnHdlr {
	g_pars := pars;

	/* tell GSUP dispatcher to send this IMSI to us */
	f_create_gsup_expect(hex2str(g_pars.imsi));

	fn.apply(id);
}

private function f_start_handler(void_fn fn, D2G_ConnHdlrPars pars)
runs on MTC_CT return D2G_ConnHdlr {
	var D2G_ConnHdlr vc_conn;
	var charstring id := testcasename();

	vc_conn := D2G_ConnHdlr.create(id);

	connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
	connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);

	connect(vc_conn:DIAMETER, vc_DIAMETER:DIAMETER_CLIENT);
	connect(vc_conn:DIAMETER_PROC, vc_DIAMETER:DIAMETER_PROC);

	DIAMETER_UNIT.receive(DiameterCapabilityExchgInd:?);

	vc_conn.start(f_init_handler(fn, id, pars));
	return vc_conn;
}

private function DiameterForwardUnitdataCallback(PDU_DIAMETER msg)
runs on DIAMETER_Emulation_CT return template PDU_DIAMETER {
	DIAMETER_UNIT.send(msg);
	return omit;
}

private function f_init_diameter(charstring id) runs on MTC_CT {
	var DIAMETEROps ops := {
		create_cb := refers(DIAMETER_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(DiameterForwardUnitdataCallback),
		raw := false /* handler mode (IMSI based routing) */
	};
	var DIAMETER_conn_parameters pars := {
		remote_ip := mp_hss_ip,
		remote_sctp_port := mp_hss_port,
		local_ip := mp_s6_local_ip,
		local_sctp_port := mp_s6_local_port,
		origin_host := "hss." & mp_diam_realm,
		origin_realm := mp_diam_realm,
		auth_app_id := omit,
		vendor_app_id := c_DIAMETER_3GPP_S6_AID
	};
	vc_DIAMETER := DIAMETER_Emulation_CT.create(id);
	map(vc_DIAMETER:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_DIAMETER:DIAMETER_UNIT, self:DIAMETER_UNIT);
	connect(vc_DIAMETER:DIAMETER_PROC, self:DIAMETER_PROC);
	vc_DIAMETER.start(DIAMETER_Emulation.main(ops, pars, id));
}

private function f_init(float t_guard := 40.0) runs on MTC_CT {

	g_Tguard.start(t_guard);
	activate(as_Tguard());

	/* Sleep to allow the remote to forget the connection (see diameter connect timer). */
	f_sleep(1.0);
	f_init_gsup(testcasename());
	f_init_diameter(testcasename());
}


private function f_DIA_AI_success() runs on D2G_ConnHdlr {
	var PDU_DIAMETER rx_dia;
	var UINT32 hbh_id := f_rnd_octstring(4);
	var UINT32 ete_id := f_rnd_octstring(4);
	var octetstring sess_id := char2oct("foobar");
	var OCT3 vplmn := '00F110'O;

	/* Unlike AIR, AIA contains no IMSI. Register ete_id in DIAMETER_Emulation,
	 * so AIA is forwarded back to us in DIAMETER port instead of MTC_CT.DIAMETER_UNIT.
	 */
	f_diameter_expect_eteid(ete_id);

	/* Send AIR to translator; expect it to show up on GSUP side */
	DIAMETER.send(ts_DIA_AIR(g_pars.imsi, vplmn, sess_id, hbh_id := hbh_id, ete_id := ete_id));
	GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));

	/* Send a positive response back to the translator; expect AIA */
	var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
								   g_pars.vec.sres,
								   g_pars.vec.kc,
								   g_pars.vec.ik,
								   g_pars.vec.ck,
								   g_pars.vec.autn,
								   g_pars.vec.res));
	GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));

	alt {
	/* Unlike AIR, AIA contains no IMSI, hence it is received in DIAMETER_UNIT: */
	[] DIAMETER.receive(tr_DIA_AIA) {
		setverdict(pass);
		}
	[] DIAMETER.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter msg rx: ", rx_dia));
		}
	}
}

private function f_TC_authinfo_normal(charstring id) runs on D2G_ConnHdlr {
	f_DIA_AI_success();
}

testcase TC_authinfo_normal() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_normal), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_DIA_AI_gsup_error(integer gsup_cause, template (present) GenericAVP err_avp) runs on D2G_ConnHdlr {
	var PDU_DIAMETER rx_dia;
	var UINT32 hbh_id := f_rnd_octstring(4);
	var UINT32 ete_id := f_rnd_octstring(4);
	var octetstring sess_id := char2oct("foobar");
	var OCT3 vplmn := '00F110'O;

	/* Unlike AIR, AIA contains no IMSI. Register ete_id in DIAMETER_Emulation,
	 * so AIA is forwarded back to us in DIAMETER port instead of MTC_CT.DIAMETER_UNIT.
	 */
	f_diameter_expect_eteid(ete_id);

	/* Send AIR to translator; expect it to show up on GSUP side */
	DIAMETER.send(ts_DIA_AIR(g_pars.imsi, vplmn, sess_id, hbh_id := hbh_id, ete_id := ete_id));
	GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));

	/* Send an error response back to the translator; expect AIA */
	GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, gsup_cause));

	alt {
	/* Unlike AIR, AIA contains no IMSI, hence it is received in DIAMETER_UNIT: */
	[] DIAMETER.receive(tr_DIA_AIA_ERR(err_avp)) {
		setverdict(pass);
		}
	[] DIAMETER.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter msg rx: ", rx_dia));
		}
	}
}

private function f_TC_authinfo_gsup_err_imsi_unknown(charstring id) runs on D2G_ConnHdlr {
	var DIAMETER_ExperimentalResultcode res_code := DIAMETER_ERROR_USER_UNKNOWN;
	f_DIA_AI_gsup_error(2, tr_AVP_ExperimentalResult(vendor_id_3GPP, int2oct(enum2int(res_code), 4)));
}
testcase TC_authinfo_gsup_err_imsi_unknown() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_imsi_unknown), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_illegal_ms(charstring id) runs on D2G_ConnHdlr {
	var DIAMETER_ExperimentalResultcode res_code := DIAMETER_ERROR_USER_UNKNOWN;
	f_DIA_AI_gsup_error(3, tr_AVP_ExperimentalResult(vendor_id_3GPP, int2oct(enum2int(res_code), 4)));
}
testcase TC_authinfo_gsup_err_illegal_ms() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_illegal_ms), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_plmn_not_allowed(charstring id) runs on D2G_ConnHdlr {
	f_DIA_AI_gsup_error(11, tr_AVP_ResultCode(DIAMETER_UNABLE_TO_COMPLY));
}
testcase TC_authinfo_gsup_err_plmn_not_allowed() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_plmn_not_allowed), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_romaning_not_allowed(charstring id) runs on D2G_ConnHdlr {
	var DIAMETER_ExperimentalResultcode res_code := DIAMETER_ERROR_ROAMING_NOT_ALLOWED;
	f_DIA_AI_gsup_error(12, tr_AVP_ExperimentalResult(vendor_id_3GPP, int2oct(enum2int(res_code), 4)));
}
testcase TC_authinfo_gsup_err_romaning_not_allowed() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_romaning_not_allowed), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_net_fail(charstring id) runs on D2G_ConnHdlr {
	f_DIA_AI_gsup_error(17, tr_AVP_ResultCode(DIAMETER_UNABLE_TO_COMPLY));
}
testcase TC_authinfo_gsup_err_net_fail() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_net_fail), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_congestion(charstring id) runs on D2G_ConnHdlr {
	f_DIA_AI_gsup_error(22, tr_AVP_ResultCode(DIAMETER_UNABLE_TO_COMPLY));
}
testcase TC_authinfo_gsup_err_congestion() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_congestion), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_auth_unacceptable(charstring id) runs on D2G_ConnHdlr {
	f_DIA_AI_gsup_error(23, tr_AVP_ResultCode(DIAMETER_UNABLE_TO_COMPLY));
}
testcase TC_authinfo_gsup_err_auth_unacceptable() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_auth_unacceptable), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_authinfo_gsup_err_proto_unspec(charstring id) runs on D2G_ConnHdlr {
	f_DIA_AI_gsup_error(23, tr_AVP_ResultCode(DIAMETER_UNABLE_TO_COMPLY));
}
testcase TC_authinfo_gsup_err_proto_unspec() runs on MTC_CT {
	var D2G_ConnHdlrPars pars := f_init_pars();
	var D2G_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_authinfo_gsup_err_proto_unspec), pars);
	vc_conn.done;
	setverdict(pass);
}

control {
	execute ( TC_authinfo_normal() );
	execute ( TC_authinfo_gsup_err_imsi_unknown() );
	execute ( TC_authinfo_gsup_err_illegal_ms() );
	execute ( TC_authinfo_gsup_err_plmn_not_allowed() );
	execute ( TC_authinfo_gsup_err_romaning_not_allowed() );
	execute ( TC_authinfo_gsup_err_net_fail() );
	execute ( TC_authinfo_gsup_err_congestion() );
	execute ( TC_authinfo_gsup_err_auth_unacceptable() );
	execute ( TC_authinfo_gsup_err_proto_unspec() );
}

}
