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

}
