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

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;

	var UeParams g_ue_pars[NUM_UE];
}

type component ConnHdlr extends S1AP_ConnHdlr, SGsAP_ConnHdlr, DIAMETER_ConnHdlr, GTP_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_local_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";
}

/* 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 template (value) 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);
	}

	/* 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(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 Cause cause := omit) runs on MTC_CT {
	var template (present) 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;
/*
	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();
		}
	}

	f_sleep(10.0);
}
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_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;
}

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


}
