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_Emulation all;
import from GSUP_Types all;

import from DIAMETER_Types all;
import from DIAMETER_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());

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

}
