module PGW_Tests {

import from TCCEncoding_Functions all;

import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from Misc_Helpers all;

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

import from UECUPS_Types all;

import from DNS_Helpers all;


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


modulepar {
	charstring mp_pgw_hostname := "127.0.0.4";
	charstring mp_local_hostname_c := "127.0.0.1";
	charstring mp_local_hostname_u := "127.0.0.1";

	charstring mp_run_prog_log_path := "/tmp";
	charstring mp_run_prog_as_user := "laforge";
	charstring mp_ping_hostname := "10.45.0.1";

	charstring mp_pcrf_local_ip := "127.0.0.9";
	integer mp_pcrf_local_port := 3868;

	charstring mp_ocs_local_ip := "127.0.0.9";
	integer mp_ocs_local_port := 3869;

	charstring mp_diam_realm := "localdomain";
}

/* main component, we typically have one per testcase */
type component PGW_Test_CT extends GTP2_ConnHdlr {
	var GTPv2_Emulation_CT vc_GTP2;
	port GTP2EM_PT TEID0;

	/* emulated PCRF */
	var DIAMETER_Emulation_CT vc_Gx;
	port DIAMETER_PT Gx_UNIT;
	port DIAMETEREM_PROC_PT Gx_PROC;
	/* emulated OCS */
	var DIAMETER_Emulation_CT vc_Gy;
	port DIAMETER_PT Gy_UNIT;
	port DIAMETEREM_PROC_PT Gy_PROC;
	/* global test case guard timer (actual timeout value is set in f_init()) */
	timer T_guard;
}

/* global altstep for global guard timer; */
altstep as_Tguard() runs on PGW_Test_CT {
	[] T_guard.timeout {
			setverdict(fail, "Timeout of T_guard");
			mtc.stop;
		}
}

type component DIAMETER_ConnHdlr_CT extends DIAMETER_ConnHdlr {
	port DIAMETER_Conn_PT DIAMETER_CLIENT;
}

function f_diam_connhldr_ct_main(hexstring imsi) runs on DIAMETER_ConnHdlr_CT {
	var PDU_DIAMETER msg;

	if (DIAMETER_PROC.checkstate("Connected")) {
		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);
			}
		}
	}
}


/* per-session component; we typically have 1..N per testcase */
type component PGW_Session_CT extends GTP2_ConnHdlr {
	var SessionPars	g_pars;

	port DIAMETER_Conn_PT Gx;
	port DIAMETER_Conn_PT Gy;

	/* TEI (Data) local side */
	var OCT4	g_teid;
	/* TEI (Control) local side */
	var OCT4	g_teic;
	/* TEI (Data) remote side */
	var OCT4	g_teid_remote;
	/* TEI (Control) remote side */
	var OCT4	g_teic_remote;
	/* GTP-U IPv4 address remote sie */
	var OCT4	g_gtpu4_remote;
	var OCT16	g_gtpu6_remote;

	/* Address allocation */
	var OCT4	g_ip4_addr;
	var OCT16	g_ip6_addr;
	var integer	g_ip6_plen;

	/* Store last received Gy message */
	var PDU_DIAMETER g_rx_gy;

	/* number of programs started, used as identifier. */
	var integer 	g_start_prog_count := 0;
}

/* configuration data for a given Session */
type record SessionPars {
	hexstring	imsi,
	hexstring	msisdn optional,
	// serving network
	integer		rat_type,
	// flags?
	charstring	apn,
	/* Apn subscribed or non-subscribed */
	boolean		selection_mode,
	BIT3		pdn_type,
	/* PAA */
	/* Max APN Restriction */
	/* APN-AMBR */
	octetstring	pco optional,
	octetstring	epco optional,
	/* Bearer Contexts to be created */

	charstring	tun_dev_name,
	charstring	tun_netns_name optional,

	/* In seconds. 0 => disabled, !0 => grant over CC-Time period */
	integer gy_validity_time
}

template (value) SessionPars
t_SessionPars(hexstring imsi, charstring tundev, integer rat_type := 6, charstring apn := "internet",
	      boolean selection_mode := false, BIT3 pdn_type := '001'B) := {
	imsi := imsi,
	msisdn := '1234'H,
	rat_type := rat_type,
	apn := apn,
	selection_mode := selection_mode,
	pdn_type := pdn_type,
	pco := omit,
	epco := omit,
	tun_dev_name := tundev,
	tun_netns_name := tundev,
	gy_validity_time := 0
}

type record BearerConfig {
	integer		eps_bearer_id
}

type function void_fn() runs on PGW_Session_CT;

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

friend function f_init_diameter(charstring id) runs on PGW_Test_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;

	/* Gx setup: */
	pars := {
		remote_ip := mp_pgw_hostname,
		remote_sctp_port := -1,
		local_ip := mp_pcrf_local_ip,
		local_sctp_port := mp_pcrf_local_port,
		origin_host := "pcrf." & mp_diam_realm,
		origin_realm := mp_diam_realm,
		auth_app_id := omit,
		vendor_app_id := c_DIAMETER_3GPP_Gx_AID
	};
	vc_Gx := DIAMETER_Emulation_CT.create(id);
	map(vc_Gx:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_Gx:DIAMETER_UNIT, self:Gx_UNIT);
	connect(vc_Gx:DIAMETER_PROC, self:Gx_PROC);
	vc_Gx.start(DIAMETER_Emulation.main(ops, pars, id));

	/* Gy setup: */
	pars := {
		remote_ip := mp_pgw_hostname,
		remote_sctp_port := -1,
		local_ip := mp_ocs_local_ip,
		local_sctp_port := mp_ocs_local_port,
		origin_host := "ocs." & mp_diam_realm,
		origin_realm := mp_diam_realm,
		auth_app_id := c_DIAMETER_CREDIT_CONTROL_AID,
		vendor_app_id := omit
	};
	vc_Gy := DIAMETER_Emulation_CT.create(id);
	map(vc_Gy:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_Gy:DIAMETER_UNIT, self:Gy_UNIT);
	connect(vc_Gy:DIAMETER_PROC, self:Gy_PROC);
	vc_Gy.start(DIAMETER_Emulation.main(ops, pars, id));

	f_diameter_wait_capability(Gx_UNIT);
	f_diameter_wait_capability(Gy_UNIT);
	/* Give some time for our emulation to get out of SUSPECT list of SUT (3 watchdong 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(1.0);
}

private function f_init(float guard_timeout := 60.0) runs on PGW_Test_CT {
	T_guard.start(guard_timeout);
	activate(as_Tguard());

	var Gtp2EmulationCfg cfg := {
		gtpc_bind_ip := mp_local_hostname_c,
		gtpc_bind_port := GTP2C_PORT,
		gtpc_remote_ip := mp_pgw_hostname,
		gtpc_remote_port := GTP2C_PORT,
		sgw_role := true,
		use_gtpu_daemon := true
	};

	vc_GTP2 := GTPv2_Emulation_CT.create("GTP2_EM");
	map(vc_GTP2:GTP2C, system:GTP2C);
	connect(vc_GTP2:TEID0, self:TEID0);
	connect(vc_GTP2:CLIENT, self:GTP2);
	connect(vc_GTP2:CLIENT_PROC, self:GTP2_PROC);
	vc_GTP2.start(GTPv2_Emulation.main(cfg));

	if (mp_pcrf_local_ip != "") {
		f_init_diameter(testcasename());
	}
}

function f_start_handler(void_fn fn, template (omit) SessionPars pars_tmpl := omit)
runs on PGW_Test_CT return PGW_Session_CT {
	var charstring id := testcasename();
	var DIAMETER_ConnHdlr_CT vc_conn_gx, vc_conn_gy;
	var PGW_Session_CT vc_conn;
	var SessionPars pars;

	if (isvalue(pars_tmpl)) {
		pars := valueof(pars_tmpl);
	} else {
		/*TODO: set default values */
	}

	vc_conn := PGW_Session_CT.create(id);
	connect(vc_conn:GTP2, vc_GTP2:CLIENT);
	connect(vc_conn:GTP2_PROC, vc_GTP2:CLIENT_PROC);

	if (isbound(vc_Gx)) {
		vc_conn_gx := DIAMETER_ConnHdlr_CT.create(id);
		connect(vc_conn_gx:DIAMETER, vc_Gx:DIAMETER_CLIENT);
		connect(vc_conn_gx:DIAMETER_PROC, vc_Gx:DIAMETER_PROC);
		connect(vc_conn:Gx, vc_conn_gx:DIAMETER_CLIENT);
		vc_conn_gx.start(f_diam_connhldr_ct_main(pars.imsi));
	}

	if (isbound(vc_Gy)) {
		vc_conn_gy := DIAMETER_ConnHdlr_CT.create(id);
		connect(vc_conn_gy:DIAMETER, vc_Gy:DIAMETER_CLIENT);
		connect(vc_conn_gy:DIAMETER_PROC, vc_Gy:DIAMETER_PROC);
		connect(vc_conn:Gy, vc_conn_gy:DIAMETER_CLIENT);
		vc_conn_gy.start(f_diam_connhldr_ct_main(pars.imsi));
	}

	vc_conn.start(f_handler_init(fn, pars));
	return vc_conn;
}

private function f_handler_init(void_fn fn, SessionPars pars)
runs on PGW_Session_CT {
	g_pars := valueof(pars);
	fn.apply();
}

private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
	var integer suffix_len := tot_len - lengthof(prefix);
	var charstring suffix_ch := int2str(suffix);
	var integer pad_len := suffix_len - lengthof(suffix_ch);

	return prefix & int2hex(0, pad_len) & str2hex(suffix_ch);
}

function f_gen_imei(integer suffix) return hexstring {
	return f_concat_pad(14, '49999'H, suffix);
}

function f_gen_imsi(integer suffix) return hexstring {
	return f_concat_pad(15, '26242'H, suffix);
}

private altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on PGW_Session_CT {
	var PDU_DIAMETER rx_dia;
	[] Gx.receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia {
		var template (omit) AVP avp;
		var octetstring sess_id;
		var AVP_Unsigned32 req_num;

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

		avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_DCC_NONE_CC_Request_Number);
		req_num := valueof(avp.avp_data.avp_DCC_NONE_CC_Request_Number);

		Gx.send(ts_DIA_Gx_CCA(rx_dia.hop_by_hop_id, rx_dia.end_to_end_id, sess_id,
					 req_type, req_num));
	}
	[] Gx.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received unexpected DIAMETER ", rx_dia));
	}
}

function f_tr_DIA_Gy_CCR(DCC_NONE_CC_Request_Type req_type)
runs on PGW_Session_CT return template (present) PDU_DIAMETER
{
	var template (present) PDU_DIAMETER tpl;
	var charstring smf_origin_host := "smf." & mp_diam_realm;
	var template (present) octetstring imsi := ?;
	var template (present) octetstring msisdn := ?;
	var template (present) octetstring rat_type := ?;
	var template (present) OCT4 charging_char := ?;
	var template (present) OCT1 nsapi := ?;
	imsi := char2oct(f_dec_TBCD(imsi_hex2oct(g_pars.imsi)));
	//msisdn := char2oct(f_dec_TBCD(substr(ctx_val.msisdn, 1, lengthof(ctx_val.msisdn) -1)));
	rat_type := int2oct(g_pars.rat_type, 1);
	charging_char := char2oct(oct2str('0000'O));  // f_create_session() uses hardcoded chg_car := '0000'O
	nsapi := '01'O; // f_create_session() uses hardcoded bearer_id := 1
	select (req_type) {
		case (INITIAL_REQUEST) {
			tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
				avps := superset(
					tr_AVP_SessionId,
					tr_AVP_OriginHost(smf_origin_host),
					tr_AVP_OriginRealm(mp_diam_realm),
					tr_AVP_DestinationRealm(mp_diam_realm),
					tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
					tr_AVP_ServiceContextId,
					tr_AVP_CcReqType(req_type),
					tr_AVP_CcReqNum(?),
					tr_AVP_EventTimestamp(?),
					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
					tr_AVP_RequestedAction(DIRECT_DEBITING),
					tr_AVP_3GPP_AoCRequestType,
					tr_AVP_MultipleServicesIndicator,
					tr_AVP_Multiple_Services_Credit_Control(content := superset(
						tr_AVP_Requested_Service_Unit,
						tr_AVP_PCC_3GPP_QoS_Information,
						tr_AVP_GI_3GPP_RatType(rat_type)
					)),
					tr_AVP_3GPP_ServiceInformation(content := superset(
						tr_AVP_3GPP_PSInformation(content := superset(
							tr_AVP_3GPP_ChargingId,
							tr_AVP_3GPP_PDPType((IPv4,IPv6,IPv4v6)),
							tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
							tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pcrf_local_ip))),
							tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pgw_hostname))),
							tr_AVP_3GPP_CalledStationId,
							tr_AVP_3GPP_SelectionMode,
							tr_AVP_3GPP_ChargingCharacteristics(charging_char),
							tr_AVP_3GPP_SGSNMCCMNC,
							tr_AVP_3GPP_NSAPI(nsapi),
							/*We don't yet send MS_Tz in CreateSessionReq:
							tr_AVP_3GPP_MS_TimeZone,*/
							tr_AVP_3GPP_ULI/*,
							We don't yet send IMEI in CreateSessionReq:
							tr_AVP_UserEquipmentInfo({
								tr_AVP_UserEquipmentInfoType(IMEISV),
								tr_AVP_UserEquipmentInfoValue(imeisv)
							})*/
						))
					))
				));
		}
		case (UPDATE_REQUEST) {
			tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
				avps := superset(
					tr_AVP_SessionId,
					tr_AVP_OriginHost(smf_origin_host),
					tr_AVP_OriginRealm(mp_diam_realm),
					tr_AVP_DestinationRealm(mp_diam_realm),
					tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
					tr_AVP_ServiceContextId,
					tr_AVP_CcReqType(req_type),
					tr_AVP_CcReqNum(?),
					tr_AVP_DestinationHost(?),
					tr_AVP_EventTimestamp(?),
					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
					tr_AVP_RequestedAction(DIRECT_DEBITING),
					tr_AVP_3GPP_AoCRequestType,
					tr_AVP_Multiple_Services_Credit_Control(content := superset(
						tr_AVP_Requested_Service_Unit,
						tr_AVP_Used_Service_Unit,
						/* tr_AVP_3GPP_Reporting_Reason, can be sometimes inside UsedServiceUnit */
						tr_AVP_PCC_3GPP_QoS_Information,
						tr_AVP_GI_3GPP_RatType(rat_type)
					)),
					tr_AVP_3GPP_ServiceInformation(content := superset(
						tr_AVP_3GPP_PSInformation(content := superset(
							tr_AVP_3GPP_ChargingId,
							/* tr_AVP_3GPP_PDPType, Only in INIT */
							tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
							tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pcrf_local_ip))),
							tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pgw_hostname))),
							tr_AVP_3GPP_CalledStationId,
							tr_AVP_3GPP_SelectionMode,
							tr_AVP_3GPP_ChargingCharacteristics(charging_char),
							tr_AVP_3GPP_SGSNMCCMNC,
							tr_AVP_3GPP_NSAPI(nsapi),
							/*We don't yet send MS_Tz in CreateSessionReq:
							tr_AVP_3GPP_MS_TimeZone,*/
							tr_AVP_3GPP_ULI/*,
							We don't yet send IMEI in CreateSessionReq:
							tr_AVP_UserEquipmentInfo({
								tr_AVP_UserEquipmentInfoType(IMEISV),
								tr_AVP_UserEquipmentInfoValue(imeisv)
							})*/
						))
					))
				));
		}
		case (TERMINATION_REQUEST) {
			tpl := tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
				avps := superset(
					tr_AVP_SessionId,
					tr_AVP_OriginHost(smf_origin_host),
					tr_AVP_OriginRealm(mp_diam_realm),
					tr_AVP_DestinationRealm(mp_diam_realm),
					tr_AVP_AuthAppId(int2oct(c_DIAMETER_CREDIT_CONTROL_AID, 4)),
					tr_AVP_ServiceContextId,
					tr_AVP_CcReqType(req_type),
					tr_AVP_CcReqNum(?),
					tr_AVP_DestinationHost(?),
					tr_AVP_EventTimestamp(?),
					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_IMSI), tr_AVP_SubcrIdData(imsi)}),
					tr_AVP_SubcrId({tr_AVP_SubcrIdType(END_USER_E164), tr_AVP_SubcrIdData(msisdn)}),
					tr_AVP_TerminationCause(?),
					tr_AVP_RequestedAction(DIRECT_DEBITING),
					tr_AVP_3GPP_AoCRequestType,
					tr_AVP_Multiple_Services_Credit_Control(content := superset(
						/* tr_AVP_Requested_Service_Unit, Only in INIT and UPDATE */
						tr_AVP_Used_Service_Unit,
						tr_AVP_3GPP_Reporting_Reason(FINAL),
						tr_AVP_PCC_3GPP_QoS_Information,
						tr_AVP_GI_3GPP_RatType(rat_type)
					)),
					tr_AVP_3GPP_ServiceInformation(content := superset(
						tr_AVP_3GPP_PSInformation(content := superset(
							tr_AVP_3GPP_ChargingId,
							/* tr_AVP_3GPP_PDPType, Only in INIT */
							tr_AVP_3GPP_PDPAddress(tr_AVP_Address((IP,IP6), ?)),
							tr_AVP_3GPP_SGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pcrf_local_ip))),
							tr_AVP_3GPP_GGSNAddress(tr_AVP_Address(IP, f_inet_addr(mp_pgw_hostname))),
							tr_AVP_3GPP_CalledStationId,
							tr_AVP_3GPP_SelectionMode,
							tr_AVP_3GPP_ChargingCharacteristics(charging_char),
							tr_AVP_3GPP_SGSNMCCMNC,
							tr_AVP_3GPP_NSAPI(nsapi),
							/*We don't yet send MS_Tz in CreateSessionReq:
							tr_AVP_3GPP_MS_TimeZone,*/
							tr_AVP_3GPP_ULI/*,
							We don't yet send IMEI in CreateSessionReq:
							tr_AVP_UserEquipmentInfo({
								tr_AVP_UserEquipmentInfoType(IMEISV),
								tr_AVP_UserEquipmentInfoValue(imeisv)
							})*/
						))
					))
				));
		}
	}
	return tpl;
}

private altstep as_DIA_Gy_CCR(DCC_NONE_CC_Request_Type req_type)
runs on PGW_Session_CT {
	[] Gy.receive(f_tr_DIA_Gy_CCR(req_type := req_type)) -> value g_rx_gy {
		var template (value) PDU_DIAMETER tx_dia;
		var template (omit) AVP avp;
		var octetstring sess_id;
		var AVP_Unsigned32 req_num;

		avp := f_DIAMETER_get_avp(g_rx_gy, c_AVP_Code_BASE_NONE_Session_Id);
		sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);

		avp := f_DIAMETER_get_avp(g_rx_gy, c_AVP_Code_DCC_NONE_CC_Request_Number);
		req_num := valueof(avp.avp_data.avp_DCC_NONE_CC_Request_Number);
		if (g_pars.gy_validity_time > 0) {
			tx_dia := ts_DIA_Gy_CCA_ValidityTime(g_rx_gy.hop_by_hop_id, g_rx_gy.end_to_end_id, sess_id,
						 req_type, req_num, g_pars.gy_validity_time);
		} else {
			tx_dia := ts_DIA_Gy_CCA(g_rx_gy.hop_by_hop_id, g_rx_gy.end_to_end_id, sess_id,
						 req_type, req_num);
		}
		Gy.send(tx_dia);
	}
	[] Gy.receive(PDU_DIAMETER:?) -> value g_rx_gy {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received unexpected DIAMETER Gy", g_rx_gy));
	}
}


/* find TEID of given interface type (and optionally instance) */
private function f_find_teid(FullyQualifiedTEID_List list,
			     template (present) integer if_type,
			     template (present) BIT4 instance := ?)
return template (omit) FullyQualifiedTEID
{
	var integer i;
	for (i := 0; i < lengthof(list); i := i+1) {
		if (match(list[i].interfaceType, if_type) and
		    match(list[i].instance, instance)) {
			return list[i];
		}
	}
	return omit;
}

/* process one to-be-created bearer context */
private function process_bctx_create(BearerContextGrouped bctx) runs on PGW_Session_CT
{
	/* FIXME: EPS Bearer ID */
	/* FIXME: Cause */

	/* find F-TEID of the P-GW U side */
	var FullyQualifiedTEID rx_fteid;
	rx_fteid := valueof(f_find_teid(bctx.bearerContextIEs.fullyQualifiedTEID, 5, '0010'B));
	g_teid_remote := rx_fteid.tEID_GRE_Key;
	if (rx_fteid.v4_Flag == '1'B) {
		g_gtpu4_remote := rx_fteid.iPv4_Address;
	}
	if (rx_fteid.v6_Flag == '1'B) {
		g_gtpu6_remote := rx_fteid.iPv6_Address;
	}

	var UECUPS_CreateTun uecups_create := {
		tx_teid := oct2int(g_teid_remote),
		rx_teid := oct2int(g_teid),
		user_addr_type := IPV4,
		user_addr := '00000000'O,
		local_gtp_ep := valueof(ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u))),
		remote_gtp_ep := valueof(ts_UECUPS_SockAddr(g_gtpu4_remote)),
		tun_dev_name := g_pars.tun_dev_name,
		tun_netns_name := g_pars.tun_netns_name
	};

	/* create tunnel in daemon */
	if (isbound(g_ip4_addr)) {
		uecups_create.user_addr := g_ip4_addr;
		f_gtp2_create_tunnel(uecups_create);
	}
	if (isbound(g_ip6_addr)) {
		uecups_create.user_addr_type := IPV6;
		uecups_create.user_addr := g_ip6_addr;
		f_gtp2_create_tunnel(uecups_create);
	}
}

/* create a session on the PGW */
private function f_create_session() runs on PGW_Session_CT {
	var PDU_GTPCv2 rx;

	/* allocate + register TEID-C on local side */
	g_teic := f_gtp2_allocate_teid();
	g_teid := g_teic;

	var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie;
	fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_teic, 0,
					f_inet_addr(mp_local_hostname_c), omit);
	fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPU, g_teid, 2,
					f_inet_addr(mp_local_hostname_u), omit);
	var template (value) PDU_GTPCv2 g2c :=
		ts_GTP2C_CreateSessionReq(imsi := g_pars.imsi, msisdn := g_pars.msisdn, rat_type := 6,
					  sender_fteid := fteid_c_ie,
					  apn := f_enc_dns_hostname(g_pars.apn),
					  pdn_type := g_pars.pdn_type, teid_list := { fteid_u_ie },
					  chg_car := '0000'O, bearer_id := 1);
	/* open5gs up to 1.2.3 won't accept it without ULI, despite not mandatory */
	var template (value) TAI tai := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0001'O };
	var template (value) ECGI ecgi := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0'H, 23 };
	g2c.gtpcv2_pdu.createSessionRequest.userLocationInfo := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi);
	g2c.gtpcv2_pdu.createSessionRequest.servingNetwork := ts_GTP2C_ServingNetwork('001'H, '01F'H);

	GTP2.send(g2c);
	if (Gx.checkstate("Connected")) {
		as_DIA_Gx_CCR(INITIAL_REQUEST);
	}
	if (Gy.checkstate("Connected")) {
		as_DIA_Gy_CCR(INITIAL_REQUEST);
	}
	alt {
	[] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_teic, cause:=Request_accepted)) -> value rx {
		/* extract TEIDs */
		var CreateSessionResponse resp := rx.gtpcv2_pdu.createSessionResponse;
		g_teic_remote := resp.fullyQualifiedTEID[0].tEID_GRE_Key;

		/* extract allocated address[es] */
		var PDN_Address_and_Prefix paa := resp.pDN_AddressAllocation.pDN_Address_and_Prefix;
		if (ischosen(paa.iPv4_Address)) {
			g_ip4_addr := paa.iPv4_Address;
		} else if (ischosen(paa.iPv6_Address)) {
			g_ip6_addr := paa.iPv6_Address.iPv6_Address;
			g_ip6_plen := paa.iPv6_Address.prefixLength;
		} else if (ischosen(paa.iPv4_IPv6)) {
			g_ip4_addr := paa.iPv4_IPv6.iPv4_Address;
			g_ip6_addr := paa.iPv4_IPv6.iPv6_Address;
			g_ip6_plen := paa.iPv4_IPv6.prefixLength;
		}
		var integer i;
		for (i := 0; i < lengthof(resp.bearerContextGrouped); i := i+1) {
			var BearerContextGrouped bctx := resp.bearerContextGrouped[i];
			select (bctx.instance) {
			case ('0000'B) { // created
				process_bctx_create(bctx);
				}
			case ('0001'B) { // removed
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
							"We don't expect removed bearer contexts yet");
				}
			}
		}
		}
	[] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_teic, cause:=?)) -> value rx {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Unexpected  CreateSessionResp(cause=",
						rx.gtpcv2_pdu.createSessionResponse.cause.causeValue, ")"));
		}
	[] GTP2.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					"Unexpected GTPv2 while waiting for CreateSessionResp");
		}
	}

}

/* delete the session from the PGW */
private function f_delete_session(template (omit) GTP2C_Cause tx_cause := omit,
				  template (present) OCT4 exp_teid,
				  template (present) GTP2C_Cause exp_cause,
				  boolean expect_diameter := true) runs on PGW_Session_CT {
	var template (value) FullyQualifiedTEID fteid_c_ie
	fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_teic, 0,
					f_inet_addr(mp_local_hostname_c), omit);
	var template PDU_GTPCv2 g2c :=
		ts_GTP2C_DeleteSessionReq(d_teid := g_teic_remote, cause := tx_cause,
					  sender_fteid := fteid_c_ie,
					  teid_list := {}, bearer_id := 1);

	GTP2.send(g2c);
	if (Gx.checkstate("Connected") and expect_diameter) {
		as_DIA_Gx_CCR(TERMINATION_REQUEST);
	}
	if (Gy.checkstate("Connected") and expect_diameter) {
		as_DIA_Gy_CCR(TERMINATION_REQUEST);
	}
	alt {
	[] GTP2.receive(tr_GTP2C_DeleteSessionResp(d_teid := exp_teid, cause := exp_cause)) {
		setverdict(pass);
		}
	[] GTP2.receive(tr_GTP2C_DeleteSessionResp(?, ?)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					"Unexpected  DeleteSessionResp");
		}
	[] GTP2.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					"Unexpected GTPv2 while waiting for DeleteSessionResp");
		}
	}

	/* destroy tunnel in daemon */
	if (isbound(g_teid)) {
		var UECUPS_DestroyTun uecups_destroy := {
			local_gtp_ep := valueof(ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u))),
			rx_teid := oct2int(g_teid)
		};
		/* FIXME: what about IPv4/IPv6 differentiation? */
		f_gtp2_destroy_tunnel(uecups_destroy);
	}
}

/* start a program on the user plane side; return its PID */
private function f_start_prog(charstring command, boolean redirect_output := true)
runs on PGW_Session_CT return integer
{
	var UECUPS_StartProgram sprog := {
		command := command,
		environment := {},
		run_as_user := mp_run_prog_as_user,
		tun_netns_name := g_pars.tun_netns_name
	};
	g_start_prog_count := g_start_prog_count + 1;

	/* Redirect stdout/stderr to the user-specified location */
	if (redirect_output) {
		var charstring id := testcasename() & "-" & hex2str(g_pars.imsi) & "-" & int2str(g_start_prog_count);
		var charstring prefix := mp_run_prog_log_path & "/" & id;
		sprog.command := sprog.command & " 1>>" & prefix & ".prog.stdout";
		sprog.command := sprog.command & " 2>>" & prefix & ".prog.stderr";
	}

	log("Starting a program: ", command);
	var UECUPS_StartProgramRes res := f_gtp2_start_program(sprog);
	if (res.result != OK) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Unable to start program '", command, "'"));
	}
	log("Started program '", command, "' with PID ", res.pid);
	return res.pid;
}

/* wait for termination of a given PID with specified exit_code */
private function f_wait_term(integer pid, template (present) integer exit_code := 0,
			     float tout := 10.0) runs on PGW_Session_CT
{
	var UECUPS_ProgramTermInd pti;
	timer T := tout;

	T.start;
	alt {
	[] GTP2.receive(UECUPS_ProgramTermInd:{pid := pid, exit_code := exit_code}) {
		setverdict(pass);
		}
	[] GTP2.receive(UECUPS_ProgramTermInd:?) -> value pti {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received unexpected ProgramTermInd := ", pti));
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("timeout (", tout, " seconds) waiting for user-plane program PID ", pid, " termination"));
		}
	}
}

/* execute a program and wait for result */
private function f_start_prog_wait(charstring command,
				   template integer exit_code := 0,
				   float tout := 10.0,
				   boolean redirect_output := true)
runs on PGW_Session_CT
{
	var integer pid := f_start_prog(command, redirect_output);
	f_wait_term(pid, exit_code, tout);
}

/* execute ping command and wait for result */
private function f_ping4(charstring host, integer interval := 1, integer count := 10) runs on PGW_Session_CT
{
	var charstring ping :="ping -c " & int2str(count) & " -i " & int2str(interval);

	if (not isbound(g_ip4_addr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "f_ping4(): g_ip4_addr is unset!");
	}
	ping := ping & " -I " & f_inet_ntoa(g_ip4_addr);
	ping := ping & " " & host;
	f_start_prog_wait(ping, tout := int2float(5 + interval*count));
}




/* send echo request; expect response */
testcase TC_tx_echo() runs on PGW_Test_CT {
	timer T := 5.0;

	f_init();

	GTP2.send(ts_GTP2C_EchoReq(0));
	T.start;
	alt {
	[] GTP2.receive(tr_GTP2C_EchoResp) {
		setverdict(pass);
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "timeout waiting for Echo Response");
		}
	}
}

/* create a session, expect it to succeed */
private function f_TC_createSession() runs on PGW_Session_CT {
	f_create_session();
	setverdict(pass);
}
testcase TC_createSession() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H, "tun22"));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_createSession), pars);
	vc_conn.done;
}

/* create a session, then execute a ping command on the user plane */
private function f_TC_createSession_ping4() runs on PGW_Session_CT {
	f_create_session();
	f_ping4(mp_ping_hostname);
	setverdict(pass);
}
testcase TC_createSession_ping4() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H, "tun23"));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_createSession_ping4), pars);
	vc_conn.done;
}
testcase TC_createSession_ping4_256() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn[256];
	var integer i;

	f_init();

	for (i := 0; i < sizeof(vc_conn); i:=i+1) {
		var charstring tundev := "ping" & int2str(i);
		var SessionPars pars := valueof(t_SessionPars(f_gen_imsi(i), tundev));
		vc_conn[i] := f_start_handler(refers(f_TC_createSession_ping4), pars);
	}

	for (i := 0; i < lengthof(vc_conn); i:=i+1) {
		vc_conn[i].done;
	}
}


/* create a session, then delete it again */
private function f_TC_createSession_deleteSession() runs on PGW_Session_CT {
	f_create_session();
	f_delete_session(omit, g_teic, Request_accepted);
	setverdict(pass);
}
testcase TC_createSession_deleteSession() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H, "tun23"));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_createSession_deleteSession), pars);
	vc_conn.done;
}

/* send a DeleteSessionReq for an unknown/invalid TEID */
private function f_TC_deleteSession_unknown() runs on PGW_Session_CT {
	g_teic := f_gtp2_allocate_teid();
	g_teic_remote := f_rnd_octstring(4);
	f_delete_session(omit, '00000000'O, Context_Not_Found, false);
	setverdict(pass);
}
testcase TC_deleteSession_unknown() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H, "tun23"));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_deleteSession_unknown), pars);
	vc_conn.done;
}

/* Test charging over Gy interface. */
private function f_TC_gy_charging_cc_time() runs on PGW_Session_CT {
	var default d;

	f_create_session();

	/* We should receive an update even if no traffic is sent: */
	as_DIA_Gy_CCR(UPDATE_REQUEST);
	f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (3..4), 0, 0);

	d := activate(as_DIA_Gy_CCR(UPDATE_REQUEST));
	f_ping4(mp_ping_hostname);
	/* Let the CCA reach the GGSN */
	f_sleep(0.5);
	deactivate(d);
	f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (3..4), (28..1000), (28..1000));

	as_DIA_Gy_CCR(UPDATE_REQUEST);
	f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (3..4), ?, ?);

	f_delete_session(omit, g_teic, Request_accepted);
	f_validate_gy_cc_report(g_rx_gy, FINAL, (0..1), 0, 0);
	setverdict(pass);
}
testcase TC_gy_charging_cc_time() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H, "tun23"));
	pars.gy_validity_time := 3; /* Grant access for 3 seconds, needs to be re-validated afterwards */
	f_init();
	vc_conn := f_start_handler(refers(f_TC_gy_charging_cc_time), pars);
	vc_conn.done;
}

control {
	execute( TC_tx_echo() );
	execute( TC_createSession() );
	execute( TC_createSession_ping4() );
	execute( TC_createSession_ping4_256() );
	execute( TC_createSession_deleteSession() );
	execute( TC_deleteSession_unknown() );
	execute( TC_gy_charging_cc_time() );
}


}
