/* MME (Mobility Management Engine) test suite in TTCN-3
 * (C) 2019 Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module MME_Tests {

import from General_Types all;
import from Native_Functions all;
import from IPL4asp_Types all;
import from S1AP_Types all;
import from S1AP_Templates all;
import from S1AP_Emulation all;
import from S1AP_PDU_Descriptions all;
import from S1AP_IEs all;
import from S1AP_PDU_Contents all;
import from S1AP_Constants all;

import from NAS_EPS_Types all;
import from NAS_Templates all;

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

import from SGsAP_Types all;
import from SGsAP_Templates all;
import from SGsAP_Emulation all;

import from GTP_Emulation all;
import from GTP_Templates all;
import from GTP_CodecPort all;
import from GTPC_Types all;

import from LTE_CryptoFunctions all;

import from L3_Templates all;
import from DNS_Helpers all;
import from Osmocom_Types all;
import from Osmocom_Gb_Types all;

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

friend module MME_Tests_SGsAP;

/* (maximum) number of emulated eNBs */
const integer NUM_ENB := 3;

/* (maximum) number of emulated UEs */
const integer NUM_UE := 3;

/* parameters of emulated ENB */
type record EnbParams {
	Global_ENB_ID global_enb_id,
	integer cell_identity,
	SupportedTAs supported_tas
}

/* parameters of emulated UE */
type record UeParams {
	hexstring imsi
}

type component MTC_CT {
	/* S1 intreface of emulated ENBs */
	var EnbParams g_enb_pars[NUM_ENB];
	var S1AP_Emulation_CT vc_S1AP[NUM_ENB];
	port S1AP_PT S1AP_UNIT[NUM_ENB];
	port S1APEM_PROC_PT S1AP_PROC[NUM_ENB];

	/* S6a/S6d interface of emulated HSS */
	var DIAMETER_Emulation_CT vc_DIAMETER;
	port DIAMETER_PT DIAMETER_UNIT;
	port DIAMETEREM_PROC_PT DIAMETER_PROC;

	/* SGs interface of emulated MSC/VLR */
	var SGsAP_Emulation_CT vc_SGsAP;
	port SGsAP_PT SGsAP_UNIT;
	port SGsAPEM_PROC_PT SGsAP_PROC;

	/* Gn interface (GTPv1C) of emulated SGSN (Rel. 7) */
	var GTP_Emulation_CT vc_GTP;

	/* S11 interface (GTPv2C) of emulated SGW-C */
	var GTPv2_Emulation_CT vc_GTP2;
	port GTP2EM_PT TEID0;

	var UeParams g_ue_pars[NUM_UE];
}

/* Encode an S1AP Global-ENB-ID into an octetstring */
private function enc_S1AP_Global_ENB_ID(Global_ENB_ID global_enb_id) return octetstring {

	/* Due to the limitations of libfftranscode, we can not define encoders (or decoders) for individual
	 * information elements (in S1AP_Types.cc). Unfortuantely Global-ENB-ID also appears in BSSGP in its
	 * encoded form. (see also: GTP-C 3GPP TS 48.018, section 11.3.70). To encode a given Global-ENB-ID
	 * we craft a full S1AP PDU and encode it. Then we can cut out the encoded Global-ENB-ID from the
	 * generated octetstring. */

	var SupportedTAs supported_tas_dummy := {{
				tAC := '0000'O,
				broadcastPLMNs := { '00f000'O },
				iE_Extensions := omit
				}};
	var octetstring encoded;
	var integer global_enb_id_len;

	if (ispresent(global_enb_id.eNB_ID.macroENB_ID)) {
		global_enb_id_len := 8;
	} else {
		/* All other ENB ID types fit into 8 byte (homeENB_ID, short_macroENB_ID, long_macroENB_ID) */
		global_enb_id_len := 9;
	}

	encoded := enc_S1AP_PDU(valueof(ts_S1AP_SetupReq(global_enb_id, supported_tas_dummy, v32)));

	return substr(encoded, 11, global_enb_id_len);
}

type component ConnHdlr extends S1AP_ConnHdlr, SGsAP_ConnHdlr, DIAMETER_ConnHdlr, GTP_ConnHdlr, GTP2_ConnHdlr {
	var ConnHdlrPars g_pars;
	timer g_Tguard := 30.0;

	var GtpPeer g_gn_iface_peer := { connId := 1, remName := mp_gn_remote_ip, remPort := mp_gn_remote_port };
}

type record ConnHdlrPars {
	/* copied over from MTC_CT on start of component */
	EnbParams enb_pars[NUM_ENB],
	/* copied over from MTC_CT on start of component */
	UeParams ue_pars,
	/* currently used MME (index into enb_pars, S1AP, ...) */
	integer mme_idx
}

modulepar {
	/* S1 interface */
	charstring mp_mme_ip := "127.0.0.1";
	integer mp_mme_s1ap_port := 36412;
	charstring mp_s1_local_ip := "127.0.0.1";
	integer mp_s1_local_port := 50000;

	/* S6 interface */
	charstring mp_s6_local_ip := "127.0.0.4";
	integer mp_s6_local_port := 3868;

	/* SGs interface */
	charstring mp_sgs_local_ip := "127.0.0.1";
	integer mp_sgs_local_port := 29118;
	charstring mp_vlr_name := "vlr.example.net";
	charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";

	/* Gn interface (GTPv1C) */
	charstring mp_gn_local_ip := "127.0.0.22";
	integer mp_gn_local_port := 2123;
	charstring mp_gn_remote_ip := "127.0.0.2";
	integer mp_gn_remote_port := 2123;

	/* S11 interface (GTPv2C, interface between MME and SGW) */
	charstring mp_s11_local_ip := "127.0.0.3";
	integer mp_s11_local_port := 2123;
	charstring mp_s11_remote_ip := "127.0.0.2";
	integer mp_s11_remote_port := 2123;
}

/* send incoming unit data messages (like reset) to global SGsAP_UNIT port */
friend function ForwardUnitdataCallback(PDU_SGsAP msg)
runs on SGsAP_Emulation_CT return template PDU_SGsAP {
	SGsAP_UNIT.send(msg);
	return omit;
}

friend function f_init_sgsap(charstring id) runs on MTC_CT {
	id := id & "-SGsAP";
	var SGsAPOps ops := {
		create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(ForwardUnitdataCallback)
	}
	var SGsAP_conn_parameters pars := {
		remote_ip := "",
		remote_sctp_port := -1,
		local_ip := mp_sgs_local_ip,
		local_sctp_port := mp_sgs_local_port
	}

	vc_SGsAP := SGsAP_Emulation_CT.create(id);
	map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
	connect(vc_SGsAP:SGsAP_PROC, self:SGsAP_PROC);
	connect(vc_SGsAP:SGsAP_UNIT, self:SGsAP_UNIT);
	vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
}

/* send incoming unit data messages (like reset) to global S1AP_UNIT port */
friend function S1apForwardUnitdataCallback(S1AP_PDU msg)
runs on S1AP_Emulation_CT return template S1AP_PDU {
	S1AP_UNIT.send(msg);
	return omit;
}

friend function f_init_one_enb(charstring id, integer num := 0) runs on MTC_CT {
	id := id & "-S1AP" & int2str(num);
	var S1APOps ops := {
		create_cb := refers(S1AP_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(S1apForwardUnitdataCallback)
	}
	var S1AP_conn_parameters pars := {
		remote_ip := mp_mme_ip,
		remote_sctp_port := mp_mme_s1ap_port,
		local_ip := mp_s1_local_ip,
		local_sctp_port := mp_s1_local_port + num,
		role := NAS_ROLE_UE
	}
	var PLMNidentity plmn_id := '00f110'O;
	var EnbParams enb_pars := {
		global_enb_id := {
			pLMNidentity := plmn_id,
			eNB_ID := {
				macroENB_ID := int2bit(num, 20)
			},
			iE_Extensions := omit
		},
		cell_identity := num,
		supported_tas := {
			{
				tAC := int2oct(12345, 2),
				broadcastPLMNs := { plmn_id },
				iE_Extensions := omit
			}
		}
	};

	g_enb_pars[num] := enb_pars;
	vc_S1AP[num] := S1AP_Emulation_CT.create(id);
	map(vc_S1AP[num]:S1AP, system:S1AP_CODEC_PT);
	connect(vc_S1AP[num]:S1AP_PROC, self:S1AP_PROC[num]);
	connect(vc_S1AP[num]:S1AP_UNIT, self:S1AP_UNIT[num]);
	vc_S1AP[num].start(S1AP_Emulation.main(ops, pars, id));
	S1AP_UNIT[num].receive(S1APEM_Event:{up_down:=S1APEM_EVENT_UP});
}
friend function f_init_one_ue(inout UeParams uep, integer imsi_suffix) {
	uep := {
		imsi := f_gen_imsi(imsi_suffix)
	}
}
friend function f_init_s1ap(charstring id, integer imsi_suffix) runs on MTC_CT {
	var integer i;
	for (i := 0; i < NUM_ENB; i := i+1) {
		f_init_one_enb(id, i);
	}
	for (i := 0; i < NUM_UE; i := i+1) {
		f_init_one_ue(g_ue_pars[i], i*1000 + imsi_suffix);
	}
}

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 MTC_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 := {
		remote_ip := mp_mme_ip,
		remote_sctp_port := -1,
		local_ip := mp_s6_local_ip,
		local_sctp_port := mp_s6_local_port,
		origin_host := "hss.localdomain",
		origin_realm := "localdomain",
		auth_app_id := omit,
		vendor_app_id := c_DIAMETER_3GPP_S6_AID
	};
	vc_DIAMETER := DIAMETER_Emulation_CT.create(id);
	map(vc_DIAMETER:DIAMETER, system:DIAMETER_CODEC_PT);
	connect(vc_DIAMETER:DIAMETER_UNIT, self:DIAMETER_UNIT);
	connect(vc_DIAMETER:DIAMETER_PROC, self:DIAMETER_PROC);
	vc_DIAMETER.start(DIAMETER_Emulation.main(ops, pars, id));

	f_diameter_wait_capability(DIAMETER_UNIT);
}

friend function f_init_gtp(charstring id) runs on MTC_CT {
	id := id & "-GTP";

	var GtpEmulationCfg gtp_cfg := {
		gtpc_bind_ip := mp_gn_local_ip,
		gtpc_bind_port := mp_gn_local_port,
		gtpu_bind_ip := omit,
		gtpu_bind_port := omit,
		sgsn_role := true
	};

	vc_GTP := GTP_Emulation_CT.create(id);
	vc_GTP.start(GTP_Emulation.main(gtp_cfg));
}

friend function f_init_gtpv2_s11(charstring id) runs on MTC_CT {
	id := id & "-GTPV2";

	var Gtp2EmulationCfg cfg := {
		gtpc_bind_ip := mp_s11_local_ip,
		gtpc_bind_port := mp_s11_local_port,
		gtpc_remote_ip := mp_s11_remote_ip,
		gtpc_remote_port := mp_s11_remote_port,
		sgw_role := true,
		use_gtpu_daemon := false
	};

	vc_GTP2 := GTPv2_Emulation_CT.create(id);
	map(vc_GTP2:GTP2C, system:GTP2C);
	connect(vc_GTP2:TEID0, self:TEID0);
	vc_GTP2.start(GTPv2_Emulation.main(cfg));
}

friend template (value) S1AP_IEs.TAI ts_enb_S1AP_TAI(EnbParams enb) := {
	pLMNidentity := enb.global_enb_id.pLMNidentity,
	tAC := enb.supported_tas[0].tAC,
	iE_Extensions := omit
}

friend template (value) EUTRAN_CGI ts_enb_S1AP_CGI(EnbParams enb) := {
	pLMNidentity := enb.global_enb_id.pLMNidentity,
	cell_ID := int2bit(enb.cell_identity, 28),
	iE_Extensions := omit
}


/* generate parameters for a connection handler */
friend function f_init_pars(integer ue_idx := 0)
runs on MTC_CT return ConnHdlrPars {
	var ConnHdlrPars pars := {
		enb_pars := g_enb_pars,
		ue_pars := g_ue_pars[ue_idx],
		mme_idx := 0
	};
	return pars;
}

type function void_fn(ConnHdlrPars pars) runs on ConnHdlr;

/* start a connection handler with given parameters */
friend function f_start_handler_with_pars(void_fn fn, ConnHdlrPars pars, integer s1ap_idx := 0)
runs on MTC_CT return ConnHdlr {
	var ConnHdlr vc_conn;
	var charstring id := testcasename() & int2str(s1ap_idx);

	vc_conn := ConnHdlr.create(id);
	/* S1AP part */
	connect(vc_conn:S1AP, vc_S1AP[s1ap_idx]:S1AP_CLIENT);
	connect(vc_conn:S1AP_PROC, vc_S1AP[s1ap_idx]:S1AP_PROC);
	if (isbound(vc_SGsAP)) {
		/* SGsAP part */
		connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
		connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
	}
	if (isbound(vc_DIAMETER)) {
		connect(vc_conn:DIAMETER, vc_DIAMETER:DIAMETER_CLIENT);
		connect(vc_conn:DIAMETER_PROC, vc_DIAMETER:DIAMETER_PROC);
	}
	if (isbound(vc_GTP)) {
		connect(vc_conn:GTP, vc_GTP:CLIENT);
		connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
	}
	if (isbound(vc_GTP2)) {
		connect(vc_conn:GTP2, vc_GTP2:CLIENT);
		connect(vc_conn:GTP2_PROC, vc_GTP2:CLIENT_PROC);
	}

	/* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
	 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
	vc_conn.start(derefers(fn)(pars));
	return vc_conn;
}

/* altstep for the global guard timer */
private altstep as_Tguard()runs on ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		mtc.stop;
	}
}

friend function f_init_handler(ConnHdlrPars pars, float t_guard := 30.0) runs on ConnHdlr {
	/* make parameters available via component variable */
	g_pars := pars;
	/* start guard timre and activate it as default */
	g_Tguard.start(t_guard);
	activate(as_Tguard());
	if (DIAMETER_PROC.checkstate("Connected")) {
		f_diameter_expect_imsi(g_pars.ue_pars.imsi);
	}
	if (SGsAP_PROC.checkstate("Connected")) {
		/* Route all SGsAP mesages for our IMSIto us */
		f_create_sgsap_expect(pars.ue_pars.imsi);
	}
}



friend function f_s1ap_setup(integer idx := 0, template S1AP_IEs.Cause cause := omit) runs on MTC_CT {
	var template (present) S1AP_IEs.Cause exp_cause;
	var boolean exp_fail := false;
	timer T := 5.0;
	if (not istemplatekind(cause, "omit")) {
		exp_fail := true;
		exp_cause := cause;
	}

	S1AP_UNIT[idx].send(ts_S1AP_SetupReq(g_enb_pars[idx].global_enb_id,
					     g_enb_pars[idx].supported_tas, v32));
	T.start;
	alt {
	[exp_fail] S1AP_UNIT[idx].receive(tr_S1AP_SetupFail(exp_cause)) {
		setverdict(pass);
		}
	[not exp_fail] S1AP_UNIT[idx].receive(tr_S1AP_SetupResp) {
		setverdict(pass);
		}
	[] S1AP_UNIT[idx].receive {
		setverdict(fail, "Received unexpected S1AP");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for S1AP Setup result");
		}
	}
}

/* Unsuccessful S1 Setup procedure to MME (wrong PLMN) */
testcase TC_s1ap_setup_wrong_plmn() runs on MTC_CT {
	var charstring id := testcasename();
	f_init_s1ap(id, 1);
	g_enb_pars[0].global_enb_id.pLMNidentity := '62F224'O;
	f_s1ap_setup(0, {misc:=unknown_PLMN});
}

/* Unsuccessful S1 Setup procedure to MME (wrong PLMN) */
testcase TC_s1ap_setup_wrong_tac() runs on MTC_CT {
	var charstring id := testcasename();
	f_init_s1ap(id, 2);
	g_enb_pars[0].supported_tas[0].broadcastPLMNs[0] := '62F224'O;
	f_s1ap_setup(0, {misc:=unknown_PLMN});
}

/* Successful S1 Setup procedure to MME */
testcase TC_s1ap_setup() runs on MTC_CT {
	var charstring id := testcasename();
	f_init_s1ap(id, 3);
	f_s1ap_setup(0);
}

private const EPS_QualityOfServiceV c_NAS_defaultQoS := {
	qCI := '00'O,
	maxBitRateUplink := omit,
	maxBitRateDownlink := omit,
	guaranteedBitRateUplink := omit,
	guaranteedBitRateDownlink := omit,
	maxBitRateUplinkExt := omit,
	maxBitRateDownlinkExt := omit,
	guaranteedBitRateUplinkExt := omit,
	guaranteedBitRateDownlinkExt := omit,
	maxBitRateUplinkExt2 := omit,
	maxBitRateDownlinkExt2 := omit,
	guaranteedBitRateUplinkExt2 := omit,
	guaranteedBitRateDownlinkExt2 := omit
};

private const UENetworkCapabilityV c_NAS_defaultUeNetCap := {
	eEA := '10000000'B,
	eIA := '11000000'B,
	uEA := omit,
	uIA := omit,
	uCS2 := omit,
	nF := omit,
	vCC := omit,
	lCS := omit,
	lPP := omit,
	aCC_CSFB := omit,
	h245_ASH := omit,
	proSe := omit,
	proSe_dd := omit,
	proSe_dc := omit,
	proSe_relay := omit,
	cP_CIoT := omit,
	uP_CIoT := omit,
	s1_Udata := omit,
	eRwoPDN := omit,
	hC_CP_CIoT := omit,
	ePCO := omit,
	multipleDRB := omit,
	v2XPC5 := omit,
	restrictEC := omit,
	cPbackoff := omit,
	dCNR := omit,
	n1Mode := omit,
	sGC := omit,
	spare1 := omit,
	spare := omit
};

private const octetstring c_NAS_defaultAPN := '00'O;

private altstep as_s1ap_handle_auth() runs on ConnHdlr {
	var PDU_NAS_EPS rx_nas;
	[] S1AP.receive(tr_NAS_AuthReq) -> value rx_nas {
		/* static XRES result as we fixed the HSS RAND value and always have the following
		RAND:   20080c3818183b522614162c07601d0d
		AUTN:   f11b89a2a8be00001f9c526f3d75d44c
		IK:     11329aae8e8d2941bb226b2061137c58
		CK:     740d62df9803eebde5120acf358433d0
		RES:    6a91970e838fd079
		SRES:   e91e4777
		Kc:     3b0f999e42198874
		SQN:    32
		IND:    0
		*/
		/* KASME: 95AFAD9A0D29AFAA079A9451DF7161D7EE4CBF2AF9387F766D058BB6B44B905D */
		const OCT16 ck := '740d62df9803eebde5120acf358433d0'O;
		const OCT16 ik := '11329aae8e8d2941bb226b2061137c58'O;
		const OCT16 autn := 'f11b89a2a8be00001f9c526f3d75d44c'O;
		const OCT8 res := '6a91970e838fd079'O;
		const OCT3 plmn_id := '00F110'O;
		const OCT6 sqn := '000000000020'O;
		const OCT6 ak := substr(autn, 0, 6) xor4b sqn;
		var octetstring kasme := f_kdf_kasme(ck, ik, plmn_id, sqn, ak);
		var S1APEM_Config cfg := {
			set_nas_keys := {
				k_nas_int := f_kdf_nas_int(1, kasme),
				k_nas_enc := f_kdf_nas_enc(1, kasme)
			}
		};
		S1AP.send(cfg);
		S1AP.send(ts_NAS_AuthResp(res));
		}
}

private altstep as_s1ap_handle_sec_mode() runs on ConnHdlr {
	var PDU_NAS_EPS rx_nas;
	var NAS_SecurityAlgorithmsV alg := {
		    typeOfIntegrityProtection := '001'B,
		    spare1 := '0'B,
		    typeOfCiphering := '000'B,
		    spare2 := '0'B
	};
	var NAS_KeySetIdentifierV kset_id := {
		identifier := '000'B,
		tSC := '0'B
	};
	[] S1AP.receive(tr_NAS_SecModeCmd(alg, kset_id, ?)) {
		S1AP.send(ts_NAS_SecModeCmpl);
		}
}

/* Exepect AuthInfoReq (AIR) from HSS; respond with AuthInforAnswer (AIA) */
private altstep as_DIA_AuthInfo() runs on ConnHdlr {
	var PDU_DIAMETER rx_dia;
	[] DIAMETER.receive(tr_DIA_AIR(g_pars.ue_pars.imsi)) -> value rx_dia {
		var template (omit) AVP avp;
		var octetstring sess_id;
		var octetstring vplmn_id;
		var hexstring imsi;
		var template (value) AVP_list auth_info_content;

		/* retrieve input data */
		imsi := valueof(f_DIAMETER_get_imsi(rx_dia));
		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_AAA_3GPP_Visited_PLMN_Id);
		vplmn_id := valueof(avp.avp_data.avp_AAA_3GPP_Visited_PLMN_Id);

		/* compute tuple */
		auth_info_content := { ts_AVP_EutranVec(1, '20080c3818183b522614162c07601d0d'O, '6a91970e838fd079'O, 'f11b89a2a8be00001f9c526f3d75d44c'O, '95AFAD9A0D29AFAA079A9451DF7161D7EE4CBF2AF9387F766D058BB6B44B905D'O) };

		DIAMETER.send(ts_DIA_AIA(auth_info_content, sess_id,
					 hbh_id := rx_dia.hop_by_hop_id,
					 ete_id := rx_dia.end_to_end_id));
	}
}

/* Expect UpdateLocationReq (ULR); respond with UpdateLocationAnswer (ULA) */
private altstep as_DIA_UpdLoc() runs on ConnHdlr {
	var PDU_DIAMETER rx_dia;
	[] DIAMETER.receive(tr_DIA_ULR(g_pars.ue_pars.imsi)) -> value rx_dia {
		var template (omit) AVP avp;
		var hexstring imsi;
		var template (value) AVP_list sub_data;

		/* retrieve input data */
		imsi := valueof(f_DIAMETER_get_imsi(rx_dia));
		avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);

		sub_data := {
			ts_AVP_3GPP_SubscriberStatus(SERVICE_GRANTED),
			ts_AVP_3GPP_SubscrRauTauTmr(30),
			ts_AVP_3GPP_AMBR(1000, 2000),
			ts_AVP_3GPP_ApnConfigProfile({
				ts_AVP_3GPP_ContextId(1),
				ts_AVP_3GPP_AllApnConfigsIncl,
				ts_AVP_3GPP_ApnConfig(1, IPv4, "*")
			})
			};

		DIAMETER.send(ts_DIA_ULA(sub_data, avp.avp_data.avp_BASE_NONE_Session_Id,
					 hbh_id := rx_dia.hop_by_hop_id,
					 ete_id := rx_dia.end_to_end_id));
	}
}

private function f_TC_attach(ConnHdlrPars pars) runs on ConnHdlr {

	f_init_handler(pars);
	var template (value) EPS_MobileIdentityV mi := ts_NAS_MobileId_IMSI(pars.ue_pars.imsi);
	var template (value) PDU_NAS_EPS nas_esm, nas_emm;
	timer T := 5.0;

/*
	nas_esm := ts_NAS_ActDefEpsBearCtxReq(bearer_id := '0000'B, proc_tid := int2bit(1,8),
					      qos := c_NAS_defaultQoS, apn := c_NAS_defaultAPN,
					      addr_type := '000'B, addr_info := ''O);
*/
	nas_esm := ts_NAS_PdnConnReq(bearer_id := '0000'B, proc_tid := int2bit(1,8),
					pdn_type := NAS_PDN_T_IPv4, req_type := '001'B);
	nas_emm := ts_NAS_AttachRequest(att_type := '000'B, kset_id := '000'B, mobile_id := mi,
					ue_net_cap := c_NAS_defaultUeNetCap,
					esm_enc := enc_PDU_NAS_EPS(valueof(nas_esm)));
	var template (value) S1AP_PDU tx;
	tx := ts_S1AP_InitialUE(p_eNB_value := 0, p_nasPdu := enc_PDU_NAS_EPS(valueof(nas_emm)),
				p_tAI := ts_enb_S1AP_TAI(g_pars.enb_pars[g_pars.mme_idx]),
				p_eUTRAN_CGI := ts_enb_S1AP_CGI(g_pars.enb_pars[g_pars.mme_idx]),
				p_rrcCause := mo_Signalling);
	S1AP.send(tx);

	as_DIA_AuthInfo();
	as_s1ap_handle_auth();
	alt {
	[] as_DIA_UpdLoc() {
		as_s1ap_handle_sec_mode();
		}
	[] as_s1ap_handle_sec_mode() {
		as_DIA_UpdLoc();
		}
	}

	/* We now expect the MME to send a Create Session Request to the SGW-C */
	/* TODO: be more restrictive, fix and use tr_GTP2C_CreateSessionReq */
	f_gtp2_register_udmsg('20'O);
	T.start;
	alt {
	[] GTP2.receive(tr_PDU_GTP2C) {
		setverdict(pass);
		}
	[] GTP2.receive {
		setverdict(fail, "unexpected GTPv2/S11 message from MME");
		}
	[] T.timeout {
		setverdict(fail, "no message from MME");
		}
	}

	/* TODO: Finish this procedure until Attach Complete */

}
testcase TC_s1ap_attach() runs on MTC_CT {
	var charstring id := testcasename();

	f_init_diameter(id);
	f_sleep(10.0);
	f_init_s1ap(id, 4);
	f_init_gtpv2_s11(id);
	f_s1ap_setup(0);

	var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
	var ConnHdlr vc_conn;
	vc_conn := f_start_handler_with_pars(refers(f_TC_attach), pars);
	vc_conn.done;
}

private function f_TC_gn_echo_request(ConnHdlrPars pars) runs on ConnHdlr {
	timer T := 5.0;
	f_init_handler(pars);
	f_gtp_register_teid('00000000'O);

	GTP.send(ts_GTPC_PING(g_gn_iface_peer, 1));
	T.start;
	alt {
	[] GTP.receive(tr_GTPC_PONG(?)) {
		setverdict(pass);
		}
	[] GTP.receive {
		setverdict(fail, "unexpected GTPC message from MME");
		}
	[] T.timeout {
		setverdict(fail, "no GTPC ECHO RESPONSE from MME");
		}
	}
}
testcase TC_gn_echo_request() runs on MTC_CT {
	var charstring id := testcasename();

	f_init_diameter(id);
	f_init_s1ap(id, 4);
	f_s1ap_setup(0);
	f_init_gtp(id);

	var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
	var ConnHdlr vc_conn;
	vc_conn := f_start_handler_with_pars(refers(f_TC_gn_echo_request), pars);
	vc_conn.done;
}

external function enc_PDU_GTPC_RAN_INF_REQ(in PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_pdu) return octetstring
with { extension "prototype(convert)"
       extension "encode(RAW)"
     }

external function enc_PDU_GTPC_RAN_INF(in PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_pdu) return octetstring
with { extension "prototype(convert)"
       extension "encode(RAW)"
     }

function f_convert_plmn(OCT3 pLMNidentity) return hexstring {
	var hexstring pLMNidentity_hex := oct2hex(pLMNidentity);
	var hexstring pLMNidentity_hex_swapped;
	pLMNidentity_hex_swapped[0] := pLMNidentity_hex[1];
	pLMNidentity_hex_swapped[1] := pLMNidentity_hex[0];
	pLMNidentity_hex_swapped[2] := pLMNidentity_hex[3];
	pLMNidentity_hex_swapped[3] := pLMNidentity_hex[2];
	pLMNidentity_hex_swapped[4] := pLMNidentity_hex[5];
	pLMNidentity_hex_swapped[5] := pLMNidentity_hex[4];
	return pLMNidentity_hex_swapped;
}

/* Make a template for a GTPC BSSGP container that contains a RAN INFORMATION REQUEST. The template can be used to
 * craft the request for the S1AP/S1-MME interface and also to verfify the contents of the coresponding request on
 * the GTPC/Gn interface */
private function f_make_ts_GTPC_RAN_Information_Request(GTP_CellId geran_gtp_ci)
		 runs on ConnHdlr return template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC {
	var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
	var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
	var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
	var octetstring gnbid;
	var GTP_CellId eutran_gtp_ci;
	eutran_gtp_ci.ra_id.lai.mcc_mnc := f_convert_plmn(g_pars.enb_pars[g_pars.mme_idx].global_enb_id.pLMNidentity);

	gnbid := enc_S1AP_Global_ENB_ID(g_pars.enb_pars[g_pars.mme_idx].global_enb_id);
	gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(geran_gtp_ci);
	gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(eutran_gtp_ci,
							  oct2int(g_pars.enb_pars[g_pars.mme_idx].supported_tas[0].tAC),
							  gnbid);

	gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(
				ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
				ts_GTPC_RIM_Sequence_Number(1),
				ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
				ts_GTPC_RIM_Protocol_Version_Number(1),
				tsu_GTPC_RAN_Information_Request_Application_Container_NACC(geran_gtp_ci),
				omit);
	gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(
				ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
				ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
				gtpc_rim_req_cont);

	return gtpc_bssgp_cont;
}

private function f_make_tr_GTPC_RAN_Information_Request(GTP_CellId geran_gtp_ci)
		 runs on ConnHdlr return template (present) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC {
	var template (present) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
	var template (present) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
	var template (present) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
	var octetstring gnbid;
	var GTP_CellId eutran_gtp_ci;
	eutran_gtp_ci.ra_id.lai.mcc_mnc := f_convert_plmn(g_pars.enb_pars[g_pars.mme_idx].global_enb_id.pLMNidentity);

	gnbid := enc_S1AP_Global_ENB_ID(g_pars.enb_pars[g_pars.mme_idx].global_enb_id);
	gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(geran_gtp_ci);
	gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(eutran_gtp_ci,
							  oct2int(g_pars.enb_pars[g_pars.mme_idx].supported_tas[0].tAC),
							  gnbid);

	gtpc_rim_req_cont := tr_GTPC_RAN_Information_Request_RIM_Container(
				ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
				ts_GTPC_RIM_Sequence_Number(1),
				ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
				ts_GTPC_RIM_Protocol_Version_Number(1),
				tru_GTPC_RAN_Information_Request_Application_Container_NACC(geran_gtp_ci));
	gtpc_bssgp_cont := tr_GTPC_RAN_Information_Request(
				tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
				tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
				gtpc_rim_req_cont);

	return gtpc_bssgp_cont;
}

/* Make initial RAN INFORMATION REQUEST message that is sent on the S1AP/S1-MME interface */
private function f_make_ts_S1AP_eNBDirectInfTrans(GTP_CellId geran_gtp_ci)
						  runs on ConnHdlr return template (value) S1AP_PDU {
	var template (value) Inter_SystemInformationTransferType inf;

	inf.rIMTransfer.rIMInformation := enc_PDU_GTPC_RAN_INF_REQ(valueof(f_make_ts_GTPC_RAN_Information_Request(geran_gtp_ci)));
	inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.lAI.pLMNidentity := hex2oct(f_convert_plmn(hex2oct(geran_gtp_ci.ra_id.lai.mcc_mnc)));
	inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.lAI.lAC := int2oct(geran_gtp_ci.ra_id.lai.lac, 2);
	inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.lAI.iE_Extensions := omit;
	inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.rAC := int2oct(geran_gtp_ci.ra_id.rac, 1);
	inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.cI := int2oct(geran_gtp_ci.cell_id, 2);
	inf.rIMTransfer.rIMRoutingAddress.gERAN_Cell_ID.iE_Extensions := omit;
	inf.rIMTransfer.iE_Extensions := omit;

	return ts_S1AP_eNBDirectInfTrans(inf);
}

/* Make RAN INFORMATION (response) message that is sent on the GTPC/Gn interface */
private function f_make_ts_GTPC_RANInfoRelay(template Gtp1cUnitdata req_gtpc_pdu,
					     GTP_CellId geran_gtp_ci, octetstring geran_si)
					     runs on ConnHdlr return template (value) Gtp1cUnitdata {
	var template Gtp1cUnitdata res_gtpc_pdu;
	var template RAN_Information_RIM_Container_GTPC gtpc_rim_res_cont;
	var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_rim_res_pdu;
	var template RIM_Routing_Information_GTPC gtpc_rim_dst_cell_id, gtpc_rim_src_cell_id;
	var template RIM_RoutingAddress gtpc_rim_ra;
	var template RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr;

	/* Assemble GTPC RAN Information */
	gtpc_rim_res_cont := ts_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
			     ts_GTPC_RIM_Sequence_Number(2),
			     ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
			     ts_GTPC_RIM_Protocol_Version_Number(1),
			     tsu_GTPC_ApplContainer_or_ApplErrContainer_NACC(tsu_GTPC_ApplContainer_NACC(geran_gtp_ci, false, 3, geran_si)),
			     omit);

	/* The source becomes the destination and vice versa */
	gtpc_rim_dst_cell_id := req_gtpc_pdu.gtpc.gtpc_pdu.ranInformationRelay.transparentContainer.
			        rANTransparentContainerField.pDU_BSSGP_RAN_INFORMATION_REQUEST.source_Cell_Identifier
	gtpc_rim_src_cell_id := req_gtpc_pdu.gtpc.gtpc_pdu.ranInformationRelay.transparentContainer.
			        rANTransparentContainerField.pDU_BSSGP_RAN_INFORMATION_REQUEST.destination_Cell_Identifier
	gtpc_bssgp_rim_res_pdu := ts_GTPC_RAN_Information(gtpc_rim_dst_cell_id,
							  gtpc_rim_src_cell_id,
							  gtpc_rim_res_cont);

	/* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/
	gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_rim_dst_cell_id.rIM_Routing_Address)));
	gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(valueof(gtpc_rim_dst_cell_id.rIMRoutingAddressDiscriminator)));

	res_gtpc_pdu := ts_GTPC_RANInfoRelay(g_gn_iface_peer,
					     ts_RANTransparentContainer_RAN_INFO(gtpc_bssgp_rim_res_pdu),
					     gtpc_rim_ra, gtpc_rim_ra_discr);

	return res_gtpc_pdu;
}

/* Make template to verify the RAN INFORMATION REQUEST as it appears on the GTPC/Gn interface */
private function f_make_tr_GTPC_MsgType(GTP_CellId geran_gtp_ci)
					runs on ConnHdlr return template (present) Gtp1cUnitdata {
	var template Gtp1cUnitdata msg;
	var template GTPC_PDUs pdus;
	var template RANTransparentContainer ran_transp_cont;

	ran_transp_cont := tr_RANTransparentContainer_RAN_INFO_REQ(
			   f_make_tr_GTPC_RAN_Information_Request(geran_gtp_ci));
	pdus := tr_RANInfoRelay(ran_transp_cont);
	msg := tr_GTPC_MsgType(g_gn_iface_peer, rANInformationRelay, '00000000'O, pdus);

	return msg;
}

/* Make template to verify the RAN INFORMATION (response) as it appears on the S1AP/S1-MME interface */
private function f_make_tr_S1AP_MMEDirectInfTrans(Gtp1cUnitdata ran_information_gtpc_pdu)
						  runs on ConnHdlr return template (present) S1AP_PDU {
	var template S1AP_PDU msg;
	var template Inter_SystemInformationTransferType inf;

	inf.rIMTransfer.rIMInformation := enc_PDU_GTPC_RAN_INF(
					  ran_information_gtpc_pdu.gtpc.gtpc_pdu.ranInformationRelay.
					  transparentContainer.rANTransparentContainerField.
					  pDU_BSSGP_RAN_INFORMATION);
	inf.rIMTransfer.rIMRoutingAddress := omit;
	inf.rIMTransfer.iE_Extensions := omit;
	msg := tr_S1AP_MMEDirectInfTrans(inf);

	return msg;
}

private function f_TC_RIM_RAN_INF(ConnHdlrPars pars) runs on ConnHdlr {
	timer T := 5.0;
	f_init_handler(pars);
	f_gtp_register_teid('00000000'O);
	var Gtp1cUnitdata req_gtpc_pdu;
	var Gtp1cUnitdata resp_gtpc_pdu;
	var GTP_CellId geran_gtp_ci;

	/* Assemble data of a fictitiously GERAN cell */
	geran_gtp_ci.ra_id.rac := oct2int('BB'O);
	geran_gtp_ci.ra_id.lai.mcc_mnc := '262f42'H
	geran_gtp_ci.ra_id.lai.lac := oct2int('AAAA'O);
	geran_gtp_ci.cell_id := oct2int('04C7'O);
	const octetstring geran_si1 := '198fb100000000000000000000000000007900002b'O;
	const octetstring geran_si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
	const octetstring geran_si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
	const octetstring geran_si := geran_si1 & geran_si3 & geran_si13;

	/* Send initial RAN information request via S1AP to MME and expect the MME to forward the request on GTP-C
	 * (eNB -> MME -> SGSN) */
	S1AP.send(f_make_ts_S1AP_eNBDirectInfTrans(geran_gtp_ci));
	T.start;
	alt {
	[] GTP.receive(f_make_tr_GTPC_MsgType(geran_gtp_ci)) -> value req_gtpc_pdu {
		setverdict(pass);
		}
	[] GTP.receive {
		setverdict(fail, "unexpected GTPC message from MME");
		}
	[] T.timeout {
		setverdict(fail, "no GTPC RAN INFORMATION REQUEST from MME");
		}
	}

	/* Send RAN information response via GTP-C to MME and expect the MME to forward the respnse on S1AP
	 * (SGSN -> MME -> eNB) */
	f_create_s1ap_expect_proc(id_MMEDirectInformationTransfer, self);
	resp_gtpc_pdu := valueof(f_make_ts_GTPC_RANInfoRelay(req_gtpc_pdu, geran_gtp_ci, geran_si));
	GTP.send(resp_gtpc_pdu);
	T.start;
	alt {
	[] S1AP.receive(f_make_tr_S1AP_MMEDirectInfTrans(resp_gtpc_pdu)) {
		setverdict(pass);
		}
	[] S1AP.receive {
		setverdict(fail, "unexpected S1AP message from MME");
		}
	[] T.timeout {
		setverdict(fail, "no S1AP RAN INFORMATION from MME");
		}
	}

	setverdict(pass);
}

testcase TC_RIM_RAN_INF() runs on MTC_CT {
	var charstring id := testcasename();

	f_init_diameter(id);
	f_init_s1ap(id, 4);
	f_s1ap_setup(0);
	f_init_gtp(id);

	var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
	var ConnHdlr vc_conn;
	vc_conn := f_start_handler_with_pars(refers(f_TC_RIM_RAN_INF), pars);

	vc_conn.done;
}

/* Successful RESET procedure from eNB to MME */
testcase TC_s1ap_reset() runs on MTC_CT {
	var charstring id := testcasename();
	f_init_s1ap(id, 3);
	f_s1ap_setup(0);

	var template (value) S1AP_IEs.Cause reset_cause := {misc := om_intervention};
	var template (value) ResetType reset_type := {s1_Interface := reset_all};
	timer T := 5.0;

	S1AP_UNIT[0].send(ts_S1AP_Reset(reset_cause, reset_type));
	T.start;
	alt {
	[] S1AP_UNIT[0].receive(tr_S1AP_ResetAck_any) {
		setverdict(pass);
		}
	[] S1AP_UNIT[0].receive {
		setverdict(fail, "Received unexpected S1AP");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for S1AP Setup result");
		}
	}
}

/* Tracking area update with a GUTI (TMSI) that is unknown to the MME. The MME is expected to reject this TAU
 * request. */
private function f_TC_tau_unknown_guti(ConnHdlrPars pars) runs on ConnHdlr {

	f_init_handler(pars);
	var template (value) EPS_MobileIdentityV mi := ts_NAS_MobileId_IMSI(pars.ue_pars.imsi);
	var template (value) S1AP_PDU tx;
	var template (value) PDU_NAS_EPS nas_tau;
	timer T := 5.0;

	var hexstring mcc_mnc := f_convert_plmn(g_pars.enb_pars[g_pars.mme_idx].global_enb_id.pLMNidentity);
	var EPS_MobileIdentityLV old_guti := valueof(ts_EPS_MobileId_GUTI(mcc_mnc, '0001'O, '01'O, 'AABBCCDD'O));
	nas_tau := ts_PDU_NAS_EPS_TrackingAreaUpdateRequest(old_guti);

	tx := ts_S1AP_InitialUE(p_eNB_value := 0, p_nasPdu := enc_PDU_NAS_EPS(valueof(nas_tau)),
				p_tAI := ts_enb_S1AP_TAI(g_pars.enb_pars[g_pars.mme_idx]),
				p_eUTRAN_CGI := ts_enb_S1AP_CGI(g_pars.enb_pars[g_pars.mme_idx]),
				p_rrcCause := mo_Signalling);

	S1AP.send(tx);

	T.start;
	alt {
	[] S1AP.receive(tr_PDU_NAS_EPS_TrackingAreaUpdateReject) {
		setverdict(pass);
		}
	[] S1AP.receive {
		setverdict(fail, "unexpected S1AP message from MME");
		}
	[] T.timeout {
		setverdict(fail, "no message from MME");
		}
	}

}
testcase TC_s1ap_tau_unknown_guti() runs on MTC_CT {
	var charstring id := testcasename();

	f_init_diameter(id);
	f_init_s1ap(id, 4);
	f_s1ap_setup(0);

	var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
	var ConnHdlr vc_conn;
	vc_conn := f_start_handler_with_pars(refers(f_TC_tau_unknown_guti), pars);
	vc_conn.done;
}

control {
	execute( TC_s1ap_setup_wrong_plmn() );
	execute( TC_s1ap_setup_wrong_tac() );
	execute( TC_s1ap_setup() );
	execute( TC_s1ap_attach() );
	execute( TC_s1ap_tau_unknown_guti() );
	execute( TC_gn_echo_request() );
	execute( TC_RIM_RAN_INF() );
	execute( TC_s1ap_reset() );
}


}
