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_212_Templates all;
import from DIAMETER_ts29_272_Templates all;
import from DIAMETER_ts29_273_Templates all;
import from DIAMETER_ts32_299_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_aaa_local_ip := "127.0.0.9";
	integer mp_aaa_local_port := 3870;

	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;
	/* emulated AAA-Server */
	var DIAMETER_Emulation_CT vc_S6b;
	port DIAMETER_PT S6b_UNIT;
	port DIAMETEREM_PROC_PT S6b_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;
	port DIAMETER_Conn_PT S6b;

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

type record BearerConfig {
	 /* EPS Bearer ID */
	uint4_t		ebi optional,
	/* TEI (Data) local side */
	OCT4 		teid_local optional,
	/* TEI (Data) remote side */
	OCT4 		teid_remote optional
};

/* configuration data for a given Session */
type record SessionPars {
	hexstring	imsi,
	hexstring	msisdn optional,
	// serving network
	GTP2C_RAT_Type	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,

	/* TEI (Control) local side */
	OCT4 		teic_local,
	/* TEI (Control) remote side */
	OCT4 		teic_remote optional,
	/* Bearer Contexts to be created */
	BearerConfig 	bearer optional,

	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,
	     template (omit) hexstring msisdn := '1234'H,
	     GTP2C_RAT_Type rat_type := GTP2C_RAT_EUTRAN,
	     charstring apn := "internet",
	     boolean selection_mode := false,
	     BIT3 pdn_type := '001'B) := {
	imsi := imsi,
	msisdn := msisdn,
	rat_type := rat_type,
	apn := apn,
	selection_mode := selection_mode,
	pdn_type := pdn_type,
	pco := omit,
	epco := omit,
	teic_local := '00000000'O,
	teic_remote := omit,
	bearer := {
		ebi := 5,
		teid_local := omit,
		teid_remote := omit
	},
	tun_dev_name := tundev,
	tun_netns_name := tundev,
	gy_validity_time := 0
}


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

	/* S6b setup: */
	pars := {
		remote_ip := mp_pgw_hostname,
		remote_sctp_port := -1,
		local_ip := mp_aaa_local_ip,
		local_sctp_port := mp_aaa_local_port,
		origin_host := "aaa." & mp_diam_realm,
		origin_realm := mp_diam_realm,
		auth_app_id := c_DIAMETER_3GPP_S6b_AID,
		vendor_app_id := c_DIAMETER_3GPP_S6b_AID
	};
	vc_S6b := DIAMETER_Emulation_CT.create(id);
	map(vc_S6b:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_S6b:DIAMETER_UNIT, self:S6b_UNIT);
	connect(vc_S6b:DIAMETER_PROC, self:S6b_PROC);
	vc_S6b.start(DIAMETER_Emulation.main(ops, pars, id));

	f_diameter_wait_capability(Gx_UNIT);
	f_diameter_wait_capability(Gy_UNIT);
	f_diameter_wait_capability(S6b_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,
		gtpu_bind_ip := omit,  /* using gtpu daemon */
		gtpu_bind_port := omit,  /* using gtpu daemon */
		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, vc_conn_s6b;
	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));
	}

	if (isbound(vc_S6b)) {
		vc_conn_s6b := DIAMETER_ConnHdlr_CT.create(id);
		connect(vc_conn_s6b:DIAMETER, vc_S6b:DIAMETER_CLIENT);
		connect(vc_conn_s6b:DIAMETER_PROC, vc_S6b:DIAMETER_PROC);
		connect(vc_conn:S6b, vc_conn_s6b:DIAMETER_CLIENT);
		vc_conn_s6b.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);
	/* allocate + register TEID-C on local side */
	g_pars.teic_local := f_gtp2_allocate_teid();
	g_pars.bearer.teid_local := g_pars.teic_local;
	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);
}

/* S6b emulation (AAA-Server) */
private altstep as_DIA_S6b_AAR() runs on PGW_Session_CT {
	var PDU_DIAMETER rx_dia;
	[] S6b.receive(tr_DIA_S6b_AAR()) -> value rx_dia {
		var template (omit) AVP avp;
		var octetstring sess_id;

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

		S6b.send(ts_DIA_S6b_AAA(sess_id, "aaa." & mp_diam_realm,
					mp_diam_realm, mp_diam_realm,
					rx_dia.hop_by_hop_id, rx_dia.end_to_end_id));
		setverdict(pass);
	}
	[] S6b.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received unexpected DIAMETER ", rx_dia));
	}
}

/* Gx emulation (PCRF)*/
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));
	}
}

/* Gy emulation (OCS) */
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(enum2int(g_pars.rat_type), 1);
	charging_char := char2oct(oct2str('0000'O));  // f_s5s8_create_session() uses hardcoded chg_car := '0000'O
	nsapi := int2oct(g_pars.bearer.ebi, 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));
	}
}

/* GTPv2C */
private function is_s2b_iface() runs on PGW_Session_CT return boolean {
	return (g_pars.rat_type == GTP2C_RAT_WLAN or g_pars.rat_type == GTP2C_RAT_Virtual);
}

/* 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
{
	g_pars.bearer.ebi := bctx.bearerContextIEs.ePS_Bearer_ID.ePS_Bearer_ID_Value;
	/* FIXME: Cause */

	var integer exp_fteid_if_type;
	var BIT4 exp_fteid_instance;
	if (is_s2b_iface()) {
		exp_fteid_if_type := 33;
		exp_fteid_instance := '0100'B;
	} else {
		exp_fteid_if_type := 5;
		exp_fteid_instance := '0010'B;
	}

	/* find F-TEID of the P-GW U side */
	var FullyQualifiedTEID rx_fteid;
	rx_fteid := valueof(f_find_teid(bctx.bearerContextIEs.fullyQualifiedTEID,
					exp_fteid_if_type, exp_fteid_instance));
	g_pars.bearer.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_pars.bearer.teid_remote),
		rx_teid := oct2int(g_pars.bearer.teid_local),
		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(template (value) FullyQualifiedTEID fteid_c_ie,
				  template (value) FullyQualifiedTEID fteid_u_ie,
				  template (omit) UserLocationInfo uli_ie := omit,
				  template (omit) APCO apco := omit,
				  template APCO exp_apco := *) runs on PGW_Session_CT {
	var PDU_GTPCv2 rx;

	/* Defaults used for s5/s8: */
	var boolean do_s6b := false;
	var template APN_Restriction apn_restriction := ?;
	/* Change behavior when on S2b: */
	if (is_s2b_iface()) {
		do_s6b := true;
		apn_restriction := omit;
	}

	var template (value) PDU_GTPCv2 g2c :=
		ts_GTP2C_CreateSessionReq(imsi := g_pars.imsi,
					  msisdn := g_pars.msisdn,
					  rat_type := enum2int(g_pars.rat_type),
					  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 := g_pars.bearer.ebi,
					  uli := uli_ie,
					  apco := apco);
	g2c.gtpcv2_pdu.createSessionRequest.servingNetwork := ts_GTP2C_ServingNetwork('001'H, '01F'H);

	GTP2.send(g2c);
	if (do_s6b and S6b.checkstate("Connected")) {
		as_DIA_S6b_AAR();
	}
	if (Gx.checkstate("Connected")) {
		as_DIA_Gx_CCR(INITIAL_REQUEST);
	}
	/* FIXME: When on S2b interface, SMF is not using the Gy interface, unknown reason. */
	if (Gy.checkstate("Connected")) {
		as_DIA_Gy_CCR(INITIAL_REQUEST);
	}
	alt {
	[] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid := g_pars.teic_local,
						   cause := Request_accepted,
						   apn_restriction := apn_restriction,
						   exp_apco := exp_apco)) -> value rx {
		/* extract TEIDs */
		var CreateSessionResponse resp := rx.gtpcv2_pdu.createSessionResponse;
		g_pars.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_pars.teic_local, 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");
		}
	}

}

/* create a session on the PGW on a S5/S8 interface (from SGW )*/
private function f_s5s8_create_session() runs on PGW_Session_CT {
	var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie;
	var template (value) UserLocationInfo uli_ie;

	fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0,
					f_inet_addr(mp_local_hostname_c), omit);
	fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPU, g_pars.bearer.teid_local, 2,
					f_inet_addr(mp_local_hostname_u), omit);


	/* 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 };
	uli_ie := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi);

	f_create_session(fteid_c_ie, fteid_u_ie, uli_ie);

}

/* create a session on the PGW on a S2b interface (from ePDG)*/
private function f_s2b_create_session(template (omit) APCO apco := omit,
				      template APCO exp_apco := *) runs on PGW_Session_CT {
	var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie;
	var template (value) UserLocationInfo uli_ie;

	fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S2b_ePDG_GTPC, g_pars.teic_local, 0,
					f_inet_addr(mp_local_hostname_c), omit);
	fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S2bU_ePDG_GTPU, g_pars.bearer.teid_local, 5,
					f_inet_addr(mp_local_hostname_u), omit);

	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 };
	uli_ie := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi);

	f_create_session(fteid_c_ie, fteid_u_ie, uli_ie := uli_ie, apco := apco, exp_apco := exp_apco);

}

/* 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_pars.teic_local, 0,
					f_inet_addr(mp_local_hostname_c), omit);
	var template PDU_GTPCv2 g2c :=
		ts_GTP2C_DeleteSessionReq(d_teid := g_pars.teic_remote, cause := tx_cause,
					  sender_fteid := fteid_c_ie,
					  teid_list := {}, bearer_id := g_pars.bearer.ebi);

	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_pars.bearer.teid_local)) {
		var UECUPS_DestroyTun uecups_destroy := {
			local_gtp_ep := valueof(ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u))),
			rx_teid := oct2int(g_pars.bearer.teid_local)
		};
		/* 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_s5s8_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_s5s8_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_s5s8_create_session();
	f_delete_session(omit, g_pars.teic_local, 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_pars.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_s5s8_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_pars.teic_local, 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;
}

/* create a session, expect it to succeed */
private function f_TC_s2b_createSession_v4_noapco() runs on PGW_Session_CT {
	var template (omit) APCO apco := omit;
	var template APCO exp_apco := omit;
	f_s2b_create_session(apco, exp_apco);
	setverdict(pass);
}
testcase TC_s2b_createSession_v4_noapco() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H,
						      "tun22",
						      rat_type := GTP2C_RAT_WLAN));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_s2b_createSession_v4_noapco), pars);
	vc_conn.done;
}

private function f_TC_s2b_createSession_v4_apco() runs on PGW_Session_CT {
	var template (omit) APCO apco := ts_GTP2C_APCO('0000'B,
						{ts_GTP2C_PCO_P_DNS_IPv4(''O),
						 ts_GTP2C_PCO_P_PCSCF_IPv4(''O)});
	var template APCO exp_apco := tr_GTP2C_APCO('0000'B,
						{tr_GTP2C_PCO_P_DNS_IPv4(?),
						 *, /* open5gs-smfd can contain several DNS servers */
						 tr_GTP2C_PCO_P_PCSCF_IPv4(?)});
	f_s2b_create_session(apco, exp_apco);
	setverdict(pass);
}
testcase TC_s2b_createSession_v4_apco() runs on PGW_Test_CT {
	var PGW_Session_CT vc_conn;
	var SessionPars pars := valueof(t_SessionPars('001010123456789'H,
						      "tun22",
						      rat_type := GTP2C_RAT_WLAN));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_s2b_createSession_v4_apco), 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() );
	execute( TC_s2b_createSession_v4_noapco() );
	execute( TC_s2b_createSession_v4_apco() );
}


}
