pespin submitted this change.
Introduce udm testsuite
Introduce a new "udm" testsuite which runs against open5gs-udmd.
Start with a couple tests which already contains most of the
infrastructure needed and makes it easy to extend later on.
Related: SYS#7073
Change-Id: Ia9a2a055ee81c889de00ef86f8562425862ea5e3
---
M Makefile
A library/TS29503_Nudm_UEAU_Templates.ttcn
A library/TS29505_Subscription_Data_Templates.ttcn
M library/TS29571_CommonData_Templates.ttcn
M smf/gen_links.sh
A udm/ConnHdlr.ttcn
A udm/README.md
A udm/UDM_Tests.cfg
A udm/UDM_Tests.default
A udm/UDM_Tests.ttcn
A udm/create_test_subscribers.sh
A udm/expected-results.xml
A udm/gen_links.sh
A udm/mongod.conf
A udm/open5gs-udm.yaml
A udm/open5gs_prepare.sh
A udm/regen_makefile.sh
A udm/testenv.cfg
A udm/testsrcdir.cfg
19 files changed, 1,184 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index b15ec40..87adb6d 100644
--- a/Makefile
+++ b/Makefile
@@ -55,6 +55,7 @@
smdpp \
stp \
sysinfo \
+ udm \
upf \
$(NULL)
diff --git a/library/TS29503_Nudm_UEAU_Templates.ttcn b/library/TS29503_Nudm_UEAU_Templates.ttcn
new file mode 100644
index 0000000..d1f9f50
--- /dev/null
+++ b/library/TS29503_Nudm_UEAU_Templates.ttcn
@@ -0,0 +1,200 @@
+module TS29503_Nudm_UEAU_Templates {
+
+import from TS29503_Nudm_UEAU all;
+import from TS29571_CommonData_Templates all;
+
+const charstring c_Nudm_UEAU_path_api_prefix := "/nudm-ueau/v1";
+
+/* 6.3.3.2 Resource: SecurityInformation */
+template (value) charstring
+ts_Nudm_UEAU_path_security_information(template (value) charstring imsi)
+:= c_Nudm_UEAU_path_api_prefix & "/" & valueof(ts_sbi_Supi(imsi)) & "/security-information";
+
+/* 6.3.3.2.4.2 Operation: generate-auth-data */
+template (present) charstring
+tr_Nudm_UEAU_path_generate_auth_data(template (present) charstring imsi := pattern "\d+")
+:= pattern c_Nudm_UEAU_path_api_prefix & "/imsi-" & imsi & "/security-information/generate-auth-data";
+template (value) charstring
+ts_Nudm_UEAU_path_generate_auth_data(template (value) charstring imsi)
+:= valueof(ts_Nudm_UEAU_path_security_information(imsi)) & "/generate-auth-data";
+
+/* 6.3.3.3 Resource: AuthEvents */
+template (present) charstring
+tr_Nudm_UEAU_path_auth_events(template (value) charstring imsi)
+:= pattern c_Nudm_UEAU_path_api_prefix & "/imsi-" & imsi & "/auth-events";
+template (value) charstring
+ts_Nudm_UEAU_path_auth_events(template (value) charstring imsi)
+:= c_Nudm_UEAU_path_api_prefix & "/" & valueof(ts_sbi_Supi(imsi)) & "/auth-events";
+
+/* 6.3.3.6 Resource: Individual AuthEvent */
+template (value) charstring
+ts_Nudm_UEAU_path_indivdual_auth_event(template (value) charstring imsi,
+ template (value) charstring auth_event_id)
+:= valueof(ts_Nudm_UEAU_path_auth_events(imsi)) & "/" & valueof(auth_event_id);
+
+template (value) AuthType1
+ts_AuthType1(AuthType1_enum enum_val) := {
+ enum_val := enum_val
+}
+
+template (value) AvType1
+ts_AvType1(AvType1_enum enum_val) := {
+ enum_val := enum_val
+}
+
+template (value) Av5GHeAka1
+ts_Av5GHeAka1(template (value) AvType1 avType,
+ template (value) Rand1 rand,
+ template (value) XresStar1 xresStar,
+ template (value) Autn1 autn,
+ template (value) Kausf1 kausf) := {
+ avType := avType,
+ rand := rand,
+ xresStar := xresStar,
+ autn := autn,
+ kausf := kausf
+}
+
+template (value) AuthenticationVector1
+ts_AuthenticationVector1_5GHeAka(template (value) Av5GHeAka1 aka) := {
+ field2 := aka
+}
+
+template (present) AuthenticationInfoRequest1
+tr_AuthenticationInfoRequest1(template SupportedFeatures1 supportedFeatures := *,
+ template (present) ServingNetworkName1 servingNetworkName := ?,
+ template ResynchronizationInfo2 resynchronizationInfo := *,
+ template (present) NfInstanceId1 ausfInstanceId := ?,
+ template record of CagId1 cellCagInfo := *,
+ template boolean n5gcInd := *,
+ template boolean nswoInd := *,
+ template boolean disasterRoamingInd := *,
+ template boolean aun3Ind := *) := {
+ supportedFeatures := supportedFeatures,
+ servingNetworkName := servingNetworkName,
+ resynchronizationInfo := resynchronizationInfo,
+ ausfInstanceId := ausfInstanceId,
+ cellCagInfo := cellCagInfo,
+ n5gcInd := n5gcInd,
+ nswoInd := nswoInd,
+ disasterRoamingInd := disasterRoamingInd,
+ aun3Ind := aun3Ind
+}
+template (value) AuthenticationInfoRequest1
+ts_AuthenticationInfoRequest1(template (omit) SupportedFeatures1 supportedFeatures := omit,
+ template (value) ServingNetworkName1 servingNetworkName,
+ template (omit) ResynchronizationInfo2 resynchronizationInfo := omit,
+ template (value) NfInstanceId1 ausfInstanceId,
+ template (omit) record of CagId1 cellCagInfo := omit,
+ template (omit) boolean n5gcInd := omit,
+ template (omit) boolean nswoInd := omit,
+ template (omit) boolean disasterRoamingInd := omit,
+ template (omit) boolean aun3Ind := omit) := {
+ supportedFeatures := supportedFeatures,
+ servingNetworkName := servingNetworkName,
+ resynchronizationInfo := resynchronizationInfo,
+ ausfInstanceId := ausfInstanceId,
+ cellCagInfo := cellCagInfo,
+ n5gcInd := n5gcInd,
+ nswoInd := nswoInd,
+ disasterRoamingInd := disasterRoamingInd,
+ aun3Ind := aun3Ind
+}
+
+type TS29503_Nudm_UEAU.AuthenticationInfoResult1.pvsInfo ServerAddressingInfo1List;
+template (present) AuthenticationInfoResult1
+tr_AuthenticationInfoResult1(template (present) AuthType1 authType := ?,
+ template SupportedFeatures1 supportedFeatures := *,
+ template AuthenticationVector1 authenticationVector := *,
+ template Supi1 supi := *,
+ template boolean akmaInd := *,
+ template boolean authAaa := *,
+ template charstring routingId := *,
+ template ServerAddressingInfo1List pvsInfo := *,
+ template boolean mskInd := *) := {
+ authType := authType,
+ supportedFeatures := supportedFeatures,
+ authenticationVector := authenticationVector,
+ supi := supi,
+ akmaInd := akmaInd,
+ authAaa := authAaa,
+ routingId := routingId,
+ pvsInfo := pvsInfo,
+ mskInd := mskInd
+}
+template (value) AuthenticationInfoResult1
+ts_AuthenticationInfoResult1(template (value) AuthType1 authType,
+ template (omit) SupportedFeatures1 supportedFeatures := omit,
+ template (omit) AuthenticationVector1 authenticationVector := omit,
+ template (omit) Supi1 supi := omit,
+ template (omit) boolean akmaInd := omit,
+ template (omit) boolean authAaa := omit,
+ template (omit) charstring routingId := omit,
+ template (omit) ServerAddressingInfo1List pvsInfo := omit,
+ template (omit) boolean mskInd := omit) := {
+ authType := authType,
+ supportedFeatures := supportedFeatures,
+ authenticationVector := authenticationVector,
+ supi := supi,
+ akmaInd := akmaInd,
+ authAaa := authAaa,
+ routingId := routingId,
+ pvsInfo := pvsInfo,
+ mskInd := mskInd
+}
+
+template (value) AuthEvent1
+ts_AuthEvent1(template (value) NfInstanceId1 nfInstanceId,
+ template (value) Success1 success,
+ template (value) DateTime1 timeStamp,
+ template (value) AuthType1 authType,
+ template (value) ServingNetworkName1 servingNetworkName,
+ template (omit) boolean authRemovalInd := omit,
+ template (omit) NfSetId1 nfSetId := omit,
+ template (omit) record of charstring resetIds := omit,
+ template (omit) Uri1 dataRestorationCallbackUri := omit,
+ template (omit) boolean udrRestartInd := omit,
+ template (omit) DateTime1 lastSynchronizationTime := omit,
+ template (omit) boolean nswoInd := omit) := {
+ nfInstanceId := nfInstanceId,
+ success := success,
+ timeStamp := timeStamp,
+ authType := authType,
+ servingNetworkName := servingNetworkName,
+ authRemovalInd := authRemovalInd,
+ nfSetId := nfSetId,
+ resetIds := resetIds,
+ dataRestorationCallbackUri := dataRestorationCallbackUri,
+ udrRestartInd := udrRestartInd,
+ lastSynchronizationTime := lastSynchronizationTime,
+ nswoInd := nswoInd
+}
+
+template (present) AuthEvent1
+tr_AuthEvent1(template (present) NfInstanceId1 nfInstanceId := ?,
+ template (present) Success1 success := ?,
+ template (present) DateTime1 timeStamp := ?,
+ template (present) AuthType1 authType := ?,
+ template (present) ServingNetworkName1 servingNetworkName := ?,
+ template boolean authRemovalInd := *,
+ template NfSetId1 nfSetId := *,
+ template record of charstring resetIds := *,
+ template Uri1 dataRestorationCallbackUri := *,
+ template boolean udrRestartInd := *,
+ template DateTime1 lastSynchronizationTime := *,
+ template boolean nswoInd := *) := {
+ nfInstanceId := nfInstanceId,
+ success := success,
+ timeStamp := timeStamp,
+ authType := authType,
+ servingNetworkName := servingNetworkName,
+ authRemovalInd := authRemovalInd,
+ nfSetId := nfSetId,
+ resetIds := resetIds,
+ dataRestorationCallbackUri := dataRestorationCallbackUri,
+ udrRestartInd := udrRestartInd,
+ lastSynchronizationTime := lastSynchronizationTime,
+ nswoInd := nswoInd
+}
+
+}
diff --git a/library/TS29505_Subscription_Data_Templates.ttcn b/library/TS29505_Subscription_Data_Templates.ttcn
new file mode 100644
index 0000000..85912fb
--- /dev/null
+++ b/library/TS29505_Subscription_Data_Templates.ttcn
@@ -0,0 +1,163 @@
+module TS29505_Subscription_Data_Templates {
+
+import from TS29505_Subscription_Data all;
+
+const charstring c_Nudr_DR_path_api_prefix := "/nudr-dr/v1";
+
+template (present) charstring
+tr_Nudr_DR_path_authentication_subscription(template (present) charstring imsi := pattern "\d+")
+:= pattern c_Nudr_DR_path_api_prefix & "/subscription-data/imsi-" & imsi & "/authentication-data/authentication-subscription";
+
+/* 3GPP TS 29.505 5.2.24.2 */
+template (present) charstring
+tr_Nudr_DR_path_authentication_status(template (present) charstring imsi := pattern "\d+")
+:= pattern c_Nudr_DR_path_api_prefix & "/subscription-data/imsi-" & imsi & "/authentication-data/authentication-status";
+
+template (value) AuthMethod
+ts_AuthMethod(AuthMethod_enum enum_val) := {
+ enum_val := enum_val
+}
+
+template (present) AuthenticationSubscription
+tr_AuthenticationSubscription(template (present) AuthMethod authenticationMethod := ?,
+ template charstring encPermanentKey := *,
+ template charstring protectionParameterId := *,
+ template SequenceNumber sequenceNumber := *,
+ template charstring authenticationManagementField := *,
+ template charstring algorithmId := *,
+ template charstring encOpcKey := *,
+ template charstring encTopcKey := *,
+ template boolean vectorGenerationInHss := *,
+ template NfGroupId hssGroupId := *,
+ template AuthMethod n5gcAuthMethod := *,
+ template boolean rgAuthenticationInd := *,
+ template Supi supi := *,
+ template boolean akmaAllowed := *,
+ template charstring routingId := *,
+ template boolean nswoAllowed := *,
+ template boolean fivegKeyHierarSupp := *) := {
+ authenticationMethod := authenticationMethod,
+ encPermanentKey := encPermanentKey,
+ protectionParameterId := protectionParameterId,
+ sequenceNumber := sequenceNumber,
+ authenticationManagementField := authenticationManagementField,
+ algorithmId := algorithmId,
+ encOpcKey := encOpcKey,
+ encTopcKey := encTopcKey,
+ vectorGenerationInHss := vectorGenerationInHss,
+ hssGroupId := hssGroupId,
+ n5gcAuthMethod := n5gcAuthMethod,
+ rgAuthenticationInd := rgAuthenticationInd,
+ supi := supi,
+ akmaAllowed := akmaAllowed,
+ routingId := routingId,
+ nswoAllowed := nswoAllowed,
+ fivegKeyHierarSupp := fivegKeyHierarSupp
+}
+
+template (value) AuthenticationSubscription
+ts_AuthenticationSubscription(template (value) AuthMethod authenticationMethod,
+ template (omit) charstring encPermanentKey := omit,
+ template (omit) charstring protectionParameterId := omit,
+ template (omit) SequenceNumber sequenceNumber := omit,
+ template (omit) charstring authenticationManagementField := omit,
+ template (omit) charstring algorithmId := omit,
+ template (omit) charstring encOpcKey := omit,
+ template (omit) charstring encTopcKey := omit,
+ template (omit) boolean vectorGenerationInHss := omit,
+ template (omit) NfGroupId hssGroupId := omit,
+ template (omit) AuthMethod n5gcAuthMethod := omit,
+ template (omit) boolean rgAuthenticationInd := omit,
+ template (omit) Supi supi := omit,
+ template (omit) boolean akmaAllowed := omit,
+ template (omit) charstring routingId := omit,
+ template (omit) boolean nswoAllowed := omit,
+ template (omit) boolean fivegKeyHierarSupp := omit) := {
+ authenticationMethod := authenticationMethod,
+ encPermanentKey := encPermanentKey,
+ protectionParameterId := protectionParameterId,
+ sequenceNumber := sequenceNumber,
+ authenticationManagementField := authenticationManagementField,
+ algorithmId := algorithmId,
+ encOpcKey := encOpcKey,
+ encTopcKey := encTopcKey,
+ vectorGenerationInHss := vectorGenerationInHss,
+ hssGroupId := hssGroupId,
+ n5gcAuthMethod := n5gcAuthMethod,
+ rgAuthenticationInd := rgAuthenticationInd,
+ supi := supi,
+ akmaAllowed := akmaAllowed,
+ routingId := routingId,
+ nswoAllowed := nswoAllowed,
+ fivegKeyHierarSupp := fivegKeyHierarSupp
+}
+
+type TS29505_Subscription_Data.SequenceNumber.lastIndexes SequenceNumberIndexesMap;
+template (value) SequenceNumber
+ts_SequenceNumber(template (omit) SqnScheme sqnScheme := omit,
+ template (omit) charstring sqn := omit,
+ template (omit) SequenceNumberIndexesMap lastIndexes := omit,
+ template (omit) integer indLength := omit,
+ template (omit) Sign difSign := omit) := {
+ sqnScheme := sqnScheme,
+ sqn := sqn,
+ lastIndexes := lastIndexes,
+ indLength := indLength,
+ difSign := difSign
+}
+
+template (value) AuthEvent
+ts_AuthEvent(template (value) NfInstanceId nfInstanceId,
+ template (value) Success success,
+ template (value) DateTime timeStamp,
+ template (value) AuthType authType,
+ template (value) ServingNetworkName servingNetworkName,
+ template (omit) boolean authRemovalInd := omit,
+ template (omit) NfSetId nfSetId := omit,
+ template (omit) record of charstring resetIds := omit,
+ template (omit) Uri dataRestorationCallbackUri := omit,
+ template (omit) boolean udrRestartInd := omit,
+ template (omit) DateTime lastSynchronizationTime := omit,
+ template (omit) boolean nswoInd := omit) := {
+ nfInstanceId := nfInstanceId,
+ success := success,
+ timeStamp := timeStamp,
+ authType := authType,
+ servingNetworkName := servingNetworkName,
+ authRemovalInd := authRemovalInd,
+ nfSetId := nfSetId,
+ resetIds := resetIds,
+ dataRestorationCallbackUri := dataRestorationCallbackUri,
+ udrRestartInd := udrRestartInd,
+ lastSynchronizationTime := lastSynchronizationTime,
+ nswoInd := nswoInd
+}
+
+template (present) AuthEvent
+tr_AuthEvent(template (present) NfInstanceId nfInstanceId := ?,
+ template (present) Success success := ?,
+ template (present) DateTime timeStamp := ?,
+ template (present) AuthType authType := ?,
+ template (present) ServingNetworkName servingNetworkName := ?,
+ template boolean authRemovalInd := *,
+ template NfSetId nfSetId := *,
+ template record of charstring resetIds := *,
+ template Uri dataRestorationCallbackUri := *,
+ template boolean udrRestartInd := *,
+ template DateTime lastSynchronizationTime := *,
+ template boolean nswoInd := *) := {
+ nfInstanceId := nfInstanceId,
+ success := success,
+ timeStamp := timeStamp,
+ authType := authType,
+ servingNetworkName := servingNetworkName,
+ authRemovalInd := authRemovalInd,
+ nfSetId := nfSetId,
+ resetIds := resetIds,
+ dataRestorationCallbackUri := dataRestorationCallbackUri,
+ udrRestartInd := udrRestartInd,
+ lastSynchronizationTime := lastSynchronizationTime,
+ nswoInd := nswoInd
+}
+
+}
diff --git a/library/TS29571_CommonData_Templates.ttcn b/library/TS29571_CommonData_Templates.ttcn
index 7accd38..371b669 100644
--- a/library/TS29571_CommonData_Templates.ttcn
+++ b/library/TS29571_CommonData_Templates.ttcn
@@ -2,6 +2,10 @@
import from TS29571_CommonData all;
+/* 3GPP TS 29.571 Table 5.3.2-1 Supi from "SupiOrSuci": */
+template (value) charstring
+ts_sbi_Supi(template (value) charstring imsi) := "imsi-" & valueof(imsi);
+
template (value) PlmnIdNid
ts_PlmnIdNid(template (value) Mcc mcc,
template (value) Mnc mnc,
diff --git a/smf/gen_links.sh b/smf/gen_links.sh
index 7b7e678..084e7ca 100755
--- a/smf/gen_links.sh
+++ b/smf/gen_links.sh
@@ -64,6 +64,7 @@
FILES="HTTPmsg_MessageLen.ttcn HTTPmsg_MessageLen_Function.cc HTTPmsg_PT.cc HTTPmsg_PT.hh HTTPmsg_PortType.ttcn HTTPmsg_Types.ttcn "
gen_links $DIR $FILES
+# Needed by HTTP2_Adapter:
DIR=$BASEDIR/titan.ProtocolModules.HTTP2/src
FILES="HTTP2_EncDec.cc HTTP2_Types.ttcn"
gen_links $DIR $FILES
diff --git a/udm/ConnHdlr.ttcn b/udm/ConnHdlr.ttcn
new file mode 100644
index 0000000..89bc0d9
--- /dev/null
+++ b/udm/ConnHdlr.ttcn
@@ -0,0 +1,386 @@
+/* UDM test suite in TTCN-3 (3GPP TS 29.503), ConnHdlr
+ * (C) 2026 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All rights reserved.
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ *
+ * 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 ConnHdlr {
+
+import from TCCEncoding_Functions all;
+
+import from General_Types all;
+import from Native_Functions all;
+import from IPL4asp_Types all;
+import from Misc_Helpers all;
+
+import from Osmocom_Types all;
+import from GSM_Types all;
+
+import from HTTP2_Types all;
+import from HTTP2_Templates all;
+import from HTTP2_Functions all;
+import from HTTP2_Msg all;
+import from HTTP2_Adapter all;
+import from HTTP2_Server_Emulation all;
+
+import from Prometheus_Checker all;
+
+import from TS29503_Nudm_UEAU all;
+import from TS29503_Nudm_UEAU_Templates all;
+import from TS29505_Subscription_Data all;
+import from TS29505_Subscription_Data_Templates all;
+
+import from UDM_Tests all;
+
+const integer HTTP2_CONN_SCP := 0;
+
+/* These are a preset of path matches which can be applied through the entire lifecycle of the session: */
+function f_http2_server_path_match()
+runs on ConnHdlr return charstring {
+ var charstring imsi_match := "*imsi-" & g_pars.imsi_str & "*";
+ return imsi_match;
+}
+
+type record ConnHdlrPars {
+ hexstring imsi,
+ charstring imsi_str,
+ charstring serving_network,
+ NfInstanceId1 ausf_instance_id,
+ charstring nudm_ueau_auth_event_id optional
+}
+
+type component ConnHdlr extends HTTP2_CT, HTTP2_ConnHdlr, Prometheus_Checker_CT {
+ var ConnHdlrPars g_pars;
+}
+
+type function void_fn() runs on ConnHdlr;
+
+function f_ConnHdlrPars(integer idx := 0) return ConnHdlrPars
+{
+ var hexstring imsi := f_concat_pad(lengthof(mp_imsi), substr(mp_imsi, 0, lengthof(mp_imsi) - 6), idx);
+ var charstring imsi_str := f_dec_TBCD(imsi_hex2oct(imsi));
+ var template (value) ConnHdlrPars pars := {
+ imsi := imsi,
+ imsi_str := imsi_str,
+ serving_network := "5G:mnc070.mcc999.3gppnetwork.org", /* TODO: set based on mp_mcc and mp_mnc */
+ ausf_instance_id := "ausf-instance-id-" & int2str(idx),
+ nudm_ueau_auth_event_id := omit
+ };
+ return valueof(pars);
+}
+
+function f_ConnHdlr_init(void_fn fn, ConnHdlrPars pars) runs on ConnHdlr {
+ /* make parameters available via component variable */
+ g_pars := pars;
+
+ /* Setup */
+ /* Register SCP HTTP2 sever, where IUT will send all SBI requests: */
+ f_http2_server_emu_register(f_http2_server_path_match(), idx := HTTP2_CONN_SCP);
+ f_http2_adapter_init();
+
+ fn.apply();
+
+ /* Cleanup */
+ f_http2_server_emu_unregister(f_http2_server_path_match(), idx := HTTP2_CONN_SCP);
+}
+
+/********************************************
+ * SCP
+/*******************************************/
+const charstring SCP_uri_hostport := mp_scp_local_ip & ":" & int2str(mp_scp_local_port);
+const charstring SCP_uri_prefix := "http://" & SCP_uri_hostport;
+
+/****************************************************
+ * N13 Nudm_UEAU (SBI): Emulated AUSF, 3GPP TS 29.503
+ ****************************************************/
+const charstring Nudm_uri_hostport := mp_udm_hostname & ":" & int2str(mp_udm_sbi_port);
+const charstring Nudm_uri_prefix := "http://" & Nudm_uri_hostport;
+
+/* 3GPP TS 29.503 6.3.3.2.4.2 Operation: generate-auth-data */
+private function f_n13_prepare_generate_auth_data(AuthenticationInfoRequest1 aut_info_req)
+runs on ConnHdlr return HTTP2_Msg {
+ var octetstring aut_info_req_enc;
+ var integer http2_idx;
+ var integer http2_stream_id;
+ var template (value) HTTP2_Msg http2_tx;
+
+ aut_info_req_enc := f_enc_AuthenticationInfoRequest1(aut_info_req);
+
+ http2_idx := f_http2_adapter_find_free_idx();
+ http2_stream_id := f_http2_adapter_next_stream_id(http2_idx);
+ http2_tx := ts_HTTP2_Msg(http2_idx,
+ http2_stream_id,
+ hb := {
+ pseudo_headers := ts_HTTP2_pseudo_headers_Req(method := "POST",
+ scheme := "http",
+ authority := Nudm_uri_hostport,
+ path := ts_Nudm_UEAU_path_generate_auth_data(g_pars.imsi_str)),
+ headers := {
+ ts_HTTP2_Hdr_content_type("application/json"),
+ ts_HTTP2_Hdr_accept("application/json"),
+ ts_HTTP2_Hdr_user_agent("ttcn3-ausf"),
+ ts_HTTP2_Hdr_accept_encoding("gzip")
+ }
+ },
+ body := ts_HTTP2_Data_frame(http2_stream_id,
+ end_stream_flag := true,
+ data := aut_info_req_enc));
+ return valueof(http2_tx);
+}
+
+/* 3GPP TS 29.503 6.3.3.2.4.2 Operation: generate-auth-data */
+function f_n13_generate_auth_data()
+runs on ConnHdlr {
+ var HTTP2_Msg http2_tx;
+ var HTTP2_Msg http2_rx;
+ var template (present) HTTP2_Msg http2_exp_rx;
+ var template (value) AuthenticationInfoRequest1 auth_info_req;
+
+ auth_info_req := ts_AuthenticationInfoRequest1(servingNetworkName := g_pars.serving_network,
+ ausfInstanceId := g_pars.ausf_instance_id);
+
+ http2_tx := f_n13_prepare_generate_auth_data(valueof(auth_info_req));
+ f_http2_adapter_connect(mp_udm_hostname, mp_udm_sbi_port, mp_ausf_local_ip, idx := http2_tx.conn_id);
+ f_http2_adapter_send(http2_tx);
+
+ as_Nudr_DR_get_authentication_subscription();
+
+ /* 3GPP TS 29.503 Table 6.3.3.2.4.2.2-2 */
+ http2_exp_rx :=
+ tr_HTTP2_Msg(http2_tx.conn_id,
+ http2_tx.stream_id,
+ tr_HTTP2_header_block(pseudo_headers := tr_HTTP2_pseudo_headers_Resp(200)),
+ tr_HTTP2_Data_frame(stream_id := http2_tx.stream_id,
+ end_stream_flag := true,
+ data := decmatch tr_AuthenticationInfoResult1));
+ as_http2_adapter_receive(http2_rx, http2_exp_rx, idx := http2_tx.conn_id);
+
+ f_http2_adapter_close(idx := http2_tx.conn_id);
+ setverdict(pass);
+}
+
+/* 3GPP TS 29.503 6.3.3.3.3.1 Resource: AuthEvents (POST) */
+private function f_n13_prepare_auth_events(AuthEvent1 auth_event)
+runs on ConnHdlr return HTTP2_Msg {
+ var octetstring auth_event_enc;
+ var integer http2_idx;
+ var integer http2_stream_id;
+ var template (value) HTTP2_Msg http2_tx;
+
+ auth_event_enc := f_enc_AuthEvent1(auth_event);
+
+ http2_idx := f_http2_adapter_find_free_idx();
+ http2_stream_id := f_http2_adapter_next_stream_id(http2_idx);
+ http2_tx := ts_HTTP2_Msg(http2_idx,
+ http2_stream_id,
+ hb := {
+ pseudo_headers := ts_HTTP2_pseudo_headers_Req(method := "POST",
+ scheme := "http",
+ authority := Nudm_uri_hostport,
+ path := ts_Nudm_UEAU_path_auth_events(g_pars.imsi_str)),
+ headers := {
+ ts_HTTP2_Hdr_content_type("application/json"),
+ ts_HTTP2_Hdr_accept("application/json"),
+ ts_HTTP2_Hdr_user_agent("ttcn3-ausf"),
+ ts_HTTP2_Hdr_accept_encoding("gzip")
+ }
+ },
+ body := ts_HTTP2_Data_frame(http2_stream_id,
+ end_stream_flag := true,
+ data := auth_event_enc));
+ return valueof(http2_tx);
+}
+
+/* 3GPP TS 29.503 5.4.2.3.2 Authentication Confirmation */
+function f_n13_authentication_confirmation()
+runs on ConnHdlr {
+ var HTTP2_Msg http2_tx;
+ var HTTP2_Msg http2_rx;
+ var template (present) HTTP2_Msg http2_exp_rx;
+ var template (value) AuthEvent1 auth_event;
+
+ auth_event := ts_AuthEvent1(nfInstanceId := g_pars.ausf_instance_id,
+ success := true,
+ timeStamp := "2026-10-20T11:58:44.069417+00:00", /* TODO: generate the now() timestamp string */
+ authType := ts_AuthType1(FiveG_AKA),
+ servingNetworkName := g_pars.serving_network);
+
+ http2_tx := f_n13_prepare_auth_events(valueof(auth_event));
+ f_http2_adapter_connect(mp_udm_hostname, mp_udm_sbi_port, mp_ausf_local_ip, idx := http2_tx.conn_id);
+ f_http2_adapter_send(http2_tx);
+
+ as_Nudr_DR_put_authentication_status();
+
+ /* 3GPP TS 29.503 Table 6.3.3.3.3.1-3 */
+ http2_exp_rx :=
+ tr_HTTP2_Msg(http2_tx.conn_id,
+ http2_tx.stream_id,
+ tr_HTTP2_header_block(pseudo_headers := tr_HTTP2_pseudo_headers_Resp(201)),
+ tr_HTTP2_Data_frame(stream_id := http2_tx.stream_id,
+ end_stream_flag := true,
+ data := decmatch tr_AuthEvent1) ifpresent);
+ as_http2_adapter_receive(http2_rx, http2_exp_rx, idx := http2_tx.conn_id);
+
+ /* Store obtained smContextRef:*/
+ var charstring created_location := valueof(f_HTTP2_header_list_find_header(http2_rx.hb.headers, c_HTTP2_HDR_location));
+ g_pars.nudm_ueau_auth_event_id := regexp(created_location, Nudm_uri_prefix & valueof(ts_Nudm_UEAU_path_auth_events(g_pars.imsi_str)) & "/(?+)", 0);
+
+
+ f_http2_adapter_close(idx := http2_tx.conn_id);
+ setverdict(pass);
+}
+
+/* 3GPP TS 29.503 6.3.3.6.2.1 Resource: Individual AuthEvent (PUT) */
+private function f_n13_prepare_individual_auth_event(template (value) AuthEvent1 auth_event)
+runs on ConnHdlr return HTTP2_Msg {
+ var octetstring auth_event_enc;
+ var integer http2_idx;
+ var integer http2_stream_id;
+ var template (value) HTTP2_Msg http2_tx;
+
+ auth_event_enc := f_enc_AuthEvent1(valueof(auth_event));
+
+ http2_idx := f_http2_adapter_find_free_idx();
+ http2_stream_id := f_http2_adapter_next_stream_id(http2_idx);
+ http2_tx := ts_HTTP2_Msg(http2_idx,
+ http2_stream_id,
+ hb := {
+ pseudo_headers := ts_HTTP2_pseudo_headers_Req(method := "PUT",
+ scheme := "http",
+ authority := Nudm_uri_hostport,
+ path := ts_Nudm_UEAU_path_indivdual_auth_event(g_pars.imsi_str,
+ g_pars.nudm_ueau_auth_event_id)),
+ headers := {
+ ts_HTTP2_Hdr_content_type("application/json"),
+ ts_HTTP2_Hdr_accept("application/json"),
+ ts_HTTP2_Hdr_user_agent("ttcn3-ausf"),
+ ts_HTTP2_Hdr_accept_encoding("gzip")
+ }
+ },
+ body := ts_HTTP2_Data_frame(http2_stream_id,
+ end_stream_flag := true,
+ data := auth_event_enc));
+ return valueof(http2_tx);
+}
+
+/* 5.4.2.3.3 Authentication Result Removal */
+function f_n13_authentication_result_removal()
+runs on ConnHdlr {
+ var HTTP2_Msg http2_tx;
+ var HTTP2_Msg http2_rx;
+ var template (present) HTTP2_Msg http2_exp_rx;
+ var template (value) AuthEvent1 auth_event;
+
+ auth_event := ts_AuthEvent1(nfInstanceId := g_pars.ausf_instance_id,
+ success := true,
+ timeStamp := "2026-10-20T11:58:44.069417+00:00", /* TODO: generate the now() timestamp string */
+ authType := ts_AuthType1(FiveG_AKA),
+ servingNetworkName := g_pars.serving_network);
+
+ http2_tx := f_n13_prepare_individual_auth_event(auth_event);
+ f_http2_adapter_connect(mp_udm_hostname, mp_udm_sbi_port, mp_ausf_local_ip, idx := http2_tx.conn_id);
+ f_http2_adapter_send(http2_tx);
+
+ /* FIXME: This is probably incorrect, it should send a DELETE, but it's what open5gs-udmd is sending right now...
+ * See https://github.com/open5gs/open5gs/issues/4896 */
+ as_Nudr_DR_put_authentication_status();
+
+ /* 3GPP TS 29.503 Table 6.3.3.6.2.1-3 */
+ http2_exp_rx :=
+ tr_HTTP2_Msg(http2_tx.conn_id,
+ http2_tx.stream_id,
+ tr_HTTP2_header_block(pseudo_headers := tr_HTTP2_pseudo_headers_Resp(204)),
+ omit);
+ as_http2_adapter_receive(http2_rx, http2_exp_rx, idx := http2_tx.conn_id);
+
+ f_http2_adapter_close(idx := http2_tx.conn_id);
+ setverdict(pass);
+}
+
+/************************************************************************************
+ * N35 Nudr_DataRepository (SBI): Emulated UDR, 3GPP TS 29.504, 3GPP TS 29.505 A.2
+ ************************************************************************************/
+
+/* 3GPP TS 29.505 5.2.2.3.1 AuthenticationSubscription (GET) */
+function f_tr_Nudr_DR_get_authentication_subscription()
+runs on ConnHdlr return template (present) HTTP2_Msg {
+ var template (present) HTTP2_Msg http2_msg;
+ var template (present) HTTP2_header_block hb;
+ var template (present) HTTP2_pseudo_headers pseudo_headers;
+ var template HTTP2_header_list headers := *;
+
+ pseudo_headers := tr_HTTP2_pseudo_headers_Req(method := "GET",
+ path := tr_Nudr_DR_path_authentication_subscription(g_pars.imsi_str));
+ hb := tr_HTTP2_header_block(pseudo_headers, headers);
+ http2_msg := tr_HTTP2_Msg(?, ?, hb := hb, body := omit);
+ return http2_msg;
+}
+
+/* 3GPP TS 29.505 5.2.2 Resource: AuthenticationSubscription */
+altstep as_Nudr_DR_get_authentication_subscription()
+runs on ConnHdlr {
+ var HTTP2_Msg http2_rx;
+ [] HTTP2_CONN[HTTP2_CONN_SCP].receive(f_tr_Nudr_DR_get_authentication_subscription()) -> value http2_rx {
+ var template (value) AuthenticationSubscription auth_sub;
+ var octetstring body_enc;
+ var template (value) HTTP2_Msg http2_tx;
+
+ auth_sub := ts_AuthenticationSubscription(ts_AuthMethod(FiveG_AKA),
+ encPermanentKey := "3c6e0b8a9c15224a8228b9a98ca1531d",
+ sequenceNumber := ts_SequenceNumber(sqn := "0"),
+ authenticationManagementField := "8000",
+ encOpcKey := "762a2206fe0b4151ace403c86a11e479");
+ body_enc := f_enc_AuthenticationSubscription(valueof(auth_sub));
+
+ http2_tx := ts_HTTP2_Msg_200_OK(http2_rx.conn_id,
+ http2_rx.stream_id,
+ headers := {
+ ts_HTTP2_Hdr_content_type("application/json")
+ },
+ body := ts_HTTP2_Data_frame(http2_rx.stream_id,
+ end_stream_flag := true,
+ data := body_enc));
+ HTTP2_CONN[HTTP2_CONN_SCP].send(http2_tx);
+ setverdict(pass);
+ }
+}
+
+/* 3GPP TS 29.505 5.2.2.3.1 AuthenticationSubscription (PUT) */
+function f_tr_Nudr_DR_put_authentication_status()
+runs on ConnHdlr return template (present) HTTP2_Msg {
+ var template (present) HTTP2_Msg http2_msg;
+ var template (present) HTTP2_header_block hb;
+ var template (present) HTTP2_pseudo_headers pseudo_headers;
+ var template HTTP2_header_list headers := *;
+
+ pseudo_headers := tr_HTTP2_pseudo_headers_Req(method := "PUT",
+ path := tr_Nudr_DR_path_authentication_status(g_pars.imsi_str));
+ hb := tr_HTTP2_header_block(pseudo_headers, headers);
+ http2_msg := tr_HTTP2_Msg(?, ?, hb := hb, body := tr_HTTP2_Data_frame(data := decmatch tr_AuthEvent));
+ return http2_msg;
+}
+
+/* 3GPP TS 29.505 5.2.2 Resource: AuthenticationSubscription */
+altstep as_Nudr_DR_put_authentication_status()
+runs on ConnHdlr {
+ var HTTP2_Msg http2_rx;
+ [] HTTP2_CONN[HTTP2_CONN_SCP].receive(f_tr_Nudr_DR_put_authentication_status()) -> value http2_rx {
+ var template (value) HTTP2_Msg http2_tx;
+ http2_tx := ts_HTTP2_Msg_204_No_Content(http2_rx.conn_id,
+ http2_rx.stream_id,
+ headers := {
+ ts_HTTP2_Hdr_content_type("application/json")
+ },
+ body := omit);
+
+ HTTP2_CONN[HTTP2_CONN_SCP].send(http2_tx);
+ setverdict(pass);
+ }
+}
+
+}
diff --git a/udm/README.md b/udm/README.md
new file mode 100644
index 0000000..5d728b3
--- /dev/null
+++ b/udm/README.md
@@ -0,0 +1,20 @@
+# UDM_Tests.ttcn
+
+* external interfaces
+ * N8: SBI (emulates AMF)
+ * N10: SBI (emulates SMF)
+ * N13: SBI (emulates AUSF)
+ * N35: SBI (emulates UDR)
+
+{% dot udm_tests.svg
+digraph G {
+ rankdir=LR;
+ ATS [label="ATS\nUDM_Tests.ttcn"];
+ UDM [label="AMF\open5gs-udmd",shape="box"];
+
+ ATS -> UDM [label="N8"];
+ ATS -> UDM [label="N10"];
+ ATS -> UDM [label="N13"];
+ ATS -> UDM [label="N35"];
+}
+%}
diff --git a/udm/UDM_Tests.cfg b/udm/UDM_Tests.cfg
new file mode 100644
index 0000000..77a85ab
--- /dev/null
+++ b/udm/UDM_Tests.cfg
@@ -0,0 +1,23 @@
+[ORDERED_INCLUDE]
+# Common configuration, shared between test suites
+"../Common.cfg"
+# testsuite specific configuration, not expected to change
+"./UDM_Tests.default"
+
+# Local configuration below
+
+[LOGGING]
+
+[TESTPORT_PARAMETERS]
+
+[MODULE_PARAMETERS]
+UDM_Tests.mp_udm_hostname := "127.0.0.12";
+UDM_Tests.mp_udm_sbi_port := 7777;
+UDM_Tests.mp_scp_local_ip := "127.0.0.200";
+UDM_Tests.mp_scp_local_port := 7777;
+UDM_Tests.mp_ausf_local_ip := "127.0.0.6";
+
+[MAIN_CONTROLLER]
+
+[EXECUTE]
+UDM_Tests.control
diff --git a/udm/UDM_Tests.default b/udm/UDM_Tests.default
new file mode 100644
index 0000000..b03f59e
--- /dev/null
+++ b/udm/UDM_Tests.default
@@ -0,0 +1,12 @@
+[LOGGING]
+FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC;
+
+[TESTPORT_PARAMETERS]
+*.TCP.noDelay := "yes" // turn off nagle
+*.HTTP.use_notification_ASPs := "yes"
+
+[MODULE_PARAMETERS]
+
+[MAIN_CONTROLLER]
+
+[EXECUTE]
diff --git a/udm/UDM_Tests.ttcn b/udm/UDM_Tests.ttcn
new file mode 100644
index 0000000..413686e
--- /dev/null
+++ b/udm/UDM_Tests.ttcn
@@ -0,0 +1,151 @@
+/* UDM test suite in TTCN-3 (3GPP TS 29.503)
+ * (C) 2026 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All rights reserved.
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ *
+ * 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 UDM_Tests {
+
+import from General_Types all;
+import from Native_Functions all;
+import from IPL4asp_Types all;
+import from Misc_Helpers all;
+
+import from Osmocom_Types all;
+import from GSM_Types all;
+
+import from TCCEncoding_Functions all;
+
+import from HTTP2_Adapter all;
+import from HTTP2_Server_Emulation all;
+
+import from ConnHdlr all;
+
+modulepar {
+ charstring mp_udm_hostname := "127.0.0.12";
+ integer mp_udm_sbi_port := 7777;
+
+ charstring mp_scp_local_ip := "127.0.0.200";
+ integer mp_scp_local_port := 7777;
+
+ /* IP address at which we listen for HTTP2/SBI to emulate a AUSF in ttcn3 */
+ charstring mp_ausf_local_ip := "127.0.0.6";
+
+ GsmMcc mp_mcc := '999'H;
+ GsmMnc mp_mnc := '70'H;
+ HEX15n mp_imsi := '999700000000000'H;
+}
+
+type component MTC_CT extends HTTP2_CT, HTTP2_ConnHdlr {
+ /* emulated SCP */
+ var HTTP2_Server_Emulation_CT vc_HTTP2_SRV_SCP;
+
+ timer g_Tguard := 30.0;
+}
+
+private function f_init_http2_srv(charstring id) runs on MTC_CT {
+ id := id & "-HTTP2SRV";
+
+ var Http2ServerEmulationCfg http2_srv_cfg := {
+ http2_bind_ip := mp_scp_local_ip,
+ http2_bind_port := mp_scp_local_port,
+ one_req_per_conn := false
+ };
+
+ vc_HTTP2_SRV_SCP := HTTP2_Server_Emulation_CT.create(id) alive;
+ vc_HTTP2_SRV_SCP.start(HTTP2_Server_Emulation.main(http2_srv_cfg));
+
+ connect(self:HTTP2_CONN_PROC[HTTP2_CONN_SCP], vc_HTTP2_SRV_SCP:CONN_PROC);
+}
+
+
+private function f_init(integer imsi_suffix := 0, float t_guard := 30.0) runs on MTC_CT {
+ var charstring id := testcasename();
+
+ g_Tguard.start(t_guard);
+ activate(as_Tguard());
+
+ f_init_http2_srv(id);
+}
+
+private function f_shutdown() runs on MTC_CT {
+ f_http2_server_close_conn_all();
+ setverdict(pass);
+}
+
+private function f_start_handler_create()
+runs on MTC_CT return ConnHdlr
+{
+ var ConnHdlr vc_conn;
+ var charstring id := testcasename();
+
+ vc_conn := ConnHdlr.create(id);
+
+ if (isbound(vc_HTTP2_SRV_SCP)) {
+ connect(vc_conn:HTTP2_CONN[HTTP2_CONN_SCP], vc_HTTP2_SRV_SCP:CONN);
+ connect(vc_conn:HTTP2_CONN_PROC[HTTP2_CONN_SCP], vc_HTTP2_SRV_SCP:CONN_PROC);
+ }
+
+ return vc_conn;
+}
+
+private function f_start_handler_run(ConnHdlr vc_conn, void_fn fn, ConnHdlrPars pars) runs on MTC_CT
+{
+ vc_conn.start(f_ConnHdlr_init(fn, pars));
+}
+
+/* start a connection handler with given parameters */
+private function f_start_handler(void_fn fn, ConnHdlrPars pars)
+runs on MTC_CT return ConnHdlr {
+ var ConnHdlr vc_conn;
+ vc_conn := f_start_handler_create();
+ f_start_handler_run(vc_conn, fn, pars);
+ return vc_conn;
+}
+
+private altstep as_Tguard() runs on MTC_CT {
+ [] g_Tguard.timeout {
+ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Tguard timeout");
+ }
+}
+
+/* 3GPP TS 29.503 5.4.2.2.2 Authentication Information Retrieval */
+private function f_TC_auth_info_retrieve() runs on ConnHdlr {
+ f_n13_generate_auth_data();
+ setverdict(pass);
+}
+testcase TC_auth_info_retrieve() runs on MTC_CT {
+ var ConnHdlr vc_conn;
+ var ConnHdlrPars pars := f_ConnHdlrPars(0);
+ f_init();
+ vc_conn := f_start_handler(refers(f_TC_auth_info_retrieve), pars);
+ vc_conn.done;
+ f_shutdown();
+}
+
+/* 3GPP TS 29.503 5.4.2.3 ResultConfirmationInform */
+private function f_TC_result_confirmation_inform() runs on ConnHdlr {
+ f_n13_authentication_confirmation();
+ f_n13_authentication_result_removal();
+ setverdict(pass);
+}
+testcase TC_result_confirmation_inform() runs on MTC_CT {
+ var ConnHdlr vc_conn;
+ var ConnHdlrPars pars := f_ConnHdlrPars(0);
+ f_init();
+ vc_conn := f_start_handler(refers(f_TC_result_confirmation_inform), pars);
+ vc_conn.done;
+ f_shutdown();
+}
+
+control {
+ execute( TC_auth_info_retrieve() );
+ execute( TC_result_confirmation_inform() );
+}
+
+}
diff --git a/udm/create_test_subscribers.sh b/udm/create_test_subscribers.sh
new file mode 100755
index 0000000..715d66d
--- /dev/null
+++ b/udm/create_test_subscribers.sh
@@ -0,0 +1,31 @@
+#!/bin/sh -ex
+DB_URI="mongodb://127.0.0.103/open5gs"
+DBCTL_CMD="open5gs-dbctl --db_uri=$DB_URI"
+
+# mongod needs some time to bootstrap...
+while ! mongosh --quiet $DB_URI</dev/null; do
+ sleep 1
+done
+
+NUM_SUBCRS=1
+get_subscr_imsi() {
+ subscr_idx=$1
+ printf "999700000000%03u" "$subscr_idx"
+}
+
+# Create a test subscriber with IMSI=001010000000000
+DBCTL_PARALLEL_JOBS=20
+idx=0
+while test "$idx" -lt "$NUM_SUBCRS"; do
+ remain="$((NUM_SUBCRS - idx))"
+ if test "$remain" -gt "$DBCTL_PARALLEL_JOBS"; then
+ iterations=$DBCTL_PARALLEL_JOBS
+ else
+ iterations=$remain
+ fi
+ for it in $(seq "$iterations"); do
+ $DBCTL_CMD add "$(get_subscr_imsi $idx)" 3c6e0b8a9c15224a8228b9a98ca1531d 762a2206fe0b4151ace403c86a11e479 &
+ idx=$((idx + 1))
+ done
+ wait $(jobs -p)
+done
diff --git a/udm/expected-results.xml b/udm/expected-results.xml
new file mode 100644
index 0000000..2dc9390
--- /dev/null
+++ b/udm/expected-results.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<testsuite name='Titan' tests='2' failures='0' errors='0' skipped='0' inconc='0' time='MASKED'>
+ <testcase classname='UDM_Tests' name='TC_auth_info_retrieve' time='MASKED'/>
+ <testcase classname='UDM_Tests' name='TC_result_confirmation_inform' time='MASKED'/>
+</testsuite>
diff --git a/udm/gen_links.sh b/udm/gen_links.sh
new file mode 100755
index 0000000..d50f68b
--- /dev/null
+++ b/udm/gen_links.sh
@@ -0,0 +1,52 @@
+#!/bin/bash -e
+
+BASEDIR=../deps
+
+. ../_buildsystem/gen_links.inc.sh
+
+DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
+FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h"
+FILES+=" TCCEncoding_Functions.ttcn TCCEncoding.cc " # GSM 7-bit coding
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
+FILES="Socket_API_Definitions.ttcn"
+gen_links $DIR $FILES
+
+# Required by MGCP and IPA
+DIR=$BASEDIR/titan.TestPorts.IPL4asp/src
+FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh"
+gen_links $DIR $FILES
+
+# Needed by HTTP_Adapter (Prometheus_Checker.ttcn metrics):
+DIR=$BASEDIR/titan.TestPorts.Common_Components.Abstract_Socket/src
+FILES="Abstract_Socket.cc Abstract_Socket.hh "
+gen_links $DIR $FILES
+
+# Needed by HTTP_Adapter (Prometheus_Checker.ttcn metrics):
+DIR=$BASEDIR/titan.TestPorts.HTTPmsg/src
+FILES="HTTPmsg_MessageLen.ttcn HTTPmsg_MessageLen_Function.cc HTTPmsg_PT.cc HTTPmsg_PT.hh HTTPmsg_PortType.ttcn HTTPmsg_Types.ttcn "
+gen_links $DIR $FILES
+
+# Needed by HTTP2_Adapter:
+DIR=$BASEDIR/titan.ProtocolModules.HTTP2/src
+FILES="HTTP2_EncDec.cc HTTP2_Types.ttcn"
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/titan.ProtocolModules.JSON_v07_2006/src
+FILES="JSON_Generic_Null_Def.asn JSON_Generic.ttcn"
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/osmo-ttcn3-openapi-generator/openapi-specs/3GPP_5GC_Rel19/ttcn3
+FILES="TS29571_CommonData.ttcn TS29503_Nudm_UEAU.ttcn TS29505_Subscription_Data.ttcn "
+gen_links $DIR $FILES
+
+DIR=../library
+FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPCP_Types.ttcn IPCP_Templates.ttcn "
+FILES+="SCTP_Templates.ttcn "
+FILES+="HTTP2_CodecPort.ttcn HTTP2_CodecPort_CtrlFunct.ttcn HTTP2_CodecPort_CtrlFunctDef.cc HTTP2_Templates.ttcn HTTP2_Functions.ttcn HTTP2_Msg.ttcn HTTP2_Adapter.ttcn HTTP2_Server_Emulation.ttcn "
+FILES+="HTTP_Adapter.ttcn Prometheus_Checker.ttcn "
+FILES+="TS29571_CommonData_Templates.ttcn TS29503_Nudm_UEAU_Templates.ttcn TS29505_Subscription_Data_Templates.ttcn "
+gen_links $DIR $FILES
+
+gen_links_finish
diff --git a/udm/mongod.conf b/udm/mongod.conf
new file mode 100644
index 0000000..ff648f4
--- /dev/null
+++ b/udm/mongod.conf
@@ -0,0 +1,45 @@
+# mongod.conf
+
+# for documentation of all options, see:
+# http://docs.mongodb.org/manual/reference/configuration-options/
+
+# Where and how to store data.
+storage:
+ dbPath: db
+# journal:
+# enabled: true
+# engine:
+# mmapv1:
+# wiredTiger:
+
+# where to write logging data.
+# systemLog:
+# destination: file
+# logAppend: true
+# path: /data/mongod.log
+
+# network interfaces
+net:
+ port: 27017
+ bindIp: 127.0.0.103
+
+
+# how the process runs
+processManagement:
+ timeZoneInfo: /usr/share/zoneinfo
+
+#security:
+
+#operationProfiling:
+
+#replication:
+
+#sharding:
+
+## Enterprise-Only Options:
+
+#auditLog:
+
+#snmp:
+
+
diff --git a/udm/open5gs-udm.yaml b/udm/open5gs-udm.yaml
new file mode 100644
index 0000000..f507a5d
--- /dev/null
+++ b/udm/open5gs-udm.yaml
@@ -0,0 +1,38 @@
+# See https://github.com/open5gs/open5gs/blob/main/configs/open5gs/udm.yaml.in
+
+logger:
+ level: debug
+
+global:
+ max:
+ ue: 1024
+
+udm:
+ hnet:
+ - id: 1
+ scheme: 1
+ key: @sysconfdir@/open5gs/hnet/curve25519-1.key
+ - id: 2
+ scheme: 2
+ key: @sysconfdir@/open5gs/hnet/secp256r1-2.key
+ - id: 3
+ scheme: 1
+ key: @sysconfdir@/open5gs/hnet/curve25519-3.key
+ - id: 4
+ scheme: 2
+ key: @sysconfdir@/open5gs/hnet/secp256r1-4.key
+ - id: 5
+ scheme: 1
+ key: @sysconfdir@/open5gs/hnet/curve25519-5.key
+ - id: 6
+ scheme: 2
+ key: @sysconfdir@/open5gs/hnet/secp256r1-6.key
+ sbi:
+ server:
+ - address: 127.0.0.12
+ port: 7777
+ client:
+# nrf:
+# - uri: http://127.0.0.10:7777
+ scp:
+ - uri: http://127.0.0.200:7777
diff --git a/udm/open5gs_prepare.sh b/udm/open5gs_prepare.sh
new file mode 100755
index 0000000..9f4e9ec
--- /dev/null
+++ b/udm/open5gs_prepare.sh
@@ -0,0 +1,7 @@
+#!/bin/sh -ex
+
+adjust_sysconfdir_config() {
+ sed -i "s~@sysconfdir@~$TESTENV_INSTALL_DIR/etc/~g" $1
+}
+
+adjust_sysconfdir_config open5gs-udm.yaml
diff --git a/udm/regen_makefile.sh b/udm/regen_makefile.sh
new file mode 100755
index 0000000..f26fdb6
--- /dev/null
+++ b/udm/regen_makefile.sh
@@ -0,0 +1,23 @@
+#!/bin/sh -e
+
+NAME=UDM_Tests
+
+FILES="
+ *.asn
+ *.ttcn
+ Abstract_Socket.cc
+ HTTPmsg_MessageLen_Function.cc
+ HTTPmsg_PT.cc
+ HTTP2_EncDec.cc
+ HTTP2_CodecPort_CtrlFunctDef.cc
+ IPL4asp_PT.cc
+ IPL4asp_discovery.cc
+ Native_FunctionDefs.cc
+ TCCConversion.cc
+ TCCEncoding.cc
+ TCCInterface.cc
+"
+
+. ../_buildsystem/regen_makefile.inc.sh
+
+sed -i -e 's/^LINUX_LIBS = -lxml2 -lsctp/LINUX_LIBS = -lxml2 -lsctp -lgnutls/' Makefile
diff --git a/udm/testenv.cfg b/udm/testenv.cfg
new file mode 100644
index 0000000..3b2e319
--- /dev/null
+++ b/udm/testenv.cfg
@@ -0,0 +1,20 @@
+[testsuite]
+program=UDM_Tests
+config=UDM_Tests.cfg
+
+[db]
+prepare=mkdir db
+clean=rm -rf db
+program=mongod --config mongod.conf
+setup=create_test_subscribers.sh
+copy=mongod.conf
+make=no
+package=no
+
+[udm]
+prepare=./open5gs_prepare.sh
+program=open5gs-udmd -c open5gs-udm.yaml
+make=open5gs
+package=open5gs-udm
+copy=open5gs-udm.yaml open5gs_prepare.sh
+
diff --git a/udm/testsrcdir.cfg b/udm/testsrcdir.cfg
new file mode 100644
index 0000000..7f19289
--- /dev/null
+++ b/udm/testsrcdir.cfg
@@ -0,0 +1,2 @@
+[testsrcdir]
+max_jobs_per_gb_ram=0.3
To view, visit change 43932. To unsubscribe, or for help writing mail filters, visit settings.