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(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_Used_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:='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
				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) 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(?, ?)) {
		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, '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() );
}


}
