mme: initial skeleton for MME / SGsAP tetss

Change-Id: Idbd54838daaf12acccc3253dc4278de75eaaaf31
diff --git a/mme/MME_Tests_SGsAP.ttcn b/mme/MME_Tests_SGsAP.ttcn
new file mode 100644
index 0000000..935a59e
--- /dev/null
+++ b/mme/MME_Tests_SGsAP.ttcn
@@ -0,0 +1,210 @@
+module MME_Tests_SGsAP {
+
+/* Osmocom MME test suite in 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
+ */
+
+import from SGsAP_Types all;
+import from SGsAP_Templates all;
+import from SGsAP_Emulation all;
+
+import from General_Types all;
+import from Osmocom_Types all;
+import from L3_Templates all;
+import from DNS_Helpers all;
+import from MME_Tests all;
+
+/* performa SGs reset procedure */
+function f_sgsap_vlr_reset() runs on ConnHdlr {
+	var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
+	var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
+
+	SGsAP.send(ts_SGsAP_RESET_IND_VLR(vlr_name));
+	alt {
+	[] SGsAP.receive(tr_SGsAP_RESET_ACK(mme_name, vlr_name)) {
+		setverdict(pass);
+		}
+	[] SGsAP.receive(tr_SGsAP_RESET_ACK(?, ?)) {
+		setverdict(fail, "Received unexpected VLR/MME name in SGsAP RESET ACK");
+		}
+	[] SGsAP.receive {
+		setverdict(fail, "Received unexpected response to SGsAP RESET");
+		}
+	}
+}
+
+/* perform a SGs paging procedure */
+function f_sgsap_page(Service_Indicator serv_ind, template (omit) OCT4 tmsi,
+			template (omit) SGs_Cause exp_cause) runs on ConnHdlr {
+	var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
+	var boolean exp_success := true;
+	var PDU_SGsAP rx;
+	if (not istemplatekind(exp_cause, "omit")) {
+		exp_success := false;
+	}
+	SGsAP.send(ts_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, serv_ind, tmsi));
+	alt {
+	/* we expect success */
+	[exp_success] SGsAP.receive(tr_SGsAP_SERVICE_REQ(g_pars.imsi, serv_ind, ?)) {
+		setverdict(pass);
+		}
+	[exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.imsi, ?)) {
+		setverdict(fail, "Received unexpected PAGING REJECT");
+		}
+	/* we expect failure */
+	[not exp_success] SGsAP.receive(tr_SGsAP_SERVICE_REQ(g_pars.imsi, serv_ind, ?)) {
+		setverdict(fail, "Received SERVICE REQ waiting for PAGING REJECT");
+		}
+	[not exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.imsi, exp_cause)) {
+		setverdict(pass);
+		}
+	[not exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.imsi, ?)) {
+		setverdict(fail, "Received unexpected PAGING REJECT cause");
+		}
+	[] SGsAP.receive {
+		setverdict(fail, "Received unexpected SgSAP");
+		}
+	}
+}
+
+/* perform a SGs alert procedure */
+function f_sgsap_alert(template (omit) SGs_Cause exp_cause) runs on ConnHdlr{
+	var boolean exp_success := true;
+	var PDU_SGsAP rx;
+	if (not istemplatekind(exp_cause, "omit")) {
+		exp_success := false;
+	}
+	SGsAP.send(ts_SGsAP_ALERT_REQ(g_pars.imsi));
+	alt {
+	[exp_success] SGsAP.receive(tr_SGsAP_ALERT_ACK(g_pars.imsi)) {
+		setverdict(pass);
+		}
+	[exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.imsi, ?)) -> value rx {
+		setverdict(fail, "Received unexpected ALERT REJECT ", rx);
+		}
+	[not exp_success] SGsAP.receive(tr_SGsAP_ALERT_ACK(g_pars.imsi)) {
+		setverdict(fail, "Received unexpected ALERT ACK");
+		}
+	[not exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.imsi, exp_cause)) {
+		setverdict(pass)
+		}
+	[not exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.imsi, ?)) -> value rx {
+		setverdict(fail, "Received ALERT REJECT with unexpected cause ", rx);
+		}
+	[] SGsAP.receive {
+		setverdict(fail, "Received unexpected SGsAP");
+		}
+	}
+}
+
+/* Test if MME responds to VLR-originated RESET procedure as expected */
+private function f_TC_sgsap_vlr_reset(ConnHdlrPars pars) runs on ConnHdlr {
+	f_init_handler(pars);
+	f_sgsap_vlr_reset();
+}
+testcase TC_sgsap_vlr_reset() runs on MTC_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+	f_init_sgsap(testcasename());
+	pars := f_init_pars(1);
+	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_vlr_reset), pars);
+	vc_conn.done;
+}
+
+/* Page known subscriber for SMS */
+private function f_TC_sgsap_paging_sms(ConnHdlrPars pars) runs on ConnHdlr {
+	f_init_handler(pars);
+	/* TODO: register subscriber on S1 */
+	f_sgsap_page(SMS_indicator, omit, omit);
+}
+testcase TC_sgsap_paging_sms() runs on MTC_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+	f_init_sgsap(testcasename());
+	pars := f_init_pars(2);
+	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_paging_sms), pars);
+	vc_conn.done;
+}
+
+/* Page known subscriber for CS call */
+private function f_TC_sgsap_paging_cs(ConnHdlrPars pars) runs on ConnHdlr {
+	f_init_handler(pars);
+	/* TODO: register subscriber on S1 */
+	f_sgsap_page(CS_call_indicator, omit, omit);
+}
+testcase TC_sgsap_paging_cs() runs on MTC_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+	f_init_sgsap(testcasename());
+	pars := f_init_pars(3);
+	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_paging_cs), pars);
+	vc_conn.done;
+}
+
+
+/* Page unknown subscriber; expect PAGING REJECT from MME */
+private function f_TC_sgsap_paging_reject(ConnHdlrPars pars) runs on ConnHdlr {
+	f_init_handler(pars);
+	f_sgsap_page(SMS_indicator, omit, IMSI_unknown);
+}
+testcase TC_sgsap_paging_reject() runs on MTC_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+	f_init_sgsap(testcasename());
+	pars := f_init_pars(4);
+	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_paging_reject), pars);
+	vc_conn.done;
+}
+
+/* Send ALERT-REQ to MME; perform S1AP activity; expect ALERT-ACK on SGs */
+private function f_TC_sgsap_alert(ConnHdlrPars pars) runs on ConnHdlr {
+	f_init_handler(pars);
+	/* TODO: register subscriber on S1 */
+	f_sgsap_alert(omit);
+	/* TOOD: do something on S1 triggering UE ACT IND */
+	SGsAP.receive(tr_SGsAP_UE_ACT_IND(g_pars.imsi));
+}
+testcase TC_sgsap_alert() runs on MTC_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+	f_init_sgsap(testcasename());
+	pars := f_init_pars(5);
+	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_alert), pars);
+	vc_conn.done;
+}
+
+/* Send ALERT-REQ to MME for unidentified IMSI; expect ALERT-REJ on SGs */
+private function f_TC_sgsap_alert_rej(ConnHdlrPars pars) runs on ConnHdlr {
+	f_init_handler(pars);
+	/* IMSI doesn't register and is hence unknown */
+	f_sgsap_alert(IMSI_unknown);
+}
+testcase TC_sgsap_alert_rej() runs on MTC_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+	f_init_sgsap(testcasename());
+	pars := f_init_pars(6);
+	vc_conn := f_start_handler_with_pars(refers(f_TC_sgsap_alert_rej), pars);
+	vc_conn.done;
+}
+
+
+/* Test SGsAP-DOWNLINK-UNITDATA (SGs -> S1) */
+/* Test SGsAP-UPLINK-UNITDATA (S1 -> SGs)*/
+/* Test SGSAP-DETACH-IND; detach on S1; expect DETACH-IND on SGs; send DETACH-ACK */
+/* Test SGsAP-LU-REQ; perform combined attach on S1; expect LU-REQ; acknowlege it */
+/* Test SGsAP-LU-REQ; perform combined attach on S1; expect LU-REQ; reject it */
+/* Test SGsAP-MMINFO-REQ; establish SGs association; send it on SGs; expect on S1 */
+
+/* Test MT SERVICE ABORT; send PAGING; expect SERVICE REQ; send SERVICE ABORT */
+
+/* Test EPS DETACH */
+/* Test IMSI DETACH */
+
+}