jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/41188?usp=email )
Change subject: MME-Tests: Add tests for emergency cappability indication ......................................................................
MME-Tests: Add tests for emergency cappability indication
When an attachment is accepted, MME indicates the capability of emergency calls, if and only if configured in MME's configuration file. The emergency numbers that are configured are also indicated.
The tests check if the indications follow the configuration and are correctly encoded.
Related: SYS#7635 Change-Id: I3d84486dd3826d0f60a3c06693118e36b01ecd2b --- M mme/ConnHdlr.ttcn M mme/MME_Tests.ttcn A mme/MME_Tests_emergency.ttcn M mme/expected-results.xml A mme/open5gs-mme_emergency.yaml A mme/testenv_emergency.cfg R mme/testenv_generic.cfg 7 files changed, 237 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/88/41188/1
diff --git a/mme/ConnHdlr.ttcn b/mme/ConnHdlr.ttcn index ab97983..4af7095 100644 --- a/mme/ConnHdlr.ttcn +++ b/mme/ConnHdlr.ttcn @@ -124,6 +124,16 @@ OCT4 tmsi optional }
+/* parameters of emergency support */ +type record EmergParams { + boolean expect_s1_emergency, + BIT1 s1_emergency, + boolean expect_number, + integer numbers, + BIT5 categories[8], + octetstring digits[8] +} + type record ConnHdlrPars { /* copied over from MTC_CT on start of component */ EnbParams enb_pars[NUM_ENB], @@ -135,7 +145,9 @@ /* currently used MME (index into enb_pars, S1AP, ...) */ integer mme_idx, /* Currently set KSI */ - NAS_KeySetIdentifierV kset_id + NAS_KeySetIdentifierV kset_id, + /* Expected emergency parameters */ + EmergParams emerg_pars }
type component ConnHdlr extends S1AP_ConnHdlr, SGsAP_ConnHdlr, DIAMETER_ConnHdlr, GTP_ConnHdlr, GTP2_ConnHdlr { @@ -306,14 +318,48 @@ var template (value) E_RABSetupListCtxtSURes rab_setup_items; var octetstring esm_enc; var template (value) PDU_NAS_EPS nas; + var PDU_NAS_EPS_AttachAccept attach_accept; var EPS_MobileIdentityTLV mi_tlv; + var EPS_NetworkFeatureSupportTLV nfs_tlv; + var EmergencyNumberListTLV enl_tlv;
S1AP.receive(tr_NAS_AttachAccept()) -> value rx_nas; - mi_tlv := rx_nas.ePS_messages.ePS_MobilityManagement.pDU_NAS_EPS_AttachAccept.gUTI; + attach_accept := rx_nas.ePS_messages.ePS_MobilityManagement.pDU_NAS_EPS_AttachAccept; + mi_tlv := attach_accept.gUTI; if (mi_tlv.ePS_MobileIdentity.ePS_MobileIdentity.typeOfIdentity != '110'B) { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx GUTI of unexpected MI type: ", mi_tlv)); } g_pars.ue_pars.guti := mi_tlv.ePS_MobileIdentity.ePS_MobileIdentity.oddEvenInd_identity.guti + nfs_tlv := attach_accept.ePS_NetworkFeatureSupport; + if (g_pars.emerg_pars.expect_s1_emergency and nfs_tlv.eMCBS != g_pars.emerg_pars.s1_emergency) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected emergency support: ", nfs_tlv.eMCBS)); + } + if (g_pars.emerg_pars.expect_number) { + if (not ispresent(attach_accept.emergencyNumberList)) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Expected emergency number IE.")); + } + enl_tlv := attach_accept.emergencyNumberList; + if (lengthof(enl_tlv.emergencyNumberList) != g_pars.emerg_pars.numbers) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unpected emergency number list entries: ", + lengthof(enl_tlv.emergencyNumberList))); + } + for (var integer i := 0; i < g_pars.emerg_pars.numbers; i := i + 1) { + var BIT5 categories := enl_tlv.emergencyNumberList[i].emergencyServiceCategoryValue; + var octetstring digits := enl_tlv.emergencyNumberList[i].emergencyNumberDigits; + if (categories != g_pars.emerg_pars.categories[i]) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected emergency categories: ", + categories)); + } + if (digits != g_pars.emerg_pars.digits[i]) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected emergency digits: ", digits)); + } + } + }
rab_setup_it := ts_S1AP_RABSetupItemCtxtSURes(rab_id := 5, tla := oct2bit(f_inet_addr(g_pars.enb_pars[g_pars.mme_idx].gtp1u_local_ip)), diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn index 18740bf..df24a09 100644 --- a/mme/MME_Tests.ttcn +++ b/mme/MME_Tests.ttcn @@ -54,6 +54,7 @@ import from ConnHdlr all;
friend module MME_Tests_SGsAP; +friend module MME_Tests_emergency;
/* (maximum) number of emulated UEs */ const integer NUM_UE := 3; @@ -334,6 +335,7 @@ /* generate parameters for a connection handler */ friend function f_init_pars(integer ue_idx := 0) runs on MTC_CT return ConnHdlrPars { + var integer i; var ConnHdlrPars pars := { enb_pars := g_enb_pars, hss_pars := { @@ -357,8 +359,20 @@ }, ue_pars := g_ue_pars[ue_idx], mme_idx := 0, - kset_id := valueof(ts_NAS_KeySetIdentifierV('000'B, c_NAS_TSC_NATIVE_SEC_CTX)) + kset_id := valueof(ts_NAS_KeySetIdentifierV('000'B, c_NAS_TSC_NATIVE_SEC_CTX)), + emerg_pars := { + expect_s1_emergency := false, + s1_emergency := '0'B, + expect_number := false, + numbers := 0 + } }; + for (i := 0; i < sizeof(pars.emerg_pars.categories); i := i + 1) { + pars.emerg_pars.categories[i] := '00000'B; + } + for (i := 0; i < sizeof(pars.emerg_pars.digits); i := i + 1) { + pars.emerg_pars.digits[i] := ''O; + } return pars; }
@@ -787,6 +801,21 @@ vc_conn.done; }
+private function f_TC_attach_no_emergency() runs on ConnHdlr { + f_attach(); +} +testcase TC_s1ap_attach_no_emergency() runs on MTC_CT { + f_init(8, init_diameter := true, init_gtpv2c_s11 := true); + f_s1ap_setup(0); + + var ConnHdlrPars pars := f_init_pars(ue_idx := 0); + var ConnHdlr vc_conn; + pars.emerg_pars.expect_s1_emergency := true; + pars.emerg_pars.s1_emergency := '0'B; + vc_conn := f_start_handler_with_pars(refers(f_TC_attach_no_emergency), pars); + vc_conn.done; +} + control { execute( TC_s1ap_setup_unknown_global_enb_id_plmn() ); execute( TC_s1ap_setup_wrong_tac() ); @@ -799,6 +828,7 @@ execute( TC_s1ap_reset() ); execute( TC_ue_cell_reselect_eutran_to_geran() ); execute( TC_ue_cell_reselect_geran_to_eutran() ); + execute( TC_s1ap_attach_no_emergency() ); }
diff --git a/mme/MME_Tests_emergency.ttcn b/mme/MME_Tests_emergency.ttcn new file mode 100644 index 0000000..a0cae54 --- /dev/null +++ b/mme/MME_Tests_emergency.ttcn @@ -0,0 +1,65 @@ +module MME_Tests_emergency { + +/* Osmocom MME test suite in in TTCN-3, SGsAP related procedures (3GPP TS 29.118, 3GPP TS 23.272) + * (C) 2025 Andreas Eversberg aeversberg@sysmocom.de + * 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 General_Types all; +import from Osmocom_Types all; +import from Misc_Helpers all; +import from L3_Templates all; +import from DNS_Helpers all; +import from MME_Tests all; + +import from NAS_EPS_Templates all; + +import from ConnHdlr all; + +private function f_TC_emergency_supported() runs on ConnHdlr { + f_attach(); +} +testcase TC_emergency_supported() runs on MTC_CT { + f_init(4, init_diameter := true, init_gtpv2c_s11 := true); + f_s1ap_setup(0); + + var ConnHdlrPars pars := f_init_pars(ue_idx := 0); + var ConnHdlr vc_conn; + pars.emerg_pars.expect_s1_emergency := true; + pars.emerg_pars.s1_emergency := '1'B; + vc_conn := f_start_handler_with_pars(refers(f_TC_emergency_supported), pars); + vc_conn.done; +} + +private function f_TC_emergency_number_included() runs on ConnHdlr { + f_attach(); +} +testcase TC_emergency_number_included() runs on MTC_CT { + f_init(4, init_diameter := true, init_gtpv2c_s11 := true); + f_s1ap_setup(0); + + var ConnHdlrPars pars := f_init_pars(ue_idx := 0); + var ConnHdlr vc_conn; + pars.emerg_pars.expect_s1_emergency := true; + pars.emerg_pars.s1_emergency := '1'B; + pars.emerg_pars.expect_number := true; + pars.emerg_pars.numbers := 2; + pars.emerg_pars.categories[0] := '00001'B; /* police */ + pars.emerg_pars.digits[0] := '11F0'O; /* 110 */ + pars.emerg_pars.categories[1] := '00110'B; /* fire + ambulance */ + pars.emerg_pars.digits[1] := '11F2'O; /* 112 */ + vc_conn := f_start_handler_with_pars(refers(f_TC_emergency_number_included), pars); + vc_conn.done; +} + +control { + execute( TC_emergency_supported() ); + execute( TC_emergency_number_included() ); +} + +} diff --git a/mme/expected-results.xml b/mme/expected-results.xml index 694b119..c420315 100644 --- a/mme/expected-results.xml +++ b/mme/expected-results.xml @@ -11,10 +11,13 @@ <testcase classname='MME_Tests' name='TC_s1ap_reset' time='MASKED'/> <testcase classname='MME_Tests' name='TC_ue_cell_reselect_eutran_to_geran' time='MASKED'/> <testcase classname='MME_Tests' name='TC_ue_cell_reselect_geran_to_eutran' time='MASKED'/> + <testcase classname='MME_Tests' name='TC_s1ap_attach_no_emergency' time='MASKED'/> <testcase classname='MME_Tests_SGsAP' name='TC_sgsap_vlr_reset' time='MASKED'/> <testcase classname='MME_Tests_SGsAP' name='TC_sgsap_paging_sms' time='MASKED'/> <testcase classname='MME_Tests_SGsAP' name='TC_sgsap_paging_cs' time='MASKED'/> <testcase classname='MME_Tests_SGsAP' name='TC_sgsap_paging_reject' time='MASKED'/> <testcase classname='MME_Tests_SGsAP' name='TC_sgsap_alert' time='MASKED'/> <testcase classname='MME_Tests_SGsAP' name='TC_sgsap_alert_rej' time='MASKED'/> + <testcase classname='MME_Tests_emergency' name='TC_emergency_supported' time='MASKED'/> + <testcase classname='MME_Tests_emergency' name='TC_emergency_number_included' time='MASKED'/> </testsuite> diff --git a/mme/open5gs-mme_emergency.yaml b/mme/open5gs-mme_emergency.yaml new file mode 100644 index 0000000..5675599 --- /dev/null +++ b/mme/open5gs-mme_emergency.yaml @@ -0,0 +1,80 @@ +# See https://github.com/open5gs/open5gs/blob/main/configs/open5gs/mme.yaml.in + +logger: + level: debug + +global: + max: + ue: 1024 + +mme: + freeDiameter: freediameter.conf + s1ap: + server: + - address: 127.0.0.201 + gtpc: + server: + - address: 127.0.0.201 + client: + sgwc: + - address: 127.0.0.202 + smf: + - address: 127.0.0.201 + - address: ::1 + sgsn: + - address: + - 127.0.0.202 + port: 2124 + routes: + - rai: + lai: + plmn_id: + mcc: 262 + mnc: 42 + lac: 39594 + rac: 187 + ci: 1223 + metrics: + server: + - address: 127.0.0.201 + port: 9090 + gummei: + - plmn_id: + mcc: 001 + mnc: 01 + mme_gid: 2 + mme_code: 1 + tai: + - plmn_id: + mcc: 001 + mnc: 01 + tac: 12345 + security: + integrity_order : [ EIA2, EIA1, EIA0 ] + ciphering_order : [ EEA0, EEA1, EEA2 ] + network_name: + full: Open5GS + mme_name: open5gs-mme0 + sgsap: + client: + - address: 127.0.0.202 # SCTP server address configured on the MSC/VLR + local_address: 127.0.0.201 # SCTP local IP addresses to be bound in the MME + map: + tai: + plmn_id: + mcc: 001 + mnc: 01 + tac: 12345 + lai: + plmn_id: + mcc: 001 + mnc: 01 + lac: 43691 + emergency: + dnn: test.sos + number: + - digits: 110 + categories: police + number: + - digits: 112 + categories: [ fire, ambulance ] diff --git a/mme/testenv_emergency.cfg b/mme/testenv_emergency.cfg new file mode 100644 index 0000000..4c1ff91 --- /dev/null +++ b/mme/testenv_emergency.cfg @@ -0,0 +1,10 @@ +[testsuite] +titan_min=11.1.0 +program=MME_Tests +config=MME_Tests_emergency.cfg + +[mme] +program=open5gs-mmed -c open5gs-mme_emergency.yaml +make=open5gs +package=open5gs-mme +copy=open5gs-mme_emergency.yaml freediameter.conf diff --git a/mme/testenv.cfg b/mme/testenv_generic.cfg similarity index 100% rename from mme/testenv.cfg rename to mme/testenv_generic.cfg