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

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];
}

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

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

	timer T := 3.0;

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

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() );
	execute( TC_RIM_RAN_INF() );
	execute( TC_s1ap_reset() );
}


}
