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

	TEID0.send(ts_GTP2C_EchoReq(0));
	T.start;
	alt {
	[] TEID0.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() );
}


}
