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

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

/* 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);
	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_Used_Service_Unit,
						tr_AVP_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_MultipleServicesIndicator,
					tr_AVP_Multiple_Services_Credit_Control(content := superset(
						tr_AVP_Requested_Service_Unit,
						tr_AVP_Used_Service_Unit,
						tr_AVP_3GPP_Reporting_Reason,
						tr_AVP_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_MultipleServicesIndicator,
					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_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:='10'O)) -> 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
				setverdict(fail, "We don't expect removed bearer contexts yet");
				}
			}
		}
		}
	[] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_teic, cause:=?)) -> value rx {
		setverdict(fail, "Unexpected  CreateSessionResp(cause=",
				rx.gtpcv2_pdu.createSessionResponse.cause.causeValue, ")");
		}
	[] GTP2.receive {
		setverdict(fail, "Unexpected GTPv2 while waiting for CreateSessionResp");
		}
	}

}

/* delete the session from the PGW */
private function f_delete_session(template (omit) OCT1 tx_cause := omit,
				  template (present) OCT4 exp_teid,
				  template (present) OCT1 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(?, ?)) {
		setverdict(fail, "Unexpected  DeleteSessionResp");
		}
	[] GTP2.receive {
		setverdict(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
	};

	/* Redirect stdout/stderr to the user-specified location */
	if (redirect_output) {
		var charstring prefix := mp_run_prog_log_path & "/" & testcasename();
		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) {
		setverdict(fail, "Unable to start program '", command, "'");
	}
	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 {
		setverdict(fail, "Received unexpected ProgramTermInd := ", pti);
		}
	[] T.timeout {
		setverdict(fail, "timeout waiting for user-plane program 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);
	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();

	TEID0.send(ts_GTP2C_EchoReq(0));
	T.start;
	alt {
	[] TEID0.receive(tr_GTP2C_EchoResp) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(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, '10'O);
	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, '40'O /* Context Unknown */, 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, '10'O);
	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() );
}


}
