/* 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 Misc_Helpers 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_ts29_272_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
}

type record BearerConfig {
	 /* EPS Bearer ID */
	uint4_t	ebi optional,
	/* TEI (Data) local side, S11 (SGW) */
	OCT4 	s11_teid_local optional,
	/* TEI (Data) remote side, S11 (SGW) */
	OCT4	s11_teid_remote optional,
	/* TEI (Data) local side, S5c (PGW) */
	OCT4 	s5c_teid_local optional,
	/* TEI (Data) remote side, S5c (PGW) */
	OCT4	s5c_teid_remote optional
};

/* parameters of emulated UE */
type record UeParams {
	hexstring imsi,
	charstring ue_ip,
	NAS_EPS_Types.GUTI guti optional,
	octetstring kasme optional,

	/* TEI (Control) local side, S11 (SGW) */
	OCT4 	s11_teic_local,
	/* TEI (Control) remote side, S11 (SGW) */
	OCT4	s11_teic_remote optional,
	/* TEI (Control) local side, S5c (PGW) */
	OCT4 	s5c_teic_local,
	/* TEI (Control) remote side, S5c (PGW) */
	OCT4	s5c_teic_remote optional,

	BearerConfig bearer optional
}

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;
	charstring mp_s6_diam_realm := "localdomain";
	charstring mp_s6_local_diam_host := "hss.localdomain";
	charstring mp_s6_remote_diam_host := "mme.localdomain";

	/* 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";
	/* RAI+CI served from emulated peer SGSN: */
	integer mp_gn_remote_port := 2123;
	hexstring mp_gn_local_mcc := '262'H;
	hexstring mp_gn_local_mnc := 'f42'H;
	uint16_t mp_gn_local_lac := 39594;
	uint8_t mp_gn_local_rac := 187;
	uint16_t mp_gn_local_ci := 1223;

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

	/* PGW information announced by SGWC. MME never really interacts with these. */
	charstring mp_s5c_pgw_ip := "1.2.3.4";
}

/* 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),
		ue_ip := "192.168.123.50",
		guti := omit,
		kasme := omit,
		s11_teic_local := '00000000'O,
		s11_teic_remote := omit,
		s5c_teic_local := '00000000'O,
		s5c_teic_remote := omit,
		bearer := {
			ebi := omit,
			s11_teid_local := omit,
			s11_teid_remote := omit,
			s5c_teid_local := omit,
			s5c_teid_remote := omit
		}
	}
}
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;
		g_pars.ue_pars.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, g_pars.ue_pars.kasme),
				k_nas_enc := f_kdf_nas_enc(1, g_pars.ue_pars.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);
		}
}


private altstep as_s1ap_handle_IntialCtxSetupReq_Attach_Accept() runs on ConnHdlr {
	var S1AP_PDU rx_msg;
	var PDU_NAS_EPS rx_nas;
	[] S1AP.receive(tr_S1AP_IntialCtxSetupReq) -> value rx_msg {
		var template (omit) MME_UE_S1AP_ID mme_ue_id := f_S1AP_get_MME_UE_S1AP_ID(rx_msg);
		var template (omit) ENB_UE_S1AP_ID enb_ue_id := f_S1AP_get_ENB_UE_S1AP_ID(rx_msg);
		var template (value) E_RABSetupItemCtxtSURes rab_setup_it;
		var template (value) E_RABSetupListCtxtSURes rab_setup_items;
		var octetstring esm_enc;
		var template (value) PDU_NAS_EPS nas;
		var EPS_MobileIdentityTLV mi_tlv;

		S1AP.receive(tr_NAS_AttachAccept()) -> value rx_nas;
		mi_tlv := rx_nas.ePS_messages.ePS_MobilityManagement.pDU_NAS_EPS_AttachAccept.gUTI;
		if (mi_tlv.ePS_MobileIdentity.ePS_MobileIdentity.typeOfIdentity != '110'B) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx GUTI of unexpected MI type: ", mi_tlv));
		}
		g_pars.ue_pars.guti := mi_tlv.ePS_MobileIdentity.ePS_MobileIdentity.oddEvenInd_identity.guti

		rab_setup_it := ts_S1AP_RABSetupItemCtxtSURes(rab_id := 5,
							      tla := oct2bit(f_inet_addr(mp_mme_ip)),
							      gtp_teid := '00000002'O);
		rab_setup_items := ts_S1AP_RABSetupListCtxtSURes(rab_setup_it);
		S1AP.send(ts_S1AP_InitialCtxSetupResp(valueof(mme_ue_id), valueof(enb_ue_id), rab_setup_items));

		nas := ts_NAS_ActDefEpsBearCtxAck(int2bit(g_pars.ue_pars.bearer.ebi, 4), '00000000'B, omit);
		esm_enc := enc_PDU_NAS_EPS(valueof(nas));
		S1AP.send(ts_NAS_AttachComplete(esm_enc));

		/* Optional from the network: */
		S1AP.receive(tr_NAS_EMMInformation);
		}
	[] S1AP.receive(PDU_NAS_EPS:?) -> value rx_nas {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx Unexpected NAS PDU msg: ", rx_nas));
	}
}

private altstep as_s1ap_handle_IntialCtxSetupReq_TAU_Accept() runs on ConnHdlr {
	var S1AP_PDU rx_msg;
	var PDU_NAS_EPS rx_nas;
	[] S1AP.receive(tr_S1AP_IntialCtxSetupReq) -> value rx_msg {
		/* 3GPP TS 23.401 D.3.6 step 22: */
		var template (omit) MME_UE_S1AP_ID mme_ue_id := f_S1AP_get_MME_UE_S1AP_ID(rx_msg);
		var template (omit) ENB_UE_S1AP_ID enb_ue_id := f_S1AP_get_ENB_UE_S1AP_ID(rx_msg);
		var template (value) E_RABSetupItemCtxtSURes rab_setup_it;
		var template (value) E_RABSetupListCtxtSURes rab_setup_items;
		var S1APEM_Config cfg;

		S1AP.receive(tr_PDU_NAS_EPS_TrackingAreaUpdateAccept)-> value rx_nas;

		/* Configure integrity protection: */
		cfg := {
			set_nas_alg_int := NAS_ALG_IP_EIA1
		};
		S1AP.send(cfg);

		rab_setup_it := ts_S1AP_RABSetupItemCtxtSURes(rab_id := 5,
							tla := oct2bit(f_inet_addr(mp_mme_ip)),
							gtp_teid := '00000002'O);
		rab_setup_items := ts_S1AP_RABSetupListCtxtSURes(rab_setup_it);
		S1AP.send(ts_S1AP_InitialCtxSetupResp(valueof(mme_ue_id), valueof(enb_ue_id), rab_setup_items));

		/* 3GPP TS 23.401 D.3.6 step 23: */
		/* Integrity Protection: TS 24.301 Section 4.4.4.3*/
		S1AP.send(ts_PDU_NAS_EPS_TrackingAreaUpdateComplete(c_EPS_SEC_IP));
		}
	[] S1AP.receive(PDU_NAS_EPS:?) -> value rx_nas {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx Unexpected NAS PDU msg: ", rx_nas));
	}
}

private altstep as_s1ap_handle_UeContextReleaseCmd(template S1AP_IEs.Cause cause := ?) runs on ConnHdlr {
	var S1AP_PDU rx_msg;
	var PDU_NAS_EPS rx_nas;
	[] S1AP.receive(tr_S1AP_UeContextReleaseCmd(?, cause)) -> value rx_msg {
		var template MME_UE_S1AP_ID mme_ue_id;
		var template ENB_UE_S1AP_ID enb_ue_id;
		if (not ispresent(rx_msg.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_S1AP_IDs.uE_S1AP_ID_pair)) {
			/* TODO: The UE CONTEXT RELEASE COMMAND (see also: 3GPP TS 36.413, section 9.1.4.6), may identify the
			* context by either an uE_S1AP_ID_pair (MME_UE_S1AP_ID and ENB_UE_S1AP_ID) or an MME_UE_S1AP_ID alone.
			* The latter case is not implemented here yet. */
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("complete implementation of UeContextReleaseCmd handling"));
			return;
		}

		mme_ue_id := rx_msg.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_S1AP_IDs.uE_S1AP_ID_pair.mME_UE_S1AP_ID;
		enb_ue_id := rx_msg.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_S1AP_IDs.uE_S1AP_ID_pair.eNB_UE_S1AP_ID;

		S1AP.send(ts_S1AP_UeContextReleaseCompl(mme_ue_id, enb_ue_id));
		}
	[] S1AP.receive(PDU_NAS_EPS:?) -> value rx_nas {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx Unexpected NAS PDU msg: ", rx_nas));
	}
}

/* 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_DIA_CancelLocation(integer idx := 0, template S1AP_IEs.Cause cause := omit) runs on ConnHdlr {

	var UINT32 hbh_id := f_rnd_octstring(4);
	var UINT32 ete_id := f_rnd_octstring(4);
	var PDU_DIAMETER rx_dia;

	/* Unlike CLR, CLA contains no IMSI. Register ete_id in DIAMETER_Emulation,
	 * so AIA is forwarded back to us in DIAMETER port instead of MTC_CT.DIAMETER_UNIT.
	 */
	f_diameter_expect_eteid(ete_id);

	DIAMETER.send(ts_DIA_CLR(g_pars.ue_pars.imsi, SGSN_UPDATE_PROCEDURE,
		      orig_host := mp_s6_local_diam_host,
		      orig_realm := mp_s6_diam_realm,
		      dest_host := mp_s6_remote_diam_host,
		      dest_realm := mp_s6_diam_realm,
		      hbh_id := hbh_id,
		      ete_id := ete_id));

	alt {
	[] DIAMETER.receive(tr_DIA_CLA) -> value rx_dia {}
	[] DIAMETER.receive(PDU_DIAMETER:?) -> value rx_dia {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter S6b msg rx: ", rx_dia));
		}
	}
}

private altstep as_GTP2C_CreateSession_success() runs on ConnHdlr {
	var PDU_GTPCv2 rx_msg;
	var BearerContextIEs rx_bctx_ies;
	var template (value) FullyQualifiedTEID s11_fteid_c_ie, s11_fteid_u_ie, s5c_fteid_c_ie, s5c_fteid_u_ie;
	var template (value) PDN_AddressAllocation paa;
	var template (value) BearerContextIEs bctx_ies;

	[] GTP2.receive(tr_GTP2C_CreateSessionReq(g_pars.ue_pars.imsi)) -> value rx_msg {
		/* Parse TEIC and Bearer EBI and TEID and store it in g_pars */
		g_pars.ue_pars.s11_teic_remote := rx_msg.gtpcv2_pdu.createSessionRequest.fullyQualifiedTEID[0].tEID_GRE_Key;
		g_pars.ue_pars.s5c_teic_remote := rx_msg.gtpcv2_pdu.createSessionRequest.fullyQualifiedTEID[1].tEID_GRE_Key;

		rx_bctx_ies := rx_msg.gtpcv2_pdu.createSessionRequest.bearerContextGrouped[0].bearerContextIEs;
		g_pars.ue_pars.bearer.ebi := rx_bctx_ies.ePS_Bearer_ID.ePS_Bearer_ID_Value;

		/* allocate + register TEID-C on local side */
		g_pars.ue_pars.s11_teic_local := f_gtp2_allocate_teid();
		g_pars.ue_pars.bearer.s11_teid_local := g_pars.ue_pars.s11_teic_local;
		g_pars.ue_pars.s5c_teic_local := f_gtp2_allocate_teid();
		g_pars.ue_pars.bearer.s5c_teid_local := g_pars.ue_pars.s5c_teic_local;

		s11_fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S11_MME_GTPC, g_pars.ue_pars.s11_teic_local, 0,
					f_inet_addr(mp_s11_local_ip), omit);
		s5c_fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_PGW_GTPC, g_pars.ue_pars.s5c_teic_local, 1,
					f_inet_addr(mp_s5c_pgw_ip), omit);
		s11_fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S1U_SGW_GTPU, g_pars.ue_pars.bearer.s11_teid_local, 0,
					f_inet_addr(mp_s11_local_ip), omit);
		s5c_fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_PGW_GTPU, g_pars.ue_pars.bearer.s5c_teid_local, 2,
					f_inet_addr(mp_s5c_pgw_ip), omit);
		paa := ts_GTP2C_PdnAddrAlloc_v4(f_inet_addr(g_pars.ue_pars.ue_ip));
		bctx_ies := ts_GTP2C_BcContextIE(ebi := g_pars.ue_pars.bearer.ebi,
						 teid_list := { s11_fteid_u_ie, s5c_fteid_u_ie },
						 qos := ts_GTP2C_BearerQos('09'O, 0, 0, 0, 0),
						 charging_id := ts_GTP2C_ChargingID(g_pars.ue_pars.bearer.s11_teid_local));

		GTP2.send(ts_GTP2C_CreateSessionResp(g_pars.ue_pars.s11_teic_remote,
						     rx_msg.sequenceNumber,
						     { s11_fteid_c_ie, s5c_fteid_c_ie },
						     paa, { ts_GTP2C_BcGrouped(bctx_ies) } ));
		setverdict(pass);
	}
	[] GTP2.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Unexpected GTPv2/S11 message from MME"));
	}
}

private altstep as_GTP2C_ModifyBearer_success() runs on ConnHdlr {
	var PDU_GTPCv2 rx_msg;
	var BearerContextIEs rx_bctx_ies;
	var template (value) FullyQualifiedTEID s11_fteid_c_ie, s11_fteid_u_ie, s5c_fteid_c_ie, s5c_fteid_u_ie;
	var template (value) BearerContextIEs bctx_ies;

	[] GTP2.receive(tr_GTP2C_ModifyBearerReq(g_pars.ue_pars.s11_teic_local)) -> value rx_msg {

		rx_bctx_ies := rx_msg.gtpcv2_pdu.modifyBearerRequest.bearerContextGrouped[0].bearerContextIEs;

		/* TODO: validate the S1-U fullyQualifiedTEID announces the IP address provided by the ENB in InitialCtxSetupResp */
		// rx_bctx_ies.fullyQualifiedTEID[0]. == f_inet_addr(mp_mme_ip)

		/* Update S11 TEID */
		g_pars.ue_pars.bearer.s11_teid_remote := rx_bctx_ies.fullyQualifiedTEID[0].tEID_GRE_Key;

		s11_fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S1U_SGW_GTPU, g_pars.ue_pars.bearer.s11_teid_local, 0,
					f_inet_addr(mp_s11_local_ip), omit);
		bctx_ies := ts_GTP2C_BcContextIE(ebi := g_pars.ue_pars.bearer.ebi,
						 teid_list := { s11_fteid_u_ie },
						 qos := ts_GTP2C_BearerQos('09'O, 0, 0, 0, 0),
						 charging_id := ts_GTP2C_ChargingID(g_pars.ue_pars.bearer.s11_teid_local));

		GTP2.send(ts_GTP2C_ModifyBearerResp(g_pars.ue_pars.s11_teic_remote,
						     rx_msg.sequenceNumber,
						     Request_accepted,
						     g_pars.ue_pars.bearer.ebi,
						     { ts_GTP2C_BcGrouped(bctx_ies) } ));
		setverdict(pass);
	}
	[] GTP2.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Unexpected GTPv2/S11 message from MME"));
	}
}

private altstep as_GTP2C_DeleteSession_success(template Indication ind_flags := *) runs on ConnHdlr {
	var PDU_GTPCv2 rx_msg;

	[] GTP2.receive(tr_GTP2C_DeleteSessionReq(g_pars.ue_pars.s11_teic_local, indicationFlags := ind_flags)) -> value rx_msg {
		GTP2.send(ts_GTP2C_DeleteSessionResp(g_pars.ue_pars.s11_teic_remote,
						     rx_msg.sequenceNumber,
						     Request_accepted));
		setverdict(pass);
	}
	[] GTP2.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Unexpected GTPv2/S11 message from MME"));
	}
}


/* 3GPP TS 23.401 D.3.5, TS 23.003 2.8.2.1 */
private function guti2rai_ptmsi(in NAS_EPS_Types.GUTI guti, in OCT2 truncated_nas_token, out RoutingAreaIdentity rai, out OCT4 ptmsi, out OCT3 ptmsi_sig) runs on ConnHdlr {
	var bitstring mtmsi_bits := oct2bit(guti.mTMSI);
	var bitstring ptmsi_bits;
	var bitstring ptmsi_sig_bits;

	rai := valueof(ts_RoutingAreaIdentity(guti.mccDigit1 & guti.mccDigit2 & guti.mccDigit3,
					      guti.mncDigit3 & guti.mncDigit1 & guti.mncDigit2,
					      guti.mMEGI, guti.mMEC));
	/* 3GPP TS 23.003 2.8.2.0: "P-TMSI shall be of 32 bits length where the two topmost bits are
	 * reserved and always set to '11'. Hence, for a UE which may handover to GERAN/UTRAN (based on
	 * subscription and UE capabilities), the corresponding bits in the M-TMSI are set to '11'"
	 */
	ptmsi_bits := '11'B & substr(mtmsi_bits, 2, 6) & oct2bit(guti.mMEC) & substr(mtmsi_bits, 16, 16);
	ptmsi_sig_bits := substr(mtmsi_bits, 8, 8) & oct2bit(truncated_nas_token);
	ptmsi := bit2oct(ptmsi_bits);
	ptmsi_sig := bit2oct(ptmsi_sig_bits);
	/* TODO: The UE shall fill the remaining 2 octets of the <P-TMSI signature> according to clauses 9.1.1, 9.4.1, 10.2.1, or
	 * 10.5.1 of 3GPP TS.33.401 [89] , as appropriate, for RAU/Attach procedures.*/
}

/* Test UE attached to EUTRAN reselecting a GERAN cell. In this scenario, the
 * new SGSN will attempt to obtain information of the UE from the old SGSN (MME)
 * through Gn interface using SGSN Context Request/Response procedure (OS#6294). */
private function f_gtp_sgsn_context_4g_to_2g(OCT4 new_sgsn_local_teid := '12345678'O) runs on ConnHdlr {
	var template (value) GTPC_PDUs SGSNContextReqPDU;
	var RoutingAreaIdentity rai;
	var OCT4 ptmsi;
	var OCT3 ptmsi_sig;
	var Gtp1cUnitdata gtpc_pdu;
	var OCT4 old_mme_local_teid;
	var  uint16_t gtpc_seq_nr := f_rnd_int(65535);

	/* Derive NAS Token (and post-increment ul_count): */
	var OCT32 nas_token := f_s1apem_derive_nas_token(g_pars.ue_pars.kasme);
	var OCT2 truncated_nas_token := substr(nas_token, 30, 2);

	guti2rai_ptmsi(g_pars.ue_pars.guti, truncated_nas_token, rai, ptmsi, ptmsi_sig);

	SGSNContextReqPDU := ts_SGSNContextReqPDU(rai, new_sgsn_local_teid, f_inet_addr(mp_gn_local_ip),
						  ptmsi := ts_PTMSI(ptmsi), ptmsi_sig := ts_PTMSI_sig(ptmsi_sig));
	GTP.send(ts_GTPC_SGSNContextReq(g_gn_iface_peer, gtpc_seq_nr, SGSNContextReqPDU));

	timer T := 5.0;
	T.start;
	alt {
	[] GTP.receive(tr_GTPC_SGSNContextResp(g_gn_iface_peer, new_sgsn_local_teid,
					       tr_SGSNContextRespPDU(GTP_CAUSE_REQUEST_ACCEPTED,
					       g_pars.ue_pars.imsi))) -> value gtpc_pdu {
		old_mme_local_teid := gtpc_pdu.gtpc.gtpc_pdu.sgsn_ContextResponse.teidControlPlane.teidControlPlane;
		setverdict(pass);
		}
	[] GTP.receive {
		 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("unexpected GTPC message from MME"));
		}
	[] T.timeout {
		 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("no SGSN Context Response from MME"));
		}
	}

	GTP.send(ts_GTPC_SGSNContextAck(g_gn_iface_peer, old_mme_local_teid,
					oct2int(gtpc_pdu.gtpc.opt_part.sequenceNumber),
					ts_SGSNContextAckPDU(GTP_CAUSE_REQUEST_ACCEPTED)));

}

private altstep as_gtp_sgsn_context_2g_to_4g(OCT4 new_sgsn_teid := 'ABABABAB'O, GTP_Templates.GTP_RATType rat_type := GTP_RAT_TYPE_EUTRAN) runs on ConnHdlr {
	var Gtp1cUnitdata gtpc_pdu;

	[] GTP.receive(tr_GTPC_SGSNContextReq(g_gn_iface_peer, tr_SGSNContextReqPDU(rat_type := int2oct(enum2int(rat_type), 1)))) -> value gtpc_pdu {
		var template (value) PDP_Context_GTPC pdp_ctx;
		var template (value) GTPC_PDUs SGSNContextRespPDU;
		var Gtp1cUnitdata gtpc_pdu_ack;
		var OCT4 old_mme_remote_teid := gtpc_pdu.gtpc.gtpc_pdu.sgsn_ContextRequest.teidControlPlane.teidControlPlane;

		const OCT16 ck := '740d62df9803eebde5120acf358433d0'O;
		const OCT16 ik := '11329aae8e8d2941bb226b2061137c58'O;

		pdp_ctx := ts_PDP_Context_GTPC(f_inet_addr(g_pars.ue_pars.ue_ip),
					       f_inet_addr(mp_gn_local_ip),
					       c_NAS_defaultAPN,
					       ggsn_teic := '12345678'O,
					       ggsn_teid := '87654321'O);
		SGSNContextRespPDU := ts_SGSNContextRespPDU(GTP_CAUSE_REQUEST_ACCEPTED,
							   g_pars.ue_pars.imsi,
							   new_sgsn_teid,
							   f_inet_addr(mp_gn_local_ip),
							   ts_MM_ContextUMTS(ck, ik),
							   { pdp_ctx });
		GTP.send(ts_GTPC_SGSNContextResp(g_gn_iface_peer,
						 old_mme_remote_teid,
						 oct2int(gtpc_pdu.gtpc.opt_part.sequenceNumber),
						 SGSNContextRespPDU));

		GTP.receive(tr_GTPC_SGSNContextAck(g_gn_iface_peer, new_sgsn_teid,
						   tr_SGSNContextAckPDU(GTP_CAUSE_REQUEST_ACCEPTED))) -> value gtpc_pdu;
		setverdict(pass);
	}
	[] GTP.receive {
		setverdict(fail, "unexpected GTPC message from MME");
	}
}

private function f_attach() runs on ConnHdlr {
	var template (value) EPS_MobileIdentityV mi := ts_NAS_MobileId_IMSI(g_pars.ue_pars.imsi);
	var template (value) PDU_NAS_EPS nas_esm, nas_emm;
	timer T := 5.0;

	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 */
	f_gtp2_register_udmsg('20'O);
	T.start;
	alt {
	[] as_GTP2C_CreateSession_success();
	[] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); }
	}

	T.start;
	alt {
	[] as_s1ap_handle_IntialCtxSetupReq_Attach_Accept();
	[] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); }
	}

	/* We now expect the MME to send a Modify Bearer Request to the SGW-C */
	f_gtp2_register_udmsg('22'O);
	T.start;
	alt {
	[] as_GTP2C_ModifyBearer_success();
	[] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); }
	}
}

private function f_TC_attach(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	f_attach();
}
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, 0);
	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 := mp_gn_local_rac;
	geran_gtp_ci.ra_id.lai.mcc_mnc := mp_gn_local_mcc & mp_gn_local_mnc;
	geran_gtp_ci.ra_id.lai.lac := mp_gn_local_lac;
	geran_gtp_ci.cell_id := mp_gn_local_ci;
	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, 0);
	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, 0);
	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");
		}
	}

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

	f_init_diameter(id);
	f_init_s1ap(id, 5);
	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;
}

private function f_TC_ue_cell_reselect_eutran_to_geran(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	f_gtp_register_imsi(g_pars.ue_pars.imsi);
	f_attach();

	/* TS 23.401 Figure D.3.5-1 Steps 1,2,3,4: */
	f_gtp_sgsn_context_4g_to_2g();

	/* TS 23.401 Figure D.3.5-1 Step 8: */
	f_DIA_CancelLocation();

	/* TS 23.401 Figure D.3.5-1 Step 13:
	 * Upon rx of SGSN Context Acknowledge, MME released the ENB/UE context:
	 */
	as_s1ap_handle_UeContextReleaseCmd();

	/* TS 23.401 Figure D.3.5-1 Step 13:
	 * After Gn timer triggers, the SGW session is deleted.
	 * Make sure Operation Indication is set to 0, to tell the SGW to keep the Session up at the PGW.
	 */
	as_GTP2C_DeleteSession_success(tr_GTP2C_Indication(oI := '0'B));
	/* Let MME some time to handle the Create Session Response: */
	f_sleep(3.0);
}
testcase TC_ue_cell_reselect_eutran_to_geran() runs on MTC_CT {
	var charstring id := testcasename();

	f_init_diameter(id);
	f_init_s1ap(id, 6);
	f_init_gtpv2_s11(id);
	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_ue_cell_reselect_eutran_to_geran), pars);
	vc_conn.done;
}

/* 3GPP TS 23.401 D.3.6, TS 23.003 2.8.2.2 */
private function rai_ptmsi2_guti(in RoutingAreaIdentity rai, in OCT4 ptmsi, in OCT3 ptmsi_sig, out NAS_EPS_Types.GUTI guti) runs on ConnHdlr {


	var bitstring ptmsi_bits := oct2bit(ptmsi);
	var bitstring ptmsi_sig_bits := oct2bit(ptmsi_sig);
	var bitstring mtmsi_bits := '11'B &
				    substr(ptmsi_bits, 2, 6) &
				    substr(ptmsi_sig_bits, 0, 8) &
				    substr(ptmsi_bits, 16, 16);
	guti := valueof(ts_NAS_GUTI(mcc_mnc := rai.mcc_digits & rai.mnc_digits,
			    mmegi := rai.lac,
			    mmec := rai.rac,
			    tmsi := bit2oct(mtmsi_bits)));
}
/* Test UE attached to GERAN reselecting a EUTRAN cell. In this scenario, the
 * new MME will attempt to obtain information of the UE from the old SGSN
 * through Gn interface using SGSN Context Request/Response procedure (OS#6294). */
/* 3GPP TS 23.401 D.3.6, TS 23.003 2.8.2.1 */
private function f_TC_ue_cell_reselect_geran_to_eutran(ConnHdlrPars pars) runs on ConnHdlr {
	f_init_handler(pars);
	f_gtp_register_imsi(g_pars.ue_pars.imsi);
	f_gtp2_register_imsi(g_pars.ue_pars.imsi);
	/* SGSN Context Req doesn't necessarily contain IMSI, hence expect it through TEID=0 */
	f_gtp_register_teid('00000000'O);
	/* passed in SGSN Context Resp to MME, will be used by MME when answering with SGSN Context Ack: */
	const OCT4 new_sgsn_teid := 'ABABABAB'O;
	f_gtp_register_teid(new_sgsn_teid);

	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;
	var RoutingAreaIdentity rai;
	var OCT4 ptmsi := f_gen_tmsi(suffix := 0, nri_v := 0, nri_bitlen := 8);
	var OCT3 ptmsi_sig := f_rnd_octstring(3);
	var NAS_EPS_Types.GUTI guti_val;
	var template (value) EPS_MobileIdentityLV old_guti;
	var S1APEM_Config cfg;
	timer T := 5.0;

	rai := valueof(ts_RoutingAreaIdentity(mp_gn_local_mcc, mp_gn_local_mnc,
				      int2oct(mp_gn_local_lac, 2), int2oct(mp_gn_local_rac, 1)));
	rai_ptmsi2_guti(rai, ptmsi, ptmsi_sig, guti_val);
	old_guti := ts_EPS_MobileId_GUTI_(guti_val);

	nas_tau := ts_PDU_NAS_EPS_TrackingAreaUpdateRequest(old_guti,
							    ts_PTMSI_SignatureTV(ptmsi_sig),
							    ts_GUTI_TypeTV(GUTI_TYPE_MAPPED),
							    ts_NonceTV('12345678'O),
							    ts_CipheringKeySequenceNumberTV('000'B));
	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);

	/* NAS counts are reset to zero when a mapped security context is created. */
	cfg := {
		reset_nas_counts := {}
	};
	S1AP.send(cfg);

	as_gtp_sgsn_context_2g_to_4g(new_sgsn_teid);

	/* We now expect the MME to send a Create Session Request to the SGW-C */
	T.start;
	alt {
	[] as_GTP2C_CreateSession_success();
	[] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); }
	}

	/* 3GPP TS 23.401 D.3.6 steps 14-21: */
	as_DIA_UpdLoc();

	/* 3GPP TS 23.401 D.3.6 step 22, 23: */
	as_s1ap_handle_IntialCtxSetupReq_TAU_Accept();

	/* We now expect the MME to send a Modify Bearer Request to the SGW-C */
	T.start;
	alt {
	[] as_GTP2C_ModifyBearer_success();
	[] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No message from MME")); }
	}

	/* Leave some time for MME to handle Modify Bearer Response: */
	f_sleep(1.0);
}
testcase TC_ue_cell_reselect_geran_to_eutran() runs on MTC_CT {
	var charstring id := testcasename();

	f_init_diameter(id);
	f_init_s1ap(id, 7);
	f_init_gtpv2_s11(id);
	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_ue_cell_reselect_geran_to_eutran), 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() );
	execute( TC_ue_cell_reselect_eutran_to_geran() );
	execute( TC_ue_cell_reselect_geran_to_eutran() );
}


}
