Merge branch 'main' into home-routed

This commit is contained in:
Sukchan Lee
2025-04-06 18:37:36 +09:00
9 changed files with 617 additions and 6 deletions

View File

@@ -120,7 +120,8 @@ int ogs_dbi_ims_data(char *supi, ogs_ims_data_t *ims_data)
bson_error_t error;
const bson_t *document;
bson_iter_t iter;
bson_iter_t child1_iter;
bson_iter_t child1_iter, child2_iter, child3_iter, child4_iter, child5_iter;
bson_iter_t child6_iter, child7_iter, child8_iter, child9_iter;
const char *utf8 = NULL;
uint32_t length = 0;
@@ -190,6 +191,222 @@ int ogs_dbi_ims_data(char *supi, ogs_ims_data_t *ims_data)
}
}
ims_data->num_of_msisdn = msisdn_index;
} else if (!strcmp(key, "ifc") &&
BSON_ITER_HOLDS_ARRAY(&iter)) {
int ifc_index = 0;
bson_iter_recurse(&iter, &child2_iter);
while (bson_iter_next(&child2_iter)) {
ogs_assert(ifc_index < OGS_MAX_NUM_OF_IFC);
bson_iter_recurse(&child2_iter, &child3_iter);
while (bson_iter_next(&child3_iter)) {
const char *child3_key = bson_iter_key(&child3_iter);
if (!strcmp(child3_key, "priority") &&
BSON_ITER_HOLDS_INT32(&child3_iter)) {
ims_data->ifc[ifc_index].priority =
bson_iter_int32(&child3_iter);
} else if (!strcmp(child3_key, "application_server") &&
BSON_ITER_HOLDS_DOCUMENT(&child3_iter)) {
bson_iter_recurse(&child3_iter, &child4_iter);
while (bson_iter_next(&child4_iter)) {
const char *child4_key =
bson_iter_key(&child4_iter);
if (!strcmp(child4_key, "server_name") &&
BSON_ITER_HOLDS_UTF8(&child4_iter)) {
utf8 = bson_iter_utf8(&child4_iter, &length);
ims_data->ifc[ifc_index]
.application_server.server_name =
ogs_strndup(utf8, length);
} else if (!strcmp(child4_key, "default_handling")
&& BSON_ITER_HOLDS_INT32(&child4_iter)) {
ims_data->ifc[ifc_index]
.application_server.default_handling =
bson_iter_int32(&child4_iter);
}
}
} else if (!strcmp(child3_key, "trigger_point") &&
BSON_ITER_HOLDS_DOCUMENT(&child3_iter)) {
bson_iter_recurse(&child3_iter, &child5_iter);
while (bson_iter_next(&child5_iter)) {
const char *child5_key =
bson_iter_key(&child5_iter);
if (!strcmp(child5_key, "condition_type_cnf") &&
BSON_ITER_HOLDS_INT32(&child5_iter)) {
ims_data->ifc[ifc_index]
.trigger_point.condition_type_cnf =
bson_iter_int32(&child5_iter);
} else if (!strcmp(child5_key, "spt") &&
BSON_ITER_HOLDS_ARRAY(&child5_iter)) {
int spt_index = 0;
bson_iter_recurse(&child5_iter, &child6_iter);
while (bson_iter_next(&child6_iter)) {
ogs_assert(spt_index < OGS_MAX_NUM_OF_SPT);
bson_iter_recurse(&child6_iter,
&child7_iter);
while (bson_iter_next(&child7_iter)) {
const char *child7_key =
bson_iter_key(&child7_iter);
if (!strcmp(child7_key,
"condition_negated") &&
BSON_ITER_HOLDS_INT32(
&child7_iter)) {
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.condition_negated =
bson_iter_int32(
&child7_iter);
} else if (!strcmp(child7_key, "group")
&& BSON_ITER_HOLDS_INT32(
&child7_iter)) {
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.group = bson_iter_int32(
&child7_iter);
} else if (!strcmp(child7_key,
"method") &&
BSON_ITER_HOLDS_UTF8(
&child7_iter)) {
utf8 = bson_iter_utf8(&child7_iter,
&length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.method =
ogs_strndup(utf8, length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.type = OGS_SPT_HAS_METHOD;
} else if (!strcmp(child7_key,
"session_case") &&
BSON_ITER_HOLDS_INT32(
&child7_iter)) {
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.session_case =
bson_iter_int32(
&child7_iter);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.type =
OGS_SPT_HAS_SESSION_CASE;
} else if (!strcmp(child7_key,
"sip_header") &&
BSON_ITER_HOLDS_DOCUMENT(
&child7_iter)) {
bson_iter_recurse(&child7_iter,
&child8_iter);
while (bson_iter_next(
&child8_iter)) {
const char *child8_key =
bson_iter_key(
&child8_iter);
if (!strcmp(child8_key,
"header") &&
BSON_ITER_HOLDS_UTF8(
&child8_iter)) {
utf8 = bson_iter_utf8(
&child8_iter,
&length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.header =
ogs_strndup(utf8,
length);
} else if (!strcmp(child8_key,
"content") &&
BSON_ITER_HOLDS_UTF8(
&child8_iter)) {
utf8 = bson_iter_utf8(
&child8_iter,
&length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.header_content =
ogs_strndup(utf8,
length);
}
}
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.type = OGS_SPT_HAS_SIP_HEADER;
} else if (!strcmp(child7_key,
"sdp_line") &&
BSON_ITER_HOLDS_DOCUMENT(
&child7_iter)) {
bson_iter_recurse(&child7_iter,
&child9_iter);
while (bson_iter_next(
&child9_iter)) {
const char *child9_key =
bson_iter_key(
&child9_iter);
if (!strcmp(child9_key,
"line") &&
BSON_ITER_HOLDS_UTF8(
&child9_iter)) {
utf8 = bson_iter_utf8(
&child9_iter,
&length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.sdp_line =
ogs_strndup(utf8,
length);
} else if (!strcmp(child9_key,
"content") &&
BSON_ITER_HOLDS_UTF8(
&child9_iter)) {
utf8 = bson_iter_utf8(
&child9_iter,
&length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.sdp_line_content =
ogs_strndup(utf8,
length);
}
}
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.type = OGS_SPT_HAS_SDP_LINE;
} else if (!strcmp(child7_key,
"request_uri") &&
BSON_ITER_HOLDS_UTF8(
&child7_iter)) {
utf8 = bson_iter_utf8(&child7_iter,
&length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.request_uri =
ogs_strndup(utf8, length);
ims_data->ifc[ifc_index]
.trigger_point
.spt[spt_index]
.type = OGS_SPT_HAS_REQUEST_URI;
}
}
spt_index++;
}
ims_data->ifc->trigger_point.num_of_spt =
spt_index;
}
}
}
}
ifc_index++;
}
ims_data->num_of_ifc = ifc_index;
}
}

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

@@ -958,6 +958,97 @@ typedef struct ogs_media_component_s {
int num_of_sub;
} ogs_media_component_t;
#define OGS_MAX_NUM_OF_SPT 20
#define OGS_MAX_NUM_OF_IFC 20
/*
* Defines matching mechanism type of SPT
*/
typedef enum {
OGS_SPT_INVALID_TYPE,
OGS_SPT_HAS_METHOD,
OGS_SPT_HAS_SESSION_CASE,
OGS_SPT_HAS_SIP_HEADER,
OGS_SPT_HAS_SDP_LINE,
OGS_SPT_HAS_REQUEST_URI,
} ogs_spt_type_e;
/**************************************************
* Service Point Trigger Structure (SPT) */
typedef struct ogs_spt_s {
/* Matching mechanism type of SPT */
ogs_spt_type_e type;
/* Indicates if the Service Point Trigger instance is negated */
int condition_negated;
/* The SPT group or list of SPT groups assigned to the SPT */
int group;
/* The method of the SIP request */
const char *method;
/* The direction of the SIP request as evaluated by the S-CSCF */
int session_case;
/* A header in the SIP request*/
const char *header;
/* Optionally the value of the header in the SIP request */
const char *header_content;
/* A SDP line within the body (if any) of a SIP request */
const char *sdp_line;
/* Optionally the value in the SDP line of a SIP request */
const char *sdp_line_content;
/* The request-URI of the SIP request */
const char *request_uri;
} ogs_spt_t;
/*
* Defines what logical operators should be used between SPTs belonging to
* different groups
*/
typedef enum {
OGS_DISJUNCTIVE_NORMAL_FORMAT, /* an ORed set of ANDed subsets */
OGS_CONJUNCTIVE_NORMAL_FORMAT /* an ANDed set of ORed subsets */
} ogs_condition_type_cnf_e;
/**************************************************
* Trigger Point Structure
* Each TriggerPoint is made up of Service Point Trigger (SPTs) which are
* individual rules that are matched or not matched, that are either combined
* as logical AND or logical OR statements when evaluated.
*/
typedef struct ogs_trigger_point_s {
int num_of_spt;
ogs_condition_type_cnf_e condition_type_cnf;
ogs_spt_t spt[OGS_MAX_NUM_OF_SPT];
} ogs_trigger_point_t;
/**************************************************
* Application Server Structure */
typedef struct ogs_application_server_s {
const char *server_name;
int default_handling;
} ogs_application_server_t;
/**************************************************
* IFC Structure
* 3GPP TS 29.562
*/
typedef struct ogs_ifc_s {
/*
* The priority of the IFC.
* The higher the Priority Number the lower the priority of the Filter
* Criteria is
*/
int priority;
/*
* The conditions that should be checked to find out
* if the indicated Application Server should be contacted or not
*/
ogs_trigger_point_t trigger_point;
/*
* the Application Server which shall be triggered
* if the conditions are met
*/
ogs_application_server_t application_server;
} ogs_ifc_t;
typedef struct ogs_ims_data_s {
int num_of_msisdn;
struct {
@@ -969,6 +1060,9 @@ typedef struct ogs_ims_data_s {
#define OGS_MAX_NUM_OF_MEDIA_COMPONENT 16
ogs_media_component_t media_component[OGS_MAX_NUM_OF_MEDIA_COMPONENT];
int num_of_media_component;
int num_of_ifc;
ogs_ifc_t ifc[OGS_MAX_NUM_OF_IFC];
} ogs_ims_data_t;
void ogs_ims_data_free(ogs_ims_data_t *ims_data);

View File

@@ -738,6 +738,26 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
ogs_free(fields);
}
}
if (message->param.num_of_fields) {
char *fields;
fields = ogs_strdup(message->param.fields[0]);
if (!fields) {
ogs_error("ogs_strdup() failed");
return NULL;
}
for (i = 1; i < message->param.num_of_fields; i++)
fields = ogs_mstrcatf(
fields, ",%s", message->param.fields[i]);
if (fields) {
ogs_sbi_header_set(request->http.params,
OGS_SBI_PARAM_FIELDS, fields);
ogs_free(fields);
}
}
if (message->param.ipv4addr) {
ogs_sbi_header_set(request->http.params,

View File

@@ -364,6 +364,11 @@ extern "C" {
#define OGS_SBI_PARAM_FIELDS_NSSAI "nssai"
#define OGS_SBI_MAX_NUM_OF_FIELDS 8
#define OGS_SBI_PARAM_FIELDS_GPSIS "gpsis"
#define OGS_SBI_PARAM_FIELDS_SUBSCRIBED_UE_AMBR "subscribedUeAmbr"
#define OGS_SBI_PARAM_FIELDS_NSSAI "nssai"
#define OGS_SBI_MAX_NUM_OF_FIELDS 8
#define OGS_SBI_CONTENT_JSON_TYPE \
OGS_SBI_APPLICATION_TYPE "/" OGS_SBI_APPLICATION_JSON_TYPE
#define OGS_SBI_CONTENT_PROBLEM_TYPE \

View File

@@ -923,7 +923,7 @@ char *hss_cx_download_user_data(
hss_impu_t *impu = NULL;
bool barring_indication_presence = true;
int i;
int i, n, m;
ogs_assert(user_name);
ogs_assert(visited_network_identifier);
@@ -1011,7 +1011,160 @@ char *hss_cx_download_user_data(
ogs_assert(user_data);
}
if(self.sms_over_ims) {
/* IFC data */
for (n = 0; n < ims_data->num_of_ifc; n++) {
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_ifc_s);
ogs_assert(user_data);
/* priority */
user_data = ogs_mstrcatf(user_data, "%s%d%s",
ogs_diam_cx_xml_priority_s,
ims_data->ifc[n].priority,
ogs_diam_cx_xml_priority_e);
ogs_assert(user_data);
/* trigger point */
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_tp_s);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s%d%s",
ogs_diam_cx_xml_cnf_s,
ims_data->ifc[n].trigger_point.condition_type_cnf,
ogs_diam_cx_xml_cnf_e);
ogs_assert(user_data);
/* SPTs */
for (m = 0; m < ims_data->ifc[n].trigger_point.num_of_spt;
m++) {
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_spt_s);
ogs_assert(user_data);
/* condition negated */
user_data = ogs_mstrcatf(user_data, "%s%d%s",
ogs_diam_cx_xml_condition_negated_s,
ims_data->ifc[n].trigger_point.spt[m].
condition_negated,
ogs_diam_cx_xml_condition_negated_e);
ogs_assert(user_data);
/* group */
user_data = ogs_mstrcatf(user_data, "%s%d%s",
ogs_diam_cx_xml_group_s,
ims_data->ifc[n].trigger_point.spt[m].group,
ogs_diam_cx_xml_group_e);
ogs_assert(user_data);
/* method */
if (ims_data->ifc[n].trigger_point.spt[m].type ==
OGS_SPT_HAS_METHOD) {
user_data = ogs_mstrcatf(user_data, "%s%s%s",
ogs_diam_cx_xml_method_s,
ims_data->ifc[n].trigger_point.spt[m].
method,
ogs_diam_cx_xml_method_e);
ogs_assert(user_data);
}
/* session case */
if (ims_data->ifc[n].trigger_point.spt[m].type ==
OGS_SPT_HAS_SESSION_CASE) {
user_data = ogs_mstrcatf(user_data, "%s%d%s",
ogs_diam_cx_xml_session_case_s,
ims_data->ifc[n].trigger_point.spt[m].
session_case,
ogs_diam_cx_xml_session_case_e);
ogs_assert(user_data);
}
/* sip header */
if (ims_data->ifc[n].trigger_point.spt[m].type ==
OGS_SPT_HAS_SIP_HEADER) {
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_sip_hdr_s);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s%s%s",
ogs_diam_cx_xml_header_s,
ims_data->ifc[n].trigger_point.spt[m].
header,
ogs_diam_cx_xml_header_e);
ogs_assert(user_data);
if (ims_data->ifc[n].trigger_point.spt[m].
header_content) {
user_data = ogs_mstrcatf(user_data, "%s%s%s",
ogs_diam_cx_xml_content_s,
ims_data->ifc[n].trigger_point.
spt[m].header_content,
ogs_diam_cx_xml_content_e);
ogs_assert(user_data);
}
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_sip_hdr_e);
ogs_assert(user_data);
}
/* request uri */
if (ims_data->ifc[n].trigger_point.spt[m].type ==
OGS_SPT_HAS_REQUEST_URI) {
user_data = ogs_mstrcatf(user_data, "%s%s%s",
ogs_diam_cx_xml_req_uri_s,
ims_data->ifc[n].trigger_point.spt[m].
request_uri,
ogs_diam_cx_xml_req_uri_e);
ogs_assert(user_data);
}
/* extension */
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_extension_s);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_extension_e);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_spt_e);
ogs_assert(user_data);
}
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_tp_e);
ogs_assert(user_data);
/* application server */
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_app_server_s);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s%s%s",
ogs_diam_cx_xml_server_name_s,
ims_data->ifc[n].application_server.server_name,
ogs_diam_cx_xml_server_name_e);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s%d%s",
ogs_diam_cx_xml_default_handling_s,
ims_data->ifc[n].application_server.
default_handling,
ogs_diam_cx_xml_default_handling_e);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_app_server_e);
ogs_assert(user_data);
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_ifc_e);
ogs_assert(user_data);
}
if (self.sms_over_ims) {
user_data = ogs_mstrcatf(user_data, "%s",
ogs_diam_cx_xml_ifc_s);
ogs_assert(user_data);

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);

View File

@@ -34,6 +34,7 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create(
OpenAPI_subscribed_default_qos_t SubsDefQos;
OpenAPI_arp_t Arp;
OpenAPI_snssai_t sNssai;
OpenAPI_user_location_t ueLocation;
ogs_assert(sess);
ogs_assert(sess->sm_context_ref);
@@ -50,6 +51,7 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create(
memset(&SmPolicyContextData, 0, sizeof(SmPolicyContextData));
memset(&sNssai, 0, sizeof(sNssai));
memset(&SubsSessAmbr, 0, sizeof(SubsSessAmbr));
memset(&ueLocation, 0, sizeof(ueLocation));
SmPolicyContextData.supi = smf_ue->supi;
if (!SmPolicyContextData.supi) {
@@ -67,6 +69,12 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create(
goto end;
}
/*
* TODO: Currently hard-coded to "00000800";
* replace with dynamic value if needed in future
*/
SmPolicyContextData.chargingcharacteristics = (char *)"00000800";
/*
* Use ogs_sbi_supi_in_vplmn() instead of ogs_sbi_plmn_id_in_vplmn().
* This is because some vendors might not use the full DNN in LBO and
@@ -139,6 +147,8 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create(
goto end;
}
SmPolicyContextData.rat_type = OpenAPI_rat_type_NR;
SmPolicyContextData.serving_network =
ogs_sbi_build_plmn_id_nid(&sess->serving_plmn_id);
if (!SmPolicyContextData.serving_network) {
@@ -146,6 +156,28 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create(
goto end;
}
ueLocation.nr_location = ogs_sbi_build_nr_location(
&sess->nr_tai, &sess->nr_cgi);
if (!ueLocation.nr_location) {
ogs_error("ueLocation.nr_location");
goto end;
}
ueLocation.nr_location->ue_location_timestamp =
ogs_sbi_gmtime_string(sess->ue_location_timestamp);
if (!ueLocation.nr_location->ue_location_timestamp) {
ogs_error("ueLocation.nr_location->ue_location_timestamp");
goto end;
}
SmPolicyContextData.user_location_info = &ueLocation;
SmPolicyContextData.ue_time_zone =
ogs_sbi_timezone_string(ogs_timezone());
if (!SmPolicyContextData.ue_time_zone) {
ogs_error("SmPolicyContextData.ue_time_zone");
goto end;
}
if (sess->ipv4) {
SmPolicyContextData.ipv4_address =
ogs_ipv4_to_string(sess->ipv4->addr[0]);
@@ -263,6 +295,14 @@ end:
if (SmPolicyContextData.serving_network)
ogs_sbi_free_plmn_id_nid(SmPolicyContextData.serving_network);
if (ueLocation.nr_location) {
if (ueLocation.nr_location->ue_location_timestamp)
ogs_free(ueLocation.nr_location->ue_location_timestamp);
ogs_sbi_free_nr_location(ueLocation.nr_location);
}
if (SmPolicyContextData.ue_time_zone)
ogs_free(SmPolicyContextData.ue_time_zone);
if (sNssai.sd)
ogs_free(sNssai.sd);