module EPDG_Tests {

import from Misc_Helpers all;
import from General_Types all;
import from Native_Functions 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_273_Templates all;
import from DIAMETER_Emulation all;

import from GTPv2_Types all;
import from GTPv2_Templates all;
import from GTPv2_Emulation all;

modulepar {
	/* our emulated GSUP strongswan (CEAI iface) */
	charstring mp_gsup_local_ip := "127.0.0.100";
	integer mp_gsup_local_port := 0;
	charstring mp_gsup_remote_ip := "127.0.0.1";
	integer mp_gsup_remote_port := 4222;

	/* our emulated HSS */
	charstring mp_swx_local_ip := "127.0.0.100";
	integer mp_swx_local_port := 3868;

	/* our emulated PGW (Diameter S6b) */
	charstring mp_s6b_local_ip := "127.0.0.100";
	integer mp_s6b_local_port := 3869;
	charstring mp_s6b_remote_ip := "127.0.0.1";
	integer mp_s6b_remote_port := 3869;

	/* our emulated PGW (GTPv2C S2b) */
	charstring mp_s2b_local_ip := "127.0.0.100";
	integer mp_s2b_local_port := GTP2C_PORT;
	charstring mp_s2b_remote_ip := "127.0.0.1";
	integer mp_s2b_remote_port := GTP2C_PORT;

	charstring mp_diam_realm := "localdomain";
	integer mp_diam_watchdog_initial_wait_sec := 6*3;
}


type component MTC_CT {
	var DIAMETER_Emulation_CT vc_SWx;
	port DIAMETER_PT SWx_UNIT;
	port DIAMETEREM_PROC_PT SWx_PROC;

	var DIAMETER_Emulation_CT vc_S6b;
	port DIAMETER_PT S6b_UNIT;
	port DIAMETEREM_PROC_PT S6b_PROC;

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

	var GTPv2_Emulation_CT vc_GTP2;
	port GTP2EM_PT TEID0;

	timer g_Tguard;
};

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

type component DIAMETER_ConnHdlr_CT extends DIAMETER_ConnHdlr {
	port DIAMETER_Conn_PT DIAMETER_CLIENT;
	port DIAMETEREM_PROC_PT DIAMETER_PROC_CLIENT;
}

function f_diam_connhldr_ct_main(hexstring imsi) runs on DIAMETER_ConnHdlr_CT {
	var DIAMETER_ConnHdlr vc_conn_unused;
	var PDU_DIAMETER msg;
	var UINT32 ete_id;

	f_diameter_expect_imsi(imsi);


	while (true) {
		alt {
		[] DIAMETER_CLIENT.receive(PDU_DIAMETER:?) -> value msg {
			DIAMETER.send(msg);
			}
		[] DIAMETER.receive(PDU_DIAMETER:?) -> value msg {
			DIAMETER_CLIENT.send(msg);
			}
		[] DIAMETER_PROC_CLIENT.getcall(DIAMETEREM_register_eteid:{?,?}) -> param(ete_id, vc_conn_unused) {
			DIAMETER_PROC.call(DIAMETEREM_register_eteid:{ete_id, self}) {
				[] DIAMETER_PROC.getreply(DIAMETEREM_register_eteid:{?,?}) {};
				}
			DIAMETER_PROC_CLIENT.reply(DIAMETEREM_register_eteid:{ete_id, vc_conn_unused});
			}
		}
	}
}

type component EPDG_ConnHdlr extends DIAMETER_ConnHdlr, GSUP_ConnHdlr, GTP2_ConnHdlr {
	var EPDG_ConnHdlrPars g_pars;

	port DIAMETER_Conn_PT SWx;
	port DIAMETEREM_PROC_PT SWx_PROC;
	port DIAMETER_Conn_PT S6b;
	port DIAMETEREM_PROC_PT S6b_PROC;
};


type record BearerConfig {
	 /* EPS Bearer ID */
	uint4_t		ebi optional,
	/* TEI (Data) local side */
	OCT4 		teid_local optional,
	/* TEI (Data) remote side */
	OCT4 teid_remote optional
};

type record EPDG_ConnHdlrPars {
	hexstring imsi,
	charstring apn,
	charstring ue_ip,

	/* TEI (Control) local side */
	OCT4 teic_local,
	/* TEI (Control) remote side */
	OCT4 teic_remote optional,

	BearerConfig bearer optional,

	AuthVector vec optional
};

private function f_epdg_connhldr_SWx_expect_eteid(UINT32 ete_id) runs on EPDG_ConnHdlr {
	SWx_PROC.call(DIAMETEREM_register_eteid:{ete_id, null}) {
		[] SWx_PROC.getreply(DIAMETEREM_register_eteid:{?,?}) {};
	}
}
private function f_epdg_connhldr_S6b_expect_eteid(UINT32 ete_id) runs on EPDG_ConnHdlr {
	S6b_PROC.call(DIAMETEREM_register_eteid:{ete_id, null}) {
		[] S6b_PROC.getreply(DIAMETEREM_register_eteid:{?,?}) {};
	}
}

private function f_init_pars(integer imsi_suffix := 1)
runs on MTC_CT return EPDG_ConnHdlrPars {
	var EPDG_ConnHdlrPars pars := {
		imsi := f_gen_imsi(imsi_suffix),
		apn := "internet",
		ue_ip := "192.168.123.50",
		teic_local := '00000000'O,
		teic_remote := omit,
		bearer := {
			ebi := omit,
			teid_local := omit,
			teid_remote := omit
		},
		vec := f_gen_auth_vec_3g()
	};
	return pars;
}

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_client(mp_gsup_remote_ip, mp_gsup_remote_port,
						    mp_gsup_local_ip, mp_gsup_local_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 {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "No connection to GSUP Port");
		}
	}
}

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;

	/* SWx setup: */
	pars := {
		remote_ip := "",
		remote_sctp_port := -1, /* server mode */
		local_ip := mp_swx_local_ip,
		local_sctp_port := mp_swx_local_port,
		origin_host := "hss." & mp_diam_realm,
		origin_realm := mp_diam_realm,
		auth_app_id := omit,
		vendor_app_id := c_DIAMETER_3GPP_SWx_AID
	};
	vc_SWx := DIAMETER_Emulation_CT.create(id);
	map(vc_SWx:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_SWx:DIAMETER_UNIT, self:SWx_UNIT);
	connect(vc_SWx:DIAMETER_PROC, self:SWx_PROC);
	vc_SWx.start(DIAMETER_Emulation.main(ops, pars, id));

	/* S6b setup: */
	pars := {
		remote_ip := mp_s6b_remote_ip,
		remote_sctp_port := mp_s6b_remote_port, /* client mode */
		local_ip := mp_s6b_local_ip,
		local_sctp_port := mp_s6b_local_port,
		origin_host := "pgw." & mp_diam_realm,
		origin_realm := mp_diam_realm,
		auth_app_id := c_DIAMETER_3GPP_S6b_AID,
		vendor_app_id := c_DIAMETER_3GPP_S6b_AID
	};
	vc_S6b := DIAMETER_Emulation_CT.create(id);
	map(vc_S6b:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_S6b:DIAMETER_UNIT, self:S6b_UNIT);
	connect(vc_S6b:DIAMETER_PROC, self:S6b_PROC);
	vc_S6b.start(DIAMETER_Emulation.main(ops, pars, id));

	f_diameter_wait_capability(SWx_UNIT);
	f_diameter_wait_capability(S6b_UNIT);

	/* Give some time for our emulation to get out of SUSPECT list of SUT (3 watchdog ping-pongs):
	 * RFC6733 sec 5.1
	 * RFC3539 sec 3.4.1 [5]
	 * https://github.com/freeDiameter/freeDiameter/blob/master/libfdcore/p_psm.c#L49
	 */
	f_sleep(int2float(mp_diam_watchdog_initial_wait_sec));
}

private function f_init_gtp(charstring id) runs on MTC_CT {
	var Gtp2EmulationCfg cfg := {
		gtpc_bind_ip := mp_s2b_local_ip,
		gtpc_bind_port := mp_s2b_local_port,
		gtpc_remote_ip := mp_s2b_remote_ip,
		gtpc_remote_port := mp_s2b_remote_port,
		sgw_role := false,
		use_gtpu_daemon := false /* TODO: maybe use, set to true */
	};

	vc_GTP2 := GTPv2_Emulation_CT.create(id & "-GTPV2");
	map(vc_GTP2:GTP2C, system:GTP2C);
	connect(vc_GTP2:TEID0, self:TEID0);
	vc_GTP2.start(GTPv2_Emulation.main(cfg));
}

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

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

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

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

	/* tell GTPv2 dispatcher to send this IMSI to us */
	f_gtp2_register_imsi(g_pars.imsi);

	fn.apply(id);
}

private function f_start_handler(void_fn fn, EPDG_ConnHdlrPars pars)
runs on MTC_CT return EPDG_ConnHdlr {
	var EPDG_ConnHdlr vc_conn;
	var charstring id := testcasename();
	var DIAMETER_ConnHdlr_CT vc_conn_swx, vc_conn_s6b;

	vc_conn := EPDG_ConnHdlr.create(id);

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

	/* GTP2 */
	connect(vc_conn:GTP2, vc_GTP2:CLIENT);
	connect(vc_conn:GTP2_PROC, vc_GTP2:CLIENT_PROC);

	/* SWx */
	vc_conn_swx := DIAMETER_ConnHdlr_CT.create(id);
	connect(vc_conn_swx:DIAMETER, vc_SWx:DIAMETER_CLIENT);
	connect(vc_conn_swx:DIAMETER_PROC, vc_SWx:DIAMETER_PROC);
	connect(vc_conn:SWx, vc_conn_swx:DIAMETER_CLIENT);
	connect(vc_conn:SWx_PROC, vc_conn_swx:DIAMETER_PROC_CLIENT);
	vc_conn_swx.start(f_diam_connhldr_ct_main(pars.imsi));

	/* S6b */
	vc_conn_s6b := DIAMETER_ConnHdlr_CT.create(id);
	connect(vc_conn_s6b:DIAMETER, vc_S6b:DIAMETER_CLIENT);
	connect(vc_conn_s6b:DIAMETER_PROC, vc_S6b:DIAMETER_PROC);
	connect(vc_conn:S6b, vc_conn_s6b:DIAMETER_CLIENT);
	connect(vc_conn:S6b_PROC, vc_conn_s6b:DIAMETER_PROC_CLIENT);
	vc_conn_s6b.start(f_diam_connhldr_ct_main(pars.imsi));

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

/* Diameter SWx MAR + MAA. */
private altstep as_DIA_SWx_MA_success() runs on EPDG_ConnHdlr {
	var PDU_DIAMETER rx_dia;
	var template (omit) AVP avp;
	var octetstring sess_id;
	var template (value) GenericAVP sip_auth_data_item;
	[] SWx.receive(tr_DIA_SWx_MAR(g_pars.imsi)) -> value rx_dia {
		avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);
		sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
		sip_auth_data_item := ts_AVP_3GPP_SIPAuthDataItem(0,
								  g_pars.vec.rand,
								  g_pars.vec.ik,
								  g_pars.vec.ck,
								  g_pars.vec.autn,
								  g_pars.vec.auts);
		/* Send MAA to translator; expect it to show up on GSUP side */
		SWx.send(ts_DIA_SWx_MAA(g_pars.imsi, sip_auth_data_item,
					sess_id := sess_id,
					hbh_id := rx_dia.hop_by_hop_id,
					ete_id := rx_dia.end_to_end_id));
		setverdict(pass);
	}
	[] SWx.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter msg rx: ", rx_dia));
	}
}

/* Diameter SWx SAR + SAA. */
private altstep as_DIA_SWx_SA_success(template (present) CxDx_3GPP_Server_Assignment_Type server_ass_type := ?) runs on EPDG_ConnHdlr {
	var PDU_DIAMETER rx_dia;
	var template (omit) AVP avp;
	var octetstring sess_id;
	[] SWx.receive(tr_DIA_SWx_SAR(g_pars.imsi)) -> value rx_dia {
		avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);
		sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
		/* Send SAA to translator; expect it to show up on GSUP side */
		SWx.send(ts_DIA_SWx_SAA(g_pars.imsi,
					sess_id := sess_id,
					hbh_id := rx_dia.hop_by_hop_id,
					ete_id := rx_dia.end_to_end_id));
		setverdict(pass);
	}
	[] SWx.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter msg rx: ", rx_dia));
	}
}

/* Send AAR as PGW to AAA server, expect back AAA */
private function f_S6b_AA_success() runs on EPDG_ConnHdlr {
	var PDU_DIAMETER rx_dia;
	var UINT32 hbh_id := f_rnd_octstring(4);
	var UINT32 ete_id := f_rnd_octstring(4);

	/* Unlike AAR, AAA 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_epdg_connhldr_S6b_expect_eteid(ete_id);

	S6b.send(ts_DIA_S6b_AAR(g_pars.imsi,
				int2oct(DIA_TS29_373_MIP6_Feature_Vector_GTPv2_SUPPORTED, 8),
				g_pars.apn, hbh_id := hbh_id, ete_id := ete_id));

	/* AAR in S6b in AAA-Server triggers Service-Assignment Request/Answer towards HSS: */
	as_DIA_SWx_SA_success();

	alt {
	[] S6b.receive(tr_DIA_S6b_AAA) -> value rx_dia {}
	[] S6b.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter S6b msg rx: ", rx_dia));
		}
	}
}

/* Send STR as PGW to AAA server, expect back STA */
private function f_S6b_ST_success() runs on EPDG_ConnHdlr {
	var PDU_DIAMETER rx_dia;
	var UINT32 hbh_id := f_rnd_octstring(4);
	var UINT32 ete_id := f_rnd_octstring(4);

	/* Unlike STR, STA 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_epdg_connhldr_S6b_expect_eteid(ete_id);

	S6b.send(ts_DIA_S6b_STR(g_pars.imsi, DIAMETER_LOGOUT,
				hbh_id := hbh_id, ete_id := ete_id));
	alt {
	[] S6b.receive(tr_DIA_S6b_STA(DIAMETER_SUCCESS)) -> value rx_dia {}
	[] S6b.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter S6b msg rx: ", rx_dia));
		}
	}
}

/* ePDG Creates session at the PGW. PGW sends Diameter s6b AAR + AAA. */
private altstep as_GTP2C_CreateSession_success() runs on EPDG_ConnHdlr {
	var PDU_GTPCv2 rx_msg;
	var BearerContextIEs rx_bctx_ies;
	var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie;
	var template (value) PDN_AddressAllocation paa;
	var template (value) BearerContextIEs bctx_ies;

	[] GTP2.receive(tr_GTP2C_CreateSessionReq(g_pars.imsi)) -> value rx_msg {
		/* Parse TEIC and Bearer EBI and TEID and store it in g_pars */
		g_pars.teic_remote := rx_msg.gtpcv2_pdu.createSessionRequest.fullyQualifiedTEID[0].tEID_GRE_Key;
		rx_bctx_ies := rx_msg.gtpcv2_pdu.createSessionRequest.bearerContextGrouped[0].bearerContextIEs;
		g_pars.bearer.ebi := rx_bctx_ies.ePS_Bearer_ID.ePS_Bearer_ID_Value;
		g_pars.bearer.teid_remote := rx_bctx_ies.fullyQualifiedTEID[0].tEID_GRE_Key;

		/* allocate + register TEID-C on local side */
		g_pars.teic_local := f_gtp2_allocate_teid();
		g_pars.bearer.teid_local := g_pars.teic_local;

		/* Upon rx of CreateSession, emulate PGW asking the AAA server. */
		f_S6b_AA_success();

		fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S2b_ePDG_GTPC, g_pars.teic_local, 0,
					f_inet_addr(mp_s2b_local_ip), omit);
		fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S2bU_ePDG_GTPU, g_pars.bearer.teid_local, 2,
					f_inet_addr(mp_s2b_local_ip), omit);
		paa := ts_GTP2C_PdnAddrAlloc_v4(f_inet_addr(g_pars.ue_ip));
		bctx_ies := ts_GTP2C_BcContextIE(ebi := g_pars.bearer.ebi,
						 teid_list := { fteid_u_ie },
						 qos := ts_GTP2C_BearerQos('09'O, 0,0,0,0),
						 charging_id := ts_GTP2C_ChargingID(g_pars.teic_local));
		GTP2.send(ts_GTP2C_CreateSessionResp(g_pars.teic_remote, rx_msg.sequenceNumber,
						     { fteid_c_ie }, paa,
						     { ts_GTP2C_BcGrouped(bctx_ies) } ));
		setverdict(pass);
	}
	[] GTP2.receive(PDU_GTPCv2:?) -> value rx_msg {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GTP2C msg rx: ", rx_msg));
	}
}

/* ePDG Deletes session at the PGW. PGW sends Diameter s6b AAR + AAA. */
private altstep as_GTP2C_DeleteSession_success() runs on EPDG_ConnHdlr {
	var PDU_GTPCv2 rx_msg;
	var BearerContextIEs rx_bctx_ies;
	var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie;
	var template (value) PDN_AddressAllocation paa;
	var template (value) BearerContextIEs bctx_ies;

	[] GTP2.receive(tr_GTP2C_DeleteSessionReq(g_pars.teic_local)) -> value rx_msg {
		/* Upon rx of DeleteSession, emulate PGW requesting the AAA server for Sesssion Termination. */
		f_S6b_ST_success();

		GTP2.send(ts_GTP2C_DeleteSessionResp(g_pars.teic_remote,
						     rx_msg.sequenceNumber,
						     Request_accepted));
		setverdict(pass);
	}
	[] GTP2.receive(PDU_GTPCv2:?) -> value rx_msg {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GTP2C msg rx: ", rx_msg));
	}
}

/* Expect DeleteBearerResponse */
private altstep as_GTP2C_DeleteBearer_success() runs on EPDG_ConnHdlr {
	var PDU_GTPCv2 rx_msg;
	var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie;
	var template (value) PDN_AddressAllocation paa;

	[] GTP2.receive(tr_GTP2C_DeleteBearerResp(g_pars.teic_local)) -> value rx_msg {
		setverdict(pass);
	}
	[] GTP2.receive(PDU_GTPCv2:?) -> value rx_msg {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GTP2C msg rx: ", rx_msg));
	}
}
private function f_GTP2C_DeleteBearer_success() runs on EPDG_ConnHdlr {
	var integer proc_trans_id := 3;
	GTP2.send(ts_GTP2C_DeleteBearerReq(g_pars.teic_remote, proc_trans_id, g_pars.bearer.ebi, Access_changed_from_Non_3GPP_to_3GPP));
	as_GTP2C_DeleteBearer_success();
}

/* GSUP AuthInfo Req + Resp, triggers SWx MAR + MAA. */
private function f_GSUP_AI_success() runs on EPDG_ConnHdlr {
	var GSUP_PDU rx_gsup;
	var template (present) GSUP_IE auth_tuple_ie := tr_GSUP_IE_AuthTuple3G(g_pars.vec.rand,
									       g_pars.vec.ik,
									       g_pars.vec.ck,
									       g_pars.vec.autn,
									       g_pars.vec.rand  & g_pars.vec.auts);

	GSUP.send(ts_GSUP_SAI_REQ(g_pars.imsi));
	as_DIA_SWx_MA_success();
	/* Expect a positive response back to the translator; expect AIA */
	alt {
	[] GSUP.receive(tr_GSUP_SAI_RES(g_pars.imsi, auth_tuple_ie));
	[] GSUP.receive(GSUP_PDU:?) -> value rx_gsup {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup));
		}
	}
	setverdict(pass);
}

/* GSUP LU Req + Resp, triggers SWx SAR + SAA (Server Assignment). */
private function f_GSUP_LU_success() runs on EPDG_ConnHdlr {
	var GSUP_PDU rx_gsup;
	var template octetstring destination_name := *;
	GSUP.send(ts_GSUP_UL_REQ(g_pars.imsi));
	as_DIA_SWx_SA_success(REGISTRATION);
	/* Expect a positive response back to the translator */
	alt {
	[] GSUP.receive(tr_GSUP_UL_RES(g_pars.imsi, destination_name));
	[] GSUP.receive(GSUP_PDU:?) -> value rx_gsup {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup));
		}
	}
	setverdict(pass);
}

/* GSUP TunnelEPDG Tunnel Req + Resp, triggers S2b CreateSession Req + Response. */
private function f_GSUP_EPDGTunnel_success() runs on EPDG_ConnHdlr {
	var GSUP_PDU rx_gsup;
	GSUP.send(ts_GSUP_EPDGTunnel_REQ(g_pars.imsi));
	as_GTP2C_CreateSession_success();
	/* Expect a positive response back to the translator; */
	var template (present) GSUP_IEs pdp_info := {
			tr_GSUP_IE_PDP_CONTEXT_ID(?),
			tr_GSUP_IE_PDP_ADDRESS(?),
			tr_GSUP_IE_APN(?),
			tr_GSUP_IE_PDP_QOS(?),
			tr_GSUP_IE_Charging_Characteristics(?)
			};
	alt {
	[] GSUP.receive(tr_GSUP_EPDGTunnel_RES(g_pars.imsi, pdp_info));
	[] GSUP.receive(GSUP_PDU:?) -> value rx_gsup {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup));
		}
	}
	setverdict(pass);
}

/* GSUP Purge MS Req + Resp, triggers S2b DeleteSession Req + Response. */
private function f_GSUP_PurgeMS_success() runs on EPDG_ConnHdlr {
	var GSUP_PDU rx_gsup;
	GSUP.send(ts_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
	as_GTP2C_DeleteSession_success();
	/* ePDG internally sends STR to its AAA-Server. Since all sessions
	become inactive, AAA-Server sends SAR(USER_DEREGISTRATION) to HSS: */

	/* Expect a positive response back to the translator; */
	as_DIA_SWx_SA_success(USER_DEREGISTRATION);
	alt {
	[] GSUP.receive(tr_GSUP_PURGE_MS_RES(g_pars.imsi));
	[] GSUP.receive(GSUP_PDU:?) -> value rx_gsup {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup));
		}
	}
	setverdict(pass);
}

private function f_TC_authinfo_normal(charstring id) runs on EPDG_ConnHdlr {
	f_GSUP_AI_success();
	f_GSUP_LU_success();
	f_GSUP_EPDGTunnel_success();
	f_GSUP_PurgeMS_success();
}

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

private function f_TC_ho_wifi_to_lte(charstring id) runs on EPDG_ConnHdlr {
	f_TC_authinfo_normal(id);
	/* Whenever UE goes back to 3GPP, PGW will notify ePDG with a Delete Bearer Request
	 * cause="Access changed from non-3gpp to 3gpp" */
	f_GTP2C_DeleteBearer_success();
}

testcase TC_ho_wifi_to_lte() runs on MTC_CT {
	var EPDG_ConnHdlrPars pars := f_init_pars();
	var EPDG_ConnHdlr vc_conn;
	f_init();
	vc_conn := f_start_handler(refers(f_TC_ho_wifi_to_lte), pars);
	vc_conn.done;
	setverdict(pass);
}

control {
	execute ( TC_authinfo_normal() );
	execute ( TC_ho_wifi_to_lte() );
}

}
