module MME_Tests_SGsAP { /* Osmocom MME test suite in in TTCN-3 * (C) 2019 Harald Welte * 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.ue_pars.imsi, vlr_name, serv_ind, tmsi)); alt { /* we expect success */ [exp_success] SGsAP.receive(tr_SGsAP_SERVICE_REQ(g_pars.ue_pars.imsi, serv_ind, ?)) { setverdict(pass); } [exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.ue_pars.imsi, ?)) { setverdict(fail, "Received unexpected PAGING REJECT"); } /* we expect failure */ [not exp_success] SGsAP.receive(tr_SGsAP_SERVICE_REQ(g_pars.ue_pars.imsi, serv_ind, ?)) { setverdict(fail, "Received SERVICE REQ waiting for PAGING REJECT"); } [not exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.ue_pars.imsi, exp_cause)) { setverdict(pass); } [not exp_success] SGsAP.receive(tr_SGsAP_PAGING_REJ(g_pars.ue_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.ue_pars.imsi)); alt { [exp_success] SGsAP.receive(tr_SGsAP_ALERT_ACK(g_pars.ue_pars.imsi)) { setverdict(pass); } [exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.ue_pars.imsi, ?)) -> value rx { setverdict(fail, "Received unexpected ALERT REJECT ", rx); } [not exp_success] SGsAP.receive(tr_SGsAP_ALERT_ACK(g_pars.ue_pars.imsi)) { setverdict(fail, "Received unexpected ALERT ACK"); } [not exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.ue_pars.imsi, exp_cause)) { setverdict(pass) } [not exp_success] SGsAP.receive(tr_SGsAP_ALERT_REJECT(g_pars.ue_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.ue_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 */ }