[HSS,S6A] Add two Supported-Features AVPs to ULA for 5G-NSA roaming (#3832)

This commit adds support for two Supported-Features AVPs in the
UpdateLocationAnswer (ULA) to enable 5G-NSA roaming. The first AVP
includes subscriber restrictions, while the second AVP signals that NR
as Secondary RAT is supported. Updates include modifications to
lib/diameter/s6a/message.c, lib/diameter/s6a/message.h, and
src/hss/hss-s6a-path.c.
This commit is contained in:
Sukchan Lee
2025-04-06 17:01:05 +09:00
parent 6af18a15c3
commit 9217889f8a
3 changed files with 85 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2025 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
@@ -92,6 +92,10 @@ struct dict_object *ogs_diam_s6a_software_version = NULL;
struct dict_object *ogs_diam_s6a_msisdn = NULL;
struct dict_object *ogs_diam_s6a_a_msisdn = NULL;
struct dict_object *ogs_diam_s6a_supported_features = NULL;
struct dict_object *ogs_diam_s6a_feature_list_id = NULL;
struct dict_object *ogs_diam_s6a_feature_list = NULL;
extern int ogs_dict_s6a_entry(char *conffile);
int ogs_diam_s6a_init(void)
@@ -176,5 +180,9 @@ int ogs_diam_s6a_init(void)
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "MSISDN", &ogs_diam_s6a_msisdn);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "A-MSISDN", &ogs_diam_s6a_a_msisdn);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Supported-Features", &ogs_diam_s6a_supported_features);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List-ID", &ogs_diam_s6a_feature_list_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List", &ogs_diam_s6a_feature_list);
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2025 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
@@ -159,6 +159,10 @@ extern struct dict_object *ogs_diam_s6a_software_version;
extern struct dict_object *ogs_diam_s6a_msisdn;
extern struct dict_object *ogs_diam_s6a_a_msisdn;
extern struct dict_object *ogs_diam_s6a_supported_features;
extern struct dict_object *ogs_diam_s6a_feature_list_id;
extern struct dict_object *ogs_diam_s6a_feature_list;
typedef struct ogs_diam_e_utran_vector_s {
uint8_t xres[OGS_MAX_RES_LEN];
uint8_t xres_len;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2025 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
@@ -974,6 +974,76 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ans, OGS_DIAM_S6A_APPLICATION_ID);
ogs_assert(ret == 0);
/*
* AVP 628 Supported-Features
* AVP 629 Feature-List-ID: 1
* AVP 630 Feature-List: (misc subscriber restrictions)
*/
ret = fd_msg_avp_new(ogs_diam_s6a_supported_features, 0, &avp);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_vendor_id, 0, &avpch1);
ogs_assert(ret == 0);
val.i32 = OGS_3GPP_VENDOR_ID;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_feature_list_id, 0, &avpch1);
ogs_assert(ret == 0);
val.i32 = 1;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_feature_list, 0, &avpch1);
ogs_assert(ret == 0);
val.u32 = 0x0000000b;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/*
* AVP 628 Supported-Features
* AVP 629 Feature-List-ID: 2
* AVP 630 Feature-List: (“NR as Secondary RAT: Supported”)
*/
ret = fd_msg_avp_new(ogs_diam_s6a_supported_features, 0, &avp);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_vendor_id, 0, &avpch1);
ogs_assert(ret == 0);
val.i32 = OGS_3GPP_VENDOR_ID;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_feature_list_id, 0, &avpch1);
ogs_assert(ret == 0);
val.i32 = 2;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
ret = fd_msg_avp_new(ogs_diam_s6a_feature_list, 0, &avpch1);
ogs_assert(ret == 0);
val.u32 = 0x08000001;
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Send the answer */
ret = fd_msg_send(msg, NULL, NULL);
ogs_assert(ret == 0);