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 CreateBearerResponse */
private altstep as_GTP2C_CreateBearer_success() runs on EPDG_ConnHdlr {
	var PDU_GTPCv2 rx_msg;

	[] GTP2.receive(tr_GTP2C_CreateBearerResp(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_CreateBearer_success(uint4_t dedicated_bearer_id := 6) runs on EPDG_ConnHdlr {

	var template (value) FullyQualifiedTEID fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S2bU_ePDG_GTPU, g_pars.bearer.teid_local, dedicated_bearer_id,
							    f_inet_addr(mp_s2b_local_ip), omit);
	var template (value) FullyQualifiedTEID_List teid_list := { fteid_u_ie };

	var template (value) FullyQualifiedPDN_ConnectionSetID pgw_fq_csid := ts_GTP2C_FQCSID_IPv4(f_inet_addr(mp_s2b_local_ip), int2oct(dedicated_bearer_id, 2));
	var template (value) FullyQualifiedPDN_ConnectionSetID_List csid_list := { pgw_fq_csid };

	var template (value) BearerContextGrouped_List bcg_list := {
			ts_GTP2C_BcGrouped({
				ePS_Bearer_ID := ts_GTP2C_EpsBearerId(dedicated_bearer_id),
				cause := omit,
				ePS_Bearer_TFT := omit,
				fullyQualifiedTEID := teid_list,
				bearerLevel_QoS := ts_GTP2C_BearerQos('09'O, 0,0,0,0),
				chargingID := ts_GTP2C_ChargingID(f_rnd_octstring(4)),
				bearerFlags := omit,
				transactionIdentifier := omit,
				protocolConfigOptions := omit,
				rAN_NASCause := omit,
				additionalProtocolConfigOptions := omit,
				extendedProtocolConfigOptions := omit
				})
	};
	GTP2.send(ts_GTP2C_CreateBearerReq(g_pars.teic_remote, omit, g_pars.bearer.ebi,
					   dedicated_bearer_id, bcg_list, csid_list));
	as_GTP2C_CreateBearer_success();
}

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

/* Expect CancelLocationReq */
private altstep as_GSUP_CancelLocation_success() runs on EPDG_ConnHdlr {
	var GSUP_PDU rx_gsup;

	[] GSUP.receive(tr_GSUP_CL_REQ(g_pars.imsi)) -> value rx_gsup {
		GSUP.send(ts_GSUP_CL_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));
	}
}

private function f_initial_attach() runs on EPDG_ConnHdlr {
	f_GSUP_AI_success();
	f_GSUP_LU_success();
	f_GSUP_EPDGTunnel_success();
}

private function f_TC_authinfo_normal(charstring id) runs on EPDG_ConnHdlr {
	f_initial_attach();
	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_lte_to_wifi(charstring id) runs on EPDG_ConnHdlr {
	f_initial_attach();
	/* Whenever UE comes from 3GPP, PGW may activate a dedicated S2b bearer
	 * and notify ePDG with a Create Bearer Request */
	f_GTP2C_CreateBearer_success();
	f_GSUP_PurgeMS_success();
}

testcase TC_ho_lte_to_wifi() 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_lte_to_wifi), pars);
	vc_conn.done;
	setverdict(pass);
}

private function f_TC_ho_wifi_to_lte(charstring id) runs on EPDG_ConnHdlr {
	f_initial_attach();
	/* 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_lte_to_wifi() );
	execute ( TC_ho_wifi_to_lte() );
}

}
