forked from acouzens/open5gs
Fixed incorrect SMF selection in Multi-SMF (#2557)
This commit is contained in:
parent
125740727e
commit
d406fbeb92
|
@ -161,6 +161,12 @@ char ogs_from_hex(char ch)
|
|||
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
||||
}
|
||||
|
||||
char ogs_to_hex(char ch)
|
||||
{
|
||||
static char hex[] = "0123456789ABCDEF";
|
||||
return hex[ch & 15];
|
||||
}
|
||||
|
||||
char *ogs_uint24_to_0string(ogs_uint24_t x)
|
||||
{
|
||||
return ogs_msprintf("%06x", x.v);
|
||||
|
|
|
@ -44,6 +44,7 @@ void *ogs_bcd_to_buffer_reverse_order(const char *in, void *out, int *out_len);
|
|||
void *ogs_buffer_to_bcd(uint8_t *in, int in_len, void *out);
|
||||
|
||||
char ogs_from_hex(char ch);
|
||||
char ogs_to_hex(char ch);
|
||||
|
||||
char *ogs_uint24_to_0string(ogs_uint24_t x);
|
||||
char *ogs_uint28_to_0string(uint32_t x);
|
||||
|
|
|
@ -1316,6 +1316,62 @@ ogs_sbi_nf_info_t *ogs_sbi_nf_info_find(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool ogs_sbi_check_smf_info_slice(
|
||||
ogs_sbi_smf_info_t *smf_info, ogs_s_nssai_t *s_nssai, char *dnn)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
ogs_assert(smf_info);
|
||||
ogs_assert(s_nssai);
|
||||
ogs_assert(dnn);
|
||||
|
||||
for (i = 0; i < smf_info->num_of_slice; i++) {
|
||||
if (s_nssai->sst == smf_info->slice[i].s_nssai.sst &&
|
||||
s_nssai->sd.v == smf_info->slice[i].s_nssai.sd.v) {
|
||||
|
||||
for (j = 0; j < smf_info->slice[i].num_of_dnn; j++) {
|
||||
if (ogs_strcasecmp(dnn, smf_info->slice[i].dnn[j]) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool ogs_sbi_check_smf_info_tai(
|
||||
ogs_sbi_smf_info_t *smf_info, ogs_5gs_tai_t *tai)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
ogs_assert(smf_info);
|
||||
ogs_assert(tai);
|
||||
|
||||
if (smf_info->num_of_nr_tai == 0 && smf_info->num_of_nr_tai_range == 0)
|
||||
return true;
|
||||
|
||||
for (i = 0; i < smf_info->num_of_nr_tai; i++) {
|
||||
if (memcmp(&tai->plmn_id,
|
||||
&smf_info->nr_tai[i].plmn_id, OGS_PLMN_ID_LEN) == 0) {
|
||||
if (tai->tac.v == smf_info->nr_tai[i].tac.v)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < smf_info->num_of_nr_tai_range; i++) {
|
||||
if (memcmp(&tai->plmn_id,
|
||||
&smf_info->nr_tai_range[i].plmn_id, OGS_PLMN_ID_LEN) == 0) {
|
||||
for (j = 0; j < smf_info->nr_tai_range[i].num_of_tac_range; j++) {
|
||||
if (tai->tac.v >= smf_info->nr_tai_range[i].start[j].v &&
|
||||
tai->tac.v <= smf_info->nr_tai_range[i].end[j].v) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_instance_build_default(ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
ogs_sbi_server_t *server = NULL;
|
||||
|
@ -1547,6 +1603,8 @@ bool ogs_sbi_discovery_option_is_matched(
|
|||
OpenAPI_nf_type_e requester_nf_type,
|
||||
ogs_sbi_discovery_option_t *discovery_option)
|
||||
{
|
||||
ogs_sbi_nf_info_t *nf_info = NULL;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(requester_nf_type);
|
||||
ogs_assert(discovery_option);
|
||||
|
@ -1581,6 +1639,30 @@ bool ogs_sbi_discovery_option_is_matched(
|
|||
if (exist == false) return false;
|
||||
}
|
||||
|
||||
ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
|
||||
if (nf_instance->nf_type != nf_info->nf_type) {
|
||||
ogs_error("Invalid NF-Type [%d:%d]",
|
||||
nf_instance->nf_type, nf_info->nf_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (nf_info->nf_type) {
|
||||
case OpenAPI_nf_type_SMF:
|
||||
if (discovery_option->num_of_snssais && discovery_option->dnn &&
|
||||
ogs_sbi_check_smf_info_slice(&nf_info->smf,
|
||||
&discovery_option->snssais[0],
|
||||
discovery_option->dnn) == false)
|
||||
return false;
|
||||
if (discovery_option->num_of_tai &&
|
||||
ogs_sbi_check_smf_info_tai(&nf_info->smf,
|
||||
&discovery_option->tai[0]) == false)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -402,6 +402,11 @@ void ogs_sbi_nf_info_remove_all(ogs_list_t *list);
|
|||
ogs_sbi_nf_info_t *ogs_sbi_nf_info_find(
|
||||
ogs_list_t *list, OpenAPI_nf_type_e nf_type);
|
||||
|
||||
bool ogs_sbi_check_smf_info_slice(
|
||||
ogs_sbi_smf_info_t *smf_info, ogs_s_nssai_t *s_nssai, char *dnn);
|
||||
bool ogs_sbi_check_smf_info_tai(
|
||||
ogs_sbi_smf_info_t *smf_info, ogs_5gs_tai_t *tai);
|
||||
|
||||
void ogs_sbi_nf_instance_build_default(ogs_sbi_nf_instance_t *nf_instance);
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
|
||||
ogs_sbi_nf_instance_t *nf_instance, const char *name);
|
||||
|
@ -424,7 +429,9 @@ int ogs_sbi_client_default_port(void);
|
|||
ogs_assert(__nFInstance); \
|
||||
\
|
||||
if ((__cTX).nf_instance) { \
|
||||
ogs_warn("NF Instance updated [%s]", (__nFInstance)->id); \
|
||||
ogs_warn("NF Instance [%s] updated [%s]", \
|
||||
OpenAPI_nf_type_ToString((__nFInstance)->nf_type), \
|
||||
(__nFInstance)->id); \
|
||||
ogs_sbi_nf_instance_remove((__cTX).nf_instance); \
|
||||
} \
|
||||
\
|
||||
|
|
|
@ -364,10 +364,51 @@ char *ogs_sbi_client_apiroot(ogs_sbi_client_t *client)
|
|||
* Thanks Geek Hideout!
|
||||
* http://www.geekhideout.com/urlcode.shtml
|
||||
*/
|
||||
static char *url_decode(const char *str)
|
||||
char *ogs_sbi_url_encode(const char *str)
|
||||
{
|
||||
if (str != NULL) {
|
||||
char *pstr = (char*)str;
|
||||
char *pstr = (char *)str;
|
||||
char *buf = ogs_malloc(strlen(str) * 3 + 1);
|
||||
char *pbuf = buf;
|
||||
ogs_assert(buf);
|
||||
while (*pstr) {
|
||||
|
||||
if (*pstr == '"' ||
|
||||
*pstr == '(' ||
|
||||
*pstr == ')' ||
|
||||
*pstr == ',' ||
|
||||
*pstr == '/' ||
|
||||
*pstr == ':' ||
|
||||
*pstr == ';' ||
|
||||
*pstr == '<' ||
|
||||
*pstr == '=' ||
|
||||
*pstr == '>' ||
|
||||
*pstr == '?' ||
|
||||
*pstr == '@' ||
|
||||
*pstr == '[' ||
|
||||
*pstr == '\\' ||
|
||||
*pstr == ']' ||
|
||||
*pstr == '{' ||
|
||||
*pstr == '}') {
|
||||
*pbuf++ = '%';
|
||||
*pbuf++ = ogs_to_hex(*pstr >> 4);
|
||||
*pbuf++ = ogs_to_hex(*pstr & 15);
|
||||
} else
|
||||
*pbuf++ = *pstr;
|
||||
|
||||
pstr++;
|
||||
}
|
||||
*pbuf = '\0';
|
||||
return buf;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *ogs_sbi_url_decode(const char *str)
|
||||
{
|
||||
if (str != NULL) {
|
||||
char *pstr = (char *)str;
|
||||
char *buf = ogs_malloc(strlen(str) + 1);
|
||||
char *pbuf = buf;
|
||||
ogs_assert(buf);
|
||||
|
@ -396,7 +437,7 @@ char *ogs_sbi_parse_uri(char *uri, const char *delim, char **saveptr)
|
|||
{
|
||||
char *item = NULL;
|
||||
|
||||
item = url_decode(ogs_strtok_r(uri, delim, saveptr));
|
||||
item = ogs_sbi_url_decode(ogs_strtok_r(uri, delim, saveptr));
|
||||
if (!item) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@ char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h);
|
|||
char *ogs_sbi_client_apiroot(ogs_sbi_client_t *client);
|
||||
char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h);
|
||||
|
||||
char *ogs_sbi_url_encode(const char *str);
|
||||
char *ogs_sbi_url_decode(const char *str);
|
||||
|
||||
char *ogs_sbi_parse_uri(char *uri, const char *delim, char **saveptr);
|
||||
|
||||
bool ogs_sbi_getaddr_from_uri(
|
||||
|
|
|
@ -388,6 +388,23 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
|||
if (ogs_sbi_self()->discovery_config.no_service_names == false &&
|
||||
discovery_option->num_of_service_names) {
|
||||
|
||||
/*
|
||||
* Issues #1730
|
||||
* Send NF discovery query with service-names delimited with comma
|
||||
*
|
||||
* OpenAPI specification for sending NF discovery query with
|
||||
* "service-names" parameter is defined as folowing:
|
||||
* name: service-names
|
||||
* ...
|
||||
* style: form
|
||||
* explode: false
|
||||
*
|
||||
* According to OpenAPI specification, this means array items
|
||||
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||||
*
|
||||
* See also https://swagger.io/docs/specification/serialization/
|
||||
*/
|
||||
|
||||
/* send array items separated by a comma */
|
||||
char *v = ogs_sbi_discovery_option_build_service_names(
|
||||
discovery_option);
|
||||
|
@ -396,11 +413,47 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
|||
OGS_SBI_PARAM_SERVICE_NAMES, v);
|
||||
ogs_free(v);
|
||||
} else {
|
||||
ogs_warn("invalid service names failed[%d:%s]",
|
||||
ogs_warn("build failed: service-names[%d:%s]",
|
||||
discovery_option->num_of_service_names,
|
||||
discovery_option->service_names[0]);
|
||||
}
|
||||
}
|
||||
if (discovery_option->num_of_snssais) {
|
||||
char *v = ogs_sbi_discovery_option_build_snssais(discovery_option);
|
||||
if (v) {
|
||||
/*
|
||||
* In http.params, the CURL library automatically encodes the URL.
|
||||
* http.headers implements open5gs to directly encode URLs.
|
||||
*
|
||||
* Since it is http.params, the result is sent as is.
|
||||
*/
|
||||
ogs_sbi_header_set(request->http.params,
|
||||
OGS_SBI_PARAM_SNSSAIS, v);
|
||||
ogs_free(v);
|
||||
} else {
|
||||
ogs_error("build failed: snssais(%d)[SST:%d SD:0x%x]",
|
||||
discovery_option->num_of_snssais,
|
||||
discovery_option->snssais[0].sst,
|
||||
discovery_option->snssais[0].sd.v);
|
||||
}
|
||||
}
|
||||
if (discovery_option->dnn) {
|
||||
ogs_sbi_header_set(request->http.params,
|
||||
OGS_SBI_PARAM_DNN, discovery_option->dnn);
|
||||
}
|
||||
if (discovery_option->num_of_tai) {
|
||||
char *v = ogs_sbi_discovery_option_build_tai(discovery_option);
|
||||
if (v) {
|
||||
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_TAI, v);
|
||||
ogs_free(v);
|
||||
} else {
|
||||
ogs_error("build failed: tai(%d)[PLMN_ID:%06x,TAC:%d]",
|
||||
discovery_option->num_of_tai,
|
||||
ogs_plmn_id_hexdump(
|
||||
&discovery_option->tai[0].plmn_id),
|
||||
discovery_option->tai[0].tac.v);
|
||||
}
|
||||
}
|
||||
if (discovery_option->requester_features) {
|
||||
char *v = ogs_uint64_to_string(
|
||||
discovery_option->requester_features);
|
||||
|
@ -702,12 +755,47 @@ int ogs_sbi_parse_request(
|
|||
}
|
||||
} else if (!strcmp(ogs_hash_this_key(hi),
|
||||
OGS_SBI_PARAM_SERVICE_NAMES)) {
|
||||
/*
|
||||
* Issues #1730
|
||||
* Send NF discovery query with service-names delimited with comma
|
||||
*
|
||||
* OpenAPI specification for sending NF discovery query with
|
||||
* "service-names" parameter is defined as folowing:
|
||||
* name: service-names
|
||||
* ...
|
||||
* style: form
|
||||
* explode: false
|
||||
*
|
||||
* According to OpenAPI specification, this means array items
|
||||
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||||
*
|
||||
* See also https://swagger.io/docs/specification/serialization/
|
||||
*/
|
||||
char *v = ogs_hash_this_val(hi);
|
||||
if (v) {
|
||||
ogs_sbi_discovery_option_parse_service_names(
|
||||
discovery_option, v);
|
||||
discovery_option_presence = true;
|
||||
}
|
||||
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_SNSSAIS)) {
|
||||
char *v = ogs_hash_this_val(hi);
|
||||
if (v) {
|
||||
ogs_sbi_discovery_option_parse_snssais(discovery_option, v);
|
||||
discovery_option_presence = true;
|
||||
}
|
||||
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_DNN)) {
|
||||
char *v = ogs_hash_this_val(hi);
|
||||
|
||||
if (v) {
|
||||
ogs_sbi_discovery_option_set_dnn(discovery_option, v);
|
||||
discovery_option_presence = true;
|
||||
}
|
||||
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_TAI)) {
|
||||
char *v = ogs_hash_this_val(hi);
|
||||
if (v) {
|
||||
ogs_sbi_discovery_option_parse_tai(discovery_option, v);
|
||||
discovery_option_presence = true;
|
||||
}
|
||||
} else if (!strcmp(ogs_hash_this_key(hi),
|
||||
OGS_SBI_PARAM_REQUESTER_FEATURES)) {
|
||||
char *v = ogs_hash_this_val(hi);
|
||||
|
@ -2682,6 +2770,8 @@ void ogs_sbi_discovery_option_free(
|
|||
ogs_free(discovery_option->target_nf_instance_id);
|
||||
if (discovery_option->requester_nf_instance_id)
|
||||
ogs_free(discovery_option->requester_nf_instance_id);
|
||||
if (discovery_option->dnn)
|
||||
ogs_free(discovery_option->dnn);
|
||||
|
||||
for (i = 0; i < discovery_option->num_of_service_names; i++)
|
||||
ogs_free(discovery_option->service_names[i]);
|
||||
|
@ -2712,6 +2802,16 @@ void ogs_sbi_discovery_option_set_requester_nf_instance_id(
|
|||
ogs_strdup(requester_nf_instance_id);
|
||||
ogs_assert(discovery_option->requester_nf_instance_id);
|
||||
}
|
||||
void ogs_sbi_discovery_option_set_dnn(
|
||||
ogs_sbi_discovery_option_t *discovery_option, char *dnn)
|
||||
{
|
||||
ogs_assert(discovery_option);
|
||||
ogs_assert(dnn);
|
||||
|
||||
ogs_assert(!discovery_option->dnn);
|
||||
discovery_option->dnn = ogs_strdup(dnn);
|
||||
ogs_assert(discovery_option->dnn);
|
||||
}
|
||||
void ogs_sbi_discovery_option_add_service_names(
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
char *service_name)
|
||||
|
@ -2743,6 +2843,22 @@ char *ogs_sbi_discovery_option_build_service_names(
|
|||
return NULL;;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issues #1730
|
||||
* Send NF discovery query with service-names delimited with comma
|
||||
*
|
||||
* OpenAPI specification for sending NF discovery query with
|
||||
* "service-names" parameter is defined as folowing:
|
||||
* name: service-names
|
||||
* ...
|
||||
* style: form
|
||||
* explode: false
|
||||
*
|
||||
* According to OpenAPI specification, this means array items
|
||||
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||||
*
|
||||
* See also https://swagger.io/docs/specification/serialization/
|
||||
*/
|
||||
if (discovery_option->num_of_service_names > 1) {
|
||||
for (i = 1; i < discovery_option->num_of_service_names; i++)
|
||||
service_names = ogs_mstrcatf(
|
||||
|
@ -2763,9 +2879,29 @@ void ogs_sbi_discovery_option_parse_service_names(
|
|||
ogs_assert(discovery_option);
|
||||
ogs_assert(service_names);
|
||||
|
||||
v = ogs_strdup(service_names);
|
||||
ogs_assert(v);
|
||||
v = ogs_sbi_url_decode(service_names);
|
||||
if (!v) {
|
||||
ogs_error("ogs_sbi_url_decode() failed : service_names[%s]",
|
||||
service_names);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issues #1730
|
||||
* Send NF discovery query with service-names delimited with comma
|
||||
*
|
||||
* OpenAPI specification for sending NF discovery query with
|
||||
* "service-names" parameter is defined as folowing:
|
||||
* name: service-names
|
||||
* ...
|
||||
* style: form
|
||||
* explode: false
|
||||
*
|
||||
* According to OpenAPI specification, this means array items
|
||||
* should be delimited with a comma character (example: /users?id=3,4,5).
|
||||
*
|
||||
* See also https://swagger.io/docs/specification/serialization/
|
||||
*/
|
||||
token = ogs_strtok_r(v, ",", &saveptr);
|
||||
while (token != NULL) {
|
||||
ogs_sbi_discovery_option_add_service_names(discovery_option, token);
|
||||
|
@ -2774,3 +2910,205 @@ void ogs_sbi_discovery_option_parse_service_names(
|
|||
|
||||
ogs_free(v);
|
||||
}
|
||||
|
||||
void ogs_sbi_discovery_option_add_snssais(
|
||||
ogs_sbi_discovery_option_t *discovery_option, ogs_s_nssai_t *s_nssai)
|
||||
{
|
||||
ogs_assert(discovery_option);
|
||||
ogs_assert(s_nssai);
|
||||
|
||||
ogs_assert(discovery_option->num_of_snssais < OGS_MAX_NUM_OF_SLICE);
|
||||
|
||||
memcpy(&discovery_option->snssais[discovery_option->num_of_snssais],
|
||||
s_nssai, sizeof(ogs_s_nssai_t));
|
||||
discovery_option->num_of_snssais++;
|
||||
}
|
||||
char *ogs_sbi_discovery_option_build_snssais(
|
||||
ogs_sbi_discovery_option_t *discovery_option)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
char *v = NULL;
|
||||
int i;
|
||||
|
||||
ogs_assert(discovery_option);
|
||||
|
||||
item = cJSON_CreateArray();
|
||||
if (!item) {
|
||||
ogs_error("cJSON_CreateArray() failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < discovery_option->num_of_snssais; i++) {
|
||||
OpenAPI_snssai_t sNSSAI;
|
||||
cJSON *snssaiItem = NULL;
|
||||
|
||||
memset(&sNSSAI, 0, sizeof(sNSSAI));
|
||||
|
||||
sNSSAI.sst = discovery_option->snssais[i].sst;
|
||||
sNSSAI.sd = ogs_s_nssai_sd_to_string(discovery_option->snssais[i].sd);
|
||||
|
||||
snssaiItem = OpenAPI_snssai_convertToJSON(&sNSSAI);
|
||||
ogs_assert(snssaiItem);
|
||||
cJSON_AddItemToArray(item, snssaiItem);
|
||||
}
|
||||
|
||||
v = cJSON_PrintUnformatted(item);
|
||||
ogs_expect(v);
|
||||
cJSON_Delete(item);
|
||||
|
||||
return v;
|
||||
}
|
||||
void ogs_sbi_discovery_option_parse_snssais(
|
||||
ogs_sbi_discovery_option_t *discovery_option, char *snssais)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
cJSON *snssaiItem = NULL;
|
||||
char *v = NULL;
|
||||
|
||||
ogs_assert(discovery_option);
|
||||
ogs_assert(snssais);
|
||||
|
||||
v = ogs_sbi_url_decode(snssais);
|
||||
if (!v) {
|
||||
ogs_error("ogs_sbi_url_decode() failed : snssais[%s]", snssais);
|
||||
return;
|
||||
}
|
||||
|
||||
item = cJSON_Parse(v);
|
||||
if (!item) {
|
||||
ogs_error("Cannot parse snssais[%s]", snssais);
|
||||
ogs_free(v);
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_ArrayForEach(snssaiItem, item) {
|
||||
if (cJSON_IsObject(snssaiItem)) {
|
||||
OpenAPI_snssai_t *sNSSAI = OpenAPI_snssai_parseFromJSON(snssaiItem);
|
||||
|
||||
if (sNSSAI) {
|
||||
ogs_s_nssai_t s_nssai;
|
||||
|
||||
s_nssai.sst = sNSSAI->sst;
|
||||
s_nssai.sd = ogs_s_nssai_sd_from_string(sNSSAI->sd);
|
||||
|
||||
ogs_sbi_discovery_option_add_snssais(
|
||||
discovery_option, &s_nssai);
|
||||
|
||||
OpenAPI_snssai_free(sNSSAI);
|
||||
} else {
|
||||
ogs_error("OpenAPI_snssai_parseFromJSON() failed : snssais[%s]",
|
||||
snssais);
|
||||
}
|
||||
} else {
|
||||
ogs_error("Invalid cJSON Type in snssias[%s]", snssais);
|
||||
}
|
||||
}
|
||||
cJSON_Delete(item);
|
||||
|
||||
ogs_free(v);
|
||||
}
|
||||
|
||||
void ogs_sbi_discovery_option_add_tai(
|
||||
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai)
|
||||
{
|
||||
ogs_assert(discovery_option);
|
||||
ogs_assert(tai);
|
||||
|
||||
ogs_assert(discovery_option->num_of_tai < OGS_MAX_NUM_OF_TAI);
|
||||
|
||||
memcpy(&discovery_option->tai[discovery_option->num_of_tai],
|
||||
tai, sizeof(ogs_5gs_tai_t));
|
||||
discovery_option->num_of_tai++;
|
||||
}
|
||||
char *ogs_sbi_discovery_option_build_tai(
|
||||
ogs_sbi_discovery_option_t *discovery_option)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
char *v = NULL;
|
||||
int i;
|
||||
|
||||
ogs_assert(discovery_option);
|
||||
|
||||
item = cJSON_CreateArray();
|
||||
if (!item) {
|
||||
ogs_error("cJSON_CreateArray() failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < discovery_option->num_of_tai; i++) {
|
||||
OpenAPI_tai_t Tai;
|
||||
cJSON *taiItem = NULL;
|
||||
|
||||
memset(&Tai, 0, sizeof(Tai));
|
||||
|
||||
Tai.plmn_id = ogs_sbi_build_plmn_id(&discovery_option->tai[i].plmn_id);
|
||||
ogs_assert(Tai.plmn_id);
|
||||
Tai.tac = ogs_uint24_to_0string(discovery_option->tai[i].tac);
|
||||
ogs_assert(Tai.tac);
|
||||
|
||||
taiItem = OpenAPI_tai_convertToJSON(&Tai);
|
||||
ogs_assert(taiItem);
|
||||
cJSON_AddItemToArray(item, taiItem);
|
||||
|
||||
ogs_sbi_free_plmn_id(Tai.plmn_id);
|
||||
ogs_free(Tai.tac);
|
||||
}
|
||||
|
||||
v = cJSON_PrintUnformatted(item);
|
||||
ogs_expect(v);
|
||||
cJSON_Delete(item);
|
||||
|
||||
return v;
|
||||
}
|
||||
void ogs_sbi_discovery_option_parse_tai(
|
||||
ogs_sbi_discovery_option_t *discovery_option, char *tai)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
cJSON *taiItem = NULL;
|
||||
char *v = NULL;
|
||||
|
||||
ogs_assert(discovery_option);
|
||||
ogs_assert(tai);
|
||||
|
||||
v = ogs_sbi_url_decode(tai);
|
||||
if (!v) {
|
||||
ogs_error("ogs_sbi_url_decode() failed : tai[%s]", tai);
|
||||
return;
|
||||
}
|
||||
|
||||
item = cJSON_Parse(v);
|
||||
if (!item) {
|
||||
ogs_error("Cannot parse tai[%s]", tai);
|
||||
ogs_free(v);
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_ArrayForEach(taiItem, item) {
|
||||
if (cJSON_IsObject(taiItem)) {
|
||||
OpenAPI_tai_t *Tai = OpenAPI_tai_parseFromJSON(taiItem);
|
||||
|
||||
if (Tai) {
|
||||
ogs_5gs_tai_t tai;
|
||||
|
||||
memset(&tai, 0, sizeof(tai));
|
||||
|
||||
if (Tai->plmn_id)
|
||||
ogs_sbi_parse_plmn_id(&tai.plmn_id, Tai->plmn_id);
|
||||
if (Tai->tac)
|
||||
tai.tac = ogs_uint24_from_string(Tai->tac);
|
||||
|
||||
ogs_sbi_discovery_option_add_tai(discovery_option, &tai);
|
||||
|
||||
OpenAPI_tai_free(Tai);
|
||||
} else {
|
||||
ogs_error("OpenAPI_snssai_parseFromJSON() failed : tai[%s]",
|
||||
tai);
|
||||
}
|
||||
} else {
|
||||
ogs_error("Invalid cJSON Type in snssias[%s]", tai);
|
||||
}
|
||||
}
|
||||
cJSON_Delete(item);
|
||||
|
||||
ogs_free(v);
|
||||
}
|
||||
|
|
|
@ -279,6 +279,12 @@ extern "C" {
|
|||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_REQUESTER_NF_INSTANCE_ID
|
||||
#define OGS_SBI_CUSTOM_DISCOVERY_SERVICE_NAMES \
|
||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_SERVICE_NAMES
|
||||
#define OGS_SBI_CUSTOM_DISCOVERY_SNSSAIS \
|
||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_SNSSAIS
|
||||
#define OGS_SBI_CUSTOM_DISCOVERY_DNN \
|
||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_DNN
|
||||
#define OGS_SBI_CUSTOM_DISCOVERY_TAI \
|
||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_TAI
|
||||
#define OGS_SBI_CUSTOM_DISCOVERY_REQUESTER_FEATURES \
|
||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_REQUESTER_FEATURES
|
||||
#define OGS_SBI_CUSTOM_PRODUCER_ID \
|
||||
|
@ -314,6 +320,8 @@ extern "C" {
|
|||
#define OGS_SBI_PARAM_PLMN_ID "plmn-id"
|
||||
#define OGS_SBI_PARAM_SINGLE_NSSAI "single-nssai"
|
||||
#define OGS_SBI_PARAM_SNSSAI "snssai"
|
||||
#define OGS_SBI_PARAM_SNSSAIS "snssais"
|
||||
#define OGS_SBI_PARAM_TAI "tai"
|
||||
#define OGS_SBI_PARAM_SLICE_INFO_REQUEST_FOR_PDU_SESSION \
|
||||
"slice-info-request-for-pdu-session"
|
||||
#define OGS_SBI_PARAM_IPV4ADDR "ipv4Addr"
|
||||
|
@ -407,6 +415,12 @@ typedef struct ogs_sbi_discovery_option_s {
|
|||
int num_of_service_names;
|
||||
char *service_names[OGS_SBI_MAX_NUM_OF_SERVICE_TYPE];
|
||||
|
||||
int num_of_snssais;
|
||||
ogs_s_nssai_t snssais[OGS_MAX_NUM_OF_SLICE];
|
||||
char *dnn;
|
||||
int num_of_tai;
|
||||
ogs_5gs_tai_t tai[OGS_MAX_NUM_OF_TAI];
|
||||
|
||||
uint64_t requester_features;
|
||||
} ogs_sbi_discovery_option_t;
|
||||
|
||||
|
@ -591,6 +605,8 @@ void ogs_sbi_discovery_option_set_target_nf_instance_id(
|
|||
void ogs_sbi_discovery_option_set_requester_nf_instance_id(
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
char *requester_nf_instance_id);
|
||||
void ogs_sbi_discovery_option_set_dnn(
|
||||
ogs_sbi_discovery_option_t *discovery_option, char *dnn);
|
||||
|
||||
void ogs_sbi_discovery_option_add_service_names(
|
||||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
|
@ -601,6 +617,20 @@ void ogs_sbi_discovery_option_parse_service_names(
|
|||
ogs_sbi_discovery_option_t *discovery_option,
|
||||
char *service_names);
|
||||
|
||||
void ogs_sbi_discovery_option_add_snssais(
|
||||
ogs_sbi_discovery_option_t *discovery_option, ogs_s_nssai_t *s_nssai);
|
||||
char *ogs_sbi_discovery_option_build_snssais(
|
||||
ogs_sbi_discovery_option_t *discovery_option);
|
||||
void ogs_sbi_discovery_option_parse_snssais(
|
||||
ogs_sbi_discovery_option_t *discovery_option, char *snssais);
|
||||
|
||||
void ogs_sbi_discovery_option_add_tai(
|
||||
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai);
|
||||
char *ogs_sbi_discovery_option_build_tai(
|
||||
ogs_sbi_discovery_option_t *discovery_option);
|
||||
void ogs_sbi_discovery_option_parse_tai(
|
||||
ogs_sbi_discovery_option_t *discovery_option, char *tai);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -777,7 +777,7 @@ static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info)
|
|||
ogs_error("No TaiItem->tac");
|
||||
if (TaiItem) {
|
||||
if (TaiItem->plmn_id)
|
||||
ogs_free(TaiItem->plmn_id);
|
||||
ogs_sbi_free_plmn_id(TaiItem->plmn_id);
|
||||
ogs_free(TaiItem);
|
||||
}
|
||||
free_smf_info(SmfInfo);
|
||||
|
@ -972,7 +972,7 @@ static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info)
|
|||
ogs_error("No TaiItem->tac");
|
||||
if (TaiItem) {
|
||||
if (TaiItem->plmn_id)
|
||||
ogs_free(TaiItem->plmn_id);
|
||||
ogs_sbi_free_plmn_id(TaiItem->plmn_id);
|
||||
ogs_free(TaiItem);
|
||||
}
|
||||
free_amf_info(AmfInfo);
|
||||
|
|
|
@ -274,6 +274,72 @@ int ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact)
|
|||
nf_instance->id);
|
||||
}
|
||||
|
||||
if (discovery_option && discovery_option->num_of_snssais) {
|
||||
bool rc = false;
|
||||
char *v = ogs_sbi_discovery_option_build_snssais(
|
||||
discovery_option);
|
||||
ogs_expect(v);
|
||||
|
||||
if (v) {
|
||||
char *encoded = ogs_sbi_url_encode(v);
|
||||
ogs_expect(encoded);
|
||||
|
||||
if (encoded) {
|
||||
/*
|
||||
* In http.params, the CURL library automatically encodes the URL.
|
||||
* http.headers implements open5gs to directly encode URLs.
|
||||
*
|
||||
* Since it is http.headers,
|
||||
* we need to encode `v` using ogs_sbi_url_encode();
|
||||
*/
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CUSTOM_DISCOVERY_SNSSAIS, encoded);
|
||||
ogs_free(encoded);
|
||||
|
||||
rc = true;
|
||||
}
|
||||
ogs_free(v);
|
||||
}
|
||||
|
||||
if (rc == false)
|
||||
ogs_error("build failed: snssais(%d)[SST:%d SD:0x%x]",
|
||||
discovery_option->num_of_snssais,
|
||||
discovery_option->snssais[0].sst,
|
||||
discovery_option->snssais[0].sd.v);
|
||||
}
|
||||
|
||||
if (discovery_option && discovery_option->dnn) {
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CUSTOM_DISCOVERY_DNN, discovery_option->dnn);
|
||||
}
|
||||
|
||||
if (discovery_option && discovery_option->num_of_tai) {
|
||||
bool rc = false;
|
||||
char *v = ogs_sbi_discovery_option_build_tai(discovery_option);
|
||||
ogs_expect(v);
|
||||
|
||||
if (v) {
|
||||
char *encoded = ogs_sbi_url_encode(v);
|
||||
ogs_expect(encoded);
|
||||
|
||||
if (encoded) {
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CUSTOM_DISCOVERY_TAI, encoded);
|
||||
ogs_free(encoded);
|
||||
|
||||
rc = true;
|
||||
}
|
||||
ogs_free(v);
|
||||
}
|
||||
|
||||
if (rc == false)
|
||||
ogs_error("build failed: tai(%d)[PLMN_ID:%06x,TAC:%d]",
|
||||
discovery_option->num_of_tai,
|
||||
ogs_plmn_id_hexdump(
|
||||
&discovery_option->tai[0].plmn_id),
|
||||
discovery_option->tai[0].tac.v);
|
||||
}
|
||||
|
||||
if (discovery_option &&
|
||||
discovery_option->requester_features) {
|
||||
char *v = ogs_uint64_to_string(
|
||||
|
@ -615,19 +681,39 @@ static void build_default_discovery_parameter(
|
|||
if (ogs_sbi_self()->discovery_config.
|
||||
no_service_names == false &&
|
||||
discovery_option->num_of_service_names) {
|
||||
bool rc = false;
|
||||
|
||||
/* send array items separated by a comma */
|
||||
char *v = ogs_sbi_discovery_option_build_service_names(
|
||||
discovery_option);
|
||||
ogs_expect(v);
|
||||
|
||||
if (v) {
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CUSTOM_DISCOVERY_SERVICE_NAMES, v);
|
||||
char *encoded = ogs_sbi_url_encode(v);
|
||||
ogs_expect(encoded);
|
||||
|
||||
if (encoded) {
|
||||
/*
|
||||
* In http.params, the CURL library automatically encodes the URL.
|
||||
* http.headers implements open5gs to directly encode URLs.
|
||||
*
|
||||
* Since it is http.headers,
|
||||
* we need to encode `v` using ogs_sbi_url_encode();
|
||||
*/
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CUSTOM_DISCOVERY_SERVICE_NAMES, encoded);
|
||||
ogs_free(encoded);
|
||||
|
||||
rc = true;
|
||||
}
|
||||
ogs_free(v);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if (rc == false)
|
||||
ogs_warn("invalid service names failed[%d:%s]",
|
||||
discovery_option->num_of_service_names,
|
||||
discovery_option->service_names[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2160,8 +2160,6 @@ amf_sess_t *amf_sess_cycle(amf_sess_t *sess)
|
|||
return ogs_pool_cycle(&amf_sess_pool, sess);
|
||||
}
|
||||
|
||||
static bool check_smf_info(ogs_sbi_nf_info_t *nf_info, void *context);
|
||||
|
||||
void amf_sbi_select_nf(
|
||||
ogs_sbi_object_t *sbi_object,
|
||||
ogs_sbi_service_type_e service_type,
|
||||
|
@ -2170,7 +2168,6 @@ void amf_sbi_select_nf(
|
|||
{
|
||||
OpenAPI_nf_type_e target_nf_type = OpenAPI_nf_type_NULL;
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
ogs_sbi_nf_info_t *nf_info = NULL;
|
||||
amf_sess_t *sess = NULL;
|
||||
|
||||
ogs_assert(sbi_object);
|
||||
|
@ -2198,22 +2195,6 @@ void amf_sbi_select_nf(
|
|||
false)
|
||||
continue;
|
||||
|
||||
if ((nf_instance->nf_type == OpenAPI_nf_type_SMF) &&
|
||||
(ogs_list_count(&nf_instance->nf_info_list) > 0)) {
|
||||
|
||||
ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
|
||||
if (nf_info->nf_type != nf_instance->nf_type)
|
||||
continue;
|
||||
if (check_smf_info(nf_info, sess) == false)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nf_info)
|
||||
continue;
|
||||
}
|
||||
|
||||
OGS_SBI_SETUP_NF_INSTANCE(
|
||||
sbi_object->service_type_array[service_type], nf_instance);
|
||||
break;
|
||||
|
@ -2551,90 +2532,6 @@ static void stats_remove_amf_session(void)
|
|||
ogs_info("[Removed] Number of AMF-Sessions is now %d", num_of_amf_sess);
|
||||
}
|
||||
|
||||
static bool check_smf_info_s_nssai(
|
||||
ogs_sbi_smf_info_t *smf_info, amf_sess_t *sess);
|
||||
static bool check_smf_info_nr_tai(
|
||||
ogs_sbi_smf_info_t *smf_info, amf_sess_t *sess);
|
||||
|
||||
static bool check_smf_info(ogs_sbi_nf_info_t *nf_info, void *context)
|
||||
{
|
||||
amf_sess_t *sess = NULL;
|
||||
|
||||
ogs_assert(nf_info);
|
||||
ogs_assert(nf_info->nf_type == OpenAPI_nf_type_SMF);
|
||||
sess = context;
|
||||
ogs_assert(sess);
|
||||
|
||||
if (check_smf_info_s_nssai(&nf_info->smf, sess) == false)
|
||||
return false;
|
||||
if (check_smf_info_nr_tai(&nf_info->smf, sess) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_smf_info_s_nssai(
|
||||
ogs_sbi_smf_info_t *smf_info, amf_sess_t *sess)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(sess->dnn);
|
||||
ogs_assert(smf_info);
|
||||
|
||||
for (i = 0; i < smf_info->num_of_slice; i++) {
|
||||
if (sess->s_nssai.sst == smf_info->slice[i].s_nssai.sst &&
|
||||
sess->s_nssai.sd.v == smf_info->slice[i].s_nssai.sd.v) {
|
||||
|
||||
for (j = 0; j < smf_info->slice[i].num_of_dnn; j++) {
|
||||
if (ogs_strcasecmp(sess->dnn, smf_info->slice[i].dnn[j]) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_smf_info_nr_tai(
|
||||
ogs_sbi_smf_info_t *smf_info, amf_sess_t *sess)
|
||||
{
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
int i, j;
|
||||
|
||||
ogs_assert(sess);
|
||||
amf_ue = sess->amf_ue;
|
||||
ogs_assert(amf_ue);
|
||||
ogs_assert(smf_info);
|
||||
|
||||
if (smf_info->num_of_nr_tai == 0 && smf_info->num_of_nr_tai_range == 0)
|
||||
return true;
|
||||
|
||||
for (i = 0; i < smf_info->num_of_nr_tai; i++) {
|
||||
if (memcmp(&amf_ue->nr_tai.plmn_id,
|
||||
&smf_info->nr_tai[i].plmn_id, OGS_PLMN_ID_LEN) == 0) {
|
||||
if (amf_ue->nr_tai.tac.v == smf_info->nr_tai[i].tac.v)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < smf_info->num_of_nr_tai_range; i++) {
|
||||
if (memcmp(&amf_ue->nr_tai.plmn_id,
|
||||
&smf_info->nr_tai_range[i].plmn_id, OGS_PLMN_ID_LEN) == 0) {
|
||||
for (j = 0; j < smf_info->nr_tai_range[i].num_of_tac_range; j++) {
|
||||
if (amf_ue->nr_tai.tac.v >=
|
||||
smf_info->nr_tai_range[i].start[j].v &&
|
||||
amf_ue->nr_tai.tac.v <=
|
||||
smf_info->nr_tai_range[i].end[j].v) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issues #2482
|
||||
*
|
||||
|
|
|
@ -1244,14 +1244,27 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
|||
sess->s_nssai.sst = selected_slice->s_nssai.sst;
|
||||
sess->s_nssai.sd.v = selected_slice->s_nssai.sd.v;
|
||||
|
||||
ogs_info("UE SUPI[%s] DNN[%s] S_NSSAI[SST:%d SD:0x%x]",
|
||||
amf_ue->supi, sess->dnn, sess->s_nssai.sst, sess->s_nssai.sd.v);
|
||||
ogs_info("UE SUPI[%s] DNN[%s] S_NSSAI[SST:%d SD:0x%x] "
|
||||
"smContextRef [%s]",
|
||||
amf_ue->supi, sess->dnn, sess->s_nssai.sst, sess->s_nssai.sd.v,
|
||||
sess->sm_context_ref ? sess->sm_context_ref : "NULL");
|
||||
|
||||
if (!SESSION_CONTEXT_IN_SMF(sess)) {
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
ogs_sbi_service_type_e service_type =
|
||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION;
|
||||
|
||||
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||||
|
||||
discovery_option = ogs_sbi_discovery_option_new();
|
||||
ogs_assert(discovery_option);
|
||||
|
||||
ogs_sbi_discovery_option_add_snssais(
|
||||
discovery_option, &sess->s_nssai);
|
||||
ogs_sbi_discovery_option_set_dnn(discovery_option, sess->dnn);
|
||||
ogs_sbi_discovery_option_add_tai(
|
||||
discovery_option, &amf_ue->nr_tai);
|
||||
|
||||
nf_instance = sess->sbi.
|
||||
service_type_array[service_type].nf_instance;
|
||||
if (!nf_instance) {
|
||||
|
@ -1263,21 +1276,29 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
|||
&sess->sbi,
|
||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION,
|
||||
requester_nf_type,
|
||||
NULL);
|
||||
discovery_option);
|
||||
nf_instance = sess->sbi.
|
||||
service_type_array[service_type].nf_instance;
|
||||
}
|
||||
|
||||
if (!nf_instance)
|
||||
ogs_info("No SMF Instance");
|
||||
else
|
||||
ogs_info("SMF Instance [%s]", nf_instance->id);
|
||||
} else
|
||||
ogs_info("SMF Instance [%s]", nf_instance->id);
|
||||
|
||||
if (nf_instance) {
|
||||
r = amf_sess_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION,
|
||||
discovery_option,
|
||||
amf_nsmf_pdusession_build_create_sm_context,
|
||||
sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
} else {
|
||||
r = amf_sess_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NNSSF_NSSELECTION, NULL,
|
||||
OGS_SBI_SERVICE_TYPE_NNSSF_NSSELECTION,
|
||||
discovery_option,
|
||||
amf_nnssf_nsselection_build_get, sess, 0, NULL);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
|
|
|
@ -29,6 +29,7 @@ int amf_nnssf_nsselection_handle_get(
|
|||
OpenAPI_uri_scheme_e scheme = OpenAPI_uri_scheme_NULL;
|
||||
ogs_sbi_client_t *client = NULL, *scp_client = NULL;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||||
|
||||
OpenAPI_authorized_network_slice_info_t *AuthorizedNetworkSliceInfo = NULL;
|
||||
OpenAPI_nsi_information_t *NsiInformation = NULL;
|
||||
|
@ -87,6 +88,13 @@ int amf_nnssf_nsselection_handle_get(
|
|||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
discovery_option = ogs_sbi_discovery_option_new();
|
||||
ogs_assert(discovery_option);
|
||||
|
||||
ogs_sbi_discovery_option_add_snssais(discovery_option, &sess->s_nssai);
|
||||
ogs_sbi_discovery_option_set_dnn(discovery_option, sess->dnn);
|
||||
ogs_sbi_discovery_option_add_tai(discovery_option, &amf_ue->nr_tai);
|
||||
|
||||
if (sess->nssf.nrf.id)
|
||||
ogs_free(sess->nssf.nrf.id);
|
||||
sess->nssf.nrf.id = ogs_strdup(NsiInformation->nrf_id);
|
||||
|
@ -101,7 +109,7 @@ int amf_nnssf_nsselection_handle_get(
|
|||
param.nrf_uri.nrf.id = sess->nssf.nrf.id;
|
||||
|
||||
r = amf_sess_sbi_discover_and_send(
|
||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, discovery_option,
|
||||
amf_nsmf_pdusession_build_create_sm_context,
|
||||
sess, AMF_CREATE_SM_CONTEXT_NO_STATE, ¶m);
|
||||
ogs_expect(r == OGS_OK);
|
||||
|
@ -115,6 +123,9 @@ int amf_nnssf_nsselection_handle_get(
|
|||
amf_ue, OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
|
||||
ogs_sbi_discovery_option_free(discovery_option);
|
||||
|
||||
return OGS_ERROR;;
|
||||
}
|
||||
|
||||
|
@ -128,7 +139,7 @@ int amf_nnssf_nsselection_handle_get(
|
|||
ogs_freeaddrinfo(addr);
|
||||
|
||||
r = amf_sess_sbi_discover_by_nsi(
|
||||
sess, OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL);
|
||||
sess, OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, discovery_option);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
}
|
||||
|
|
|
@ -756,6 +756,22 @@ bool nrf_nnrf_handle_nf_discover(
|
|||
ogs_debug("[%d] service-names[%s]", i,
|
||||
discovery_option->service_names[i]);
|
||||
}
|
||||
if (discovery_option->num_of_snssais) {
|
||||
for (i = 0; i < discovery_option->num_of_snssais; i++)
|
||||
ogs_debug("[%d] snssais[SST:%d SD:0x%x]", i,
|
||||
discovery_option->snssais[i].sst,
|
||||
discovery_option->snssais[i].sd.v);
|
||||
}
|
||||
if (discovery_option->dnn) {
|
||||
ogs_debug("dnn[%s]", discovery_option->dnn);
|
||||
}
|
||||
if (discovery_option->num_of_tai) {
|
||||
for (i = 0; i < discovery_option->num_of_tai; i++)
|
||||
ogs_debug("[%d] tai[PLMN_ID:%06x,TAC:%d]", i,
|
||||
ogs_plmn_id_hexdump(
|
||||
&discovery_option->tai[0].plmn_id),
|
||||
discovery_option->tai[0].tac.v);
|
||||
}
|
||||
if (discovery_option->requester_features) {
|
||||
ogs_debug("requester-features[0x%llx]",
|
||||
(long long)discovery_option->requester_features);
|
||||
|
|
|
@ -283,6 +283,8 @@ void scp_assoc_remove(scp_assoc_t *assoc)
|
|||
ogs_sbi_client_remove(assoc->client);
|
||||
if (assoc->nrf_client)
|
||||
ogs_sbi_client_remove(assoc->nrf_client);
|
||||
if (assoc->discovery_option)
|
||||
ogs_sbi_discovery_option_free(assoc->discovery_option);
|
||||
|
||||
ogs_pool_free(&scp_assoc_pool, assoc);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct scp_assoc_s {
|
|||
ogs_sbi_request_t *request;
|
||||
ogs_sbi_service_type_e service_type;
|
||||
OpenAPI_nf_type_e requester_nf_type;
|
||||
ogs_sbi_discovery_option_t *discovery_option;
|
||||
|
||||
ogs_sbi_nf_instance_t *nf_service_producer;
|
||||
} scp_assoc_t;
|
||||
|
|
|
@ -201,6 +201,14 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
|
|||
service_type = ogs_sbi_service_type_from_name(
|
||||
discovery_option->service_names[0]);
|
||||
}
|
||||
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_SNSSAIS)) {
|
||||
if (val)
|
||||
ogs_sbi_discovery_option_parse_snssais(discovery_option, val);
|
||||
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_DNN)) {
|
||||
ogs_sbi_discovery_option_set_dnn(discovery_option, val);
|
||||
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_TAI)) {
|
||||
if (val)
|
||||
ogs_sbi_discovery_option_parse_tai(discovery_option, val);
|
||||
} else if (!strcasecmp(key,
|
||||
OGS_SBI_CUSTOM_DISCOVERY_REQUESTER_FEATURES)) {
|
||||
if (val)
|
||||
|
@ -466,18 +474,46 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
|
|||
ogs_assert(assoc->service_type);
|
||||
assoc->requester_nf_type = requester_nf_type;
|
||||
ogs_assert(assoc->requester_nf_type);
|
||||
assoc->discovery_option = discovery_option;
|
||||
ogs_assert(assoc->discovery_option);
|
||||
|
||||
ogs_assert(target_nf_type);
|
||||
ogs_assert(discovery_option);
|
||||
|
||||
if (!discovery_option->num_of_service_names) {
|
||||
ogs_error("No service names");
|
||||
scp_assoc_remove(assoc);
|
||||
return OGS_ERROR;
|
||||
} else if (discovery_option->num_of_service_names > 1) {
|
||||
/*
|
||||
* TS29.500
|
||||
* 6.10.3 NF Discovery and Selection for indirect communication
|
||||
* with Delegated Discovery
|
||||
* 6.10.3.2 Conveyance of NF Discovery Factors
|
||||
*
|
||||
* If the NF service consumer includes more than one service name in the
|
||||
* 3gpp-Sbi-Discovery-service-names header, the service name corresponding
|
||||
* to the service request shall be listed as the first service name
|
||||
* in the header.
|
||||
*
|
||||
* NOTE 3: The SCP can assume that the service request corresponds
|
||||
* to the first service name in the header.
|
||||
*/
|
||||
int i;
|
||||
|
||||
for (i = 1; i < discovery_option->num_of_service_names; i++)
|
||||
ogs_free(discovery_option->service_names[i]);
|
||||
discovery_option->num_of_service_names = 1;
|
||||
|
||||
ogs_error("NOTE 3: The SCP can assume that the service request "
|
||||
"corresponds to the first service name in the header "
|
||||
"in TS29.500");
|
||||
}
|
||||
|
||||
nrf_request = ogs_nnrf_disc_build_discover(
|
||||
target_nf_type, requester_nf_type, discovery_option);
|
||||
if (!nrf_request) {
|
||||
ogs_error("ogs_nnrf_disc_build_discover() failed");
|
||||
|
||||
ogs_sbi_discovery_option_free(discovery_option);
|
||||
scp_assoc_remove(assoc);
|
||||
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -486,15 +522,12 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
|
|||
ogs_error("ogs_sbi_client_send_request() failed");
|
||||
|
||||
scp_assoc_remove(assoc);
|
||||
|
||||
ogs_sbi_request_free(nrf_request);
|
||||
ogs_sbi_discovery_option_free(discovery_option);
|
||||
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
ogs_sbi_request_free(nrf_request);
|
||||
ogs_sbi_discovery_option_free(discovery_option);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
@ -577,7 +610,9 @@ static int discover_handler(
|
|||
ogs_sbi_stream_t *stream = NULL;
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
ogs_sbi_service_type_e service_type = OGS_SBI_SERVICE_TYPE_NULL;
|
||||
OpenAPI_nf_type_e target_nf_type = OpenAPI_nf_type_NULL;
|
||||
OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
|
||||
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||||
|
||||
ogs_sbi_request_t scp_request;
|
||||
char *apiroot = NULL;
|
||||
|
@ -592,8 +627,12 @@ static int discover_handler(
|
|||
ogs_assert(request);
|
||||
service_type = assoc->service_type;
|
||||
ogs_assert(service_type);
|
||||
target_nf_type = ogs_sbi_service_type_to_nf_type(service_type);
|
||||
ogs_assert(target_nf_type);
|
||||
requester_nf_type = assoc->requester_nf_type;
|
||||
ogs_assert(requester_nf_type);
|
||||
discovery_option = assoc->discovery_option;
|
||||
ogs_assert(discovery_option);
|
||||
|
||||
if (status != OGS_OK) {
|
||||
|
||||
|
@ -631,8 +670,8 @@ static int discover_handler(
|
|||
|
||||
ogs_nnrf_disc_handle_nf_discover_search_result(message.SearchResult);
|
||||
|
||||
nf_instance = ogs_sbi_nf_instance_find_by_service_type(
|
||||
service_type, requester_nf_type);
|
||||
nf_instance = ogs_sbi_nf_instance_find_by_discovery_param(
|
||||
target_nf_type, requester_nf_type, discovery_option);
|
||||
if (!nf_instance) {
|
||||
strerror = ogs_msprintf("(NF discover) No NF-Instance [%s:%s]",
|
||||
ogs_sbi_service_type_to_name(service_type),
|
||||
|
|
|
@ -820,6 +820,20 @@ static void sbi_message_test8(abts_case *tc, void *data)
|
|||
ogs_sbi_service_type_from_name(OGS_SBI_SERVICE_NAME_NNSSAAF_NSSAA));
|
||||
}
|
||||
|
||||
static void sbi_message_test9(abts_case *tc, void *data)
|
||||
{
|
||||
const char *original = "{\"sst\": 1, \"sd\": \"A08923\"}";
|
||||
char *encoded = ogs_sbi_url_encode(original);
|
||||
char *decoded = ogs_sbi_url_decode(encoded);
|
||||
|
||||
ABTS_STR_EQUAL(tc,
|
||||
"%7B%22sst%22%3A 1%2C %22sd%22%3A %22A08923%22%7D", encoded);
|
||||
ABTS_STR_EQUAL(tc, original, decoded);
|
||||
|
||||
ogs_free(encoded);
|
||||
ogs_free(decoded);
|
||||
}
|
||||
|
||||
abts_suite *test_sbi_message(abts_suite *suite)
|
||||
{
|
||||
suite = ADD_SUITE(suite)
|
||||
|
@ -832,6 +846,7 @@ abts_suite *test_sbi_message(abts_suite *suite)
|
|||
abts_run_test(suite, sbi_message_test6, NULL);
|
||||
abts_run_test(suite, sbi_message_test7, NULL);
|
||||
abts_run_test(suite, sbi_message_test8, NULL);
|
||||
abts_run_test(suite, sbi_message_test9, NULL);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue