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

	var UeParams g_ue_pars[NUM_UE];
}

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

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

/* 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 S1apCreateCallback(S1AP_PDU msg, template (omit) MME_UE_S1AP_ID mme_id,
				   template (omit) ENB_UE_S1AP_ID enb_id, charstring id)
runs on S1AP_Emulation_CT return S1AP_ConnHdlr
{
	setverdict(fail, "implement this");
	mtc.stop;
}

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

	/* 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(rx_dia.hop_by_hop_id, rx_dia.end_to_end_id,
					 sess_id, auth_info_content));
	}
}

/* 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 octetstring sess_id;
		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);
		sess_id := valueof(avp.avp_data.avp_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(rx_dia.hop_by_hop_id, rx_dia.end_to_end_id, sess_id, sub_data));
	}
}

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

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


}
