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

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


}
