Move src/../nf-sm.[ch] to lib/sbi/nf-sm.[ch]

This commit is contained in:
Sukchan Lee 2022-08-12 14:03:53 +09:00
parent ec9fe7b31d
commit e6a14cb73d
278 changed files with 2939 additions and 12471 deletions

View File

@ -38,11 +38,11 @@ libapp = library('ogsapp',
version : libogslib_version, version : libogslib_version,
c_args : '-DOGS_APP_COMPILATION', c_args : '-DOGS_APP_COMPILATION',
include_directories : [libapp_inc, libinc], include_directories : [libapp_inc, libinc],
dependencies : [libcore_dep, yaml_dep], dependencies : [libproto_dep, yaml_dep],
install : true) install : true)
libapp_dep = declare_dependency( libapp_dep = declare_dependency(
link_with : libapp, link_with : libapp,
include_directories : [libapp_inc, libinc], include_directories : [libapp_inc, libinc],
dependencies : [libcore_dep, yaml_dep], dependencies : [libproto_dep, yaml_dep],
) )

View File

@ -20,7 +20,7 @@
#ifndef OGS_APP_H #ifndef OGS_APP_H
#define OGS_APP_H #define OGS_APP_H
#include "ogs-core.h" #include "ogs-proto.h"
#define OGS_APP_INSIDE #define OGS_APP_INSIDE

View File

@ -170,16 +170,6 @@ static void app_context_prepare(void)
#define USRSCTP_LOCAL_UDP_PORT 9899 #define USRSCTP_LOCAL_UDP_PORT 9899
self.usrsctp.udp_port = USRSCTP_LOCAL_UDP_PORT; self.usrsctp.udp_port = USRSCTP_LOCAL_UDP_PORT;
self.sctp.heartbit_interval = 5000; /* 5 seconds */
self.sctp.sack_delay = 200; /* 200 ms */
self.sctp.rto_initial = 3000; /* 3 seconds */
self.sctp.rto_min = 1000; /* 1 seconds */
self.sctp.rto_max = 5000; /* 5 seconds */
self.sctp.max_num_of_ostreams = OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
self.sctp.max_num_of_istreams = 65535;
self.sctp.max_attempts = 4;
self.sctp.max_initial_timeout = 8000; /* 8 seconds */
self.sockopt.no_delay = true; self.sockopt.no_delay = true;
#define MAX_NUM_OF_UE 1024 /* Num of UEs */ #define MAX_NUM_OF_UE 1024 /* Num of UEs */
@ -379,48 +369,6 @@ int ogs_app_context_parse_config(void)
} else } else
ogs_warn("unknown key `%s`", sockopt_key); ogs_warn("unknown key `%s`", sockopt_key);
} }
} else if (!strcmp(root_key, "sctp")) {
ogs_yaml_iter_t sctp_iter;
ogs_yaml_iter_recurse(&root_iter, &sctp_iter);
while (ogs_yaml_iter_next(&sctp_iter)) {
const char *sctp_key = ogs_yaml_iter_key(&sctp_iter);
ogs_assert(sctp_key);
if (!strcmp(sctp_key, "heartbit_interval")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.sctp.heartbit_interval = atoi(v);
} else if (!strcmp(sctp_key, "sack_delay")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.sctp.sack_delay = atoi(v);
} else if (!strcmp(sctp_key, "rto_initial")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.sctp.rto_initial = atoi(v);
} else if (!strcmp(sctp_key, "rto_min")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.sctp.rto_min = atoi(v);
} else if (!strcmp(sctp_key, "rto_max")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.sctp.rto_max = atoi(v);
} else if (!strcmp(sctp_key, "max_num_of_ostreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v)
self.sctp.max_num_of_ostreams = atoi(v);
} else if (!strcmp(sctp_key, "max_num_of_istreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v)
self.sctp.max_num_of_istreams = atoi(v);
} else if (!strcmp(sctp_key, "max_attempts")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.sctp.max_attempts = atoi(v);
} else if (!strcmp(sctp_key, "max_initial_timeout")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v)
self.sctp.max_initial_timeout = atoi(v);
} else if (!strcmp(sctp_key, "usrsctp_udp_port")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.usrsctp.udp_port = atoi(v);
} else
ogs_warn("unknown key `%s`", sctp_key);
}
} else if (!strcmp(root_key, "max")) { } else if (!strcmp(root_key, "max")) {
ogs_yaml_iter_t max_iter; ogs_yaml_iter_t max_iter;
ogs_yaml_iter_recurse(&root_iter, &max_iter); ogs_yaml_iter_recurse(&root_iter, &max_iter);

View File

@ -85,18 +85,6 @@ typedef struct ogs_app_context_s {
int l_linger; int l_linger;
} sockopt; } sockopt;
struct {
int heartbit_interval;
int sack_delay;
int rto_initial;
int rto_min;
int rto_max;
int max_num_of_ostreams;
int max_num_of_istreams;
int max_attempts;
int max_initial_timeout;
} sctp;
struct { struct {
int udp_port; int udp_port;
} usrsctp; } usrsctp;

View File

@ -40,7 +40,7 @@ int get_asn1c_environment_version(void); /* Run-time version */
#define REALLOC(oldptr, size) realloc(oldptr, size) #define REALLOC(oldptr, size) realloc(oldptr, size)
#define FREEMEM(ptr) free(ptr) #define FREEMEM(ptr) free(ptr)
#else #else
#include "ogs-core.h" #include "ogs-proto.h"
static ogs_inline void *ogs_asn_malloc(size_t size, const char *file_line) static ogs_inline void *ogs_asn_malloc(size_t size, const char *file_line)
{ {

View File

@ -171,10 +171,10 @@ libasn1c_common = library('ogsasn1c-common',
version : libogslib_version, version : libogslib_version,
c_args : libasn1c_common_cc_flags, c_args : libasn1c_common_cc_flags,
include_directories : libasn1c_common_inc, include_directories : libasn1c_common_inc,
dependencies : libcore_dep, dependencies : libproto_dep,
install : true) install : true)
libasn1c_common_dep = declare_dependency( libasn1c_common_dep = declare_dependency(
link_with : libasn1c_common, link_with : libasn1c_common,
include_directories : libasn1c_common_inc, include_directories : libasn1c_common_inc,
dependencies : libcore_dep) dependencies : libproto_dep)

View File

@ -256,7 +256,6 @@ libcore_sources = files('''
ogs-hash.h ogs-hash.h
ogs-misc.h ogs-misc.h
ogs-getopt.h ogs-getopt.h
ogs-3gpp-types.h
abts.h abts.h
ogs-abort.c ogs-abort.c
@ -292,7 +291,6 @@ libcore_sources = files('''
ogs-hash.c ogs-hash.c
ogs-misc.c ogs-misc.c
ogs-getopt.c ogs-getopt.c
ogs-3gpp-types.c
ogs-core.c ogs-core.c
abts.c abts.c
'''.split()) '''.split())

View File

@ -232,25 +232,3 @@ uint64_t ogs_uint64_from_string(char *str)
return x; return x;
} }
void ogs_extract_digit_from_string(char *digit, char *string)
{
bool extracting = false;
int i = 0;
ogs_assert(string);
ogs_assert(digit);
while (*string && i < OGS_MAX_IMSI_BCD_LEN) {
if (*string >= '0' && *string <= '9') {
*digit++ = *string;
extracting = true;
} else if (extracting == true) {
break;
}
string++;
i++;
}
*digit = 0;
}

View File

@ -49,8 +49,6 @@ char *ogs_uint64_to_string(uint64_t x);
ogs_uint24_t ogs_uint24_from_string(char *str); ogs_uint24_t ogs_uint24_from_string(char *str);
uint64_t ogs_uint64_from_string(char *str); uint64_t ogs_uint64_from_string(char *str);
void ogs_extract_digit_from_string(char *digit, char *string);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -62,7 +62,6 @@
#include "core/ogs-hash.h" #include "core/ogs-hash.h"
#include "core/ogs-misc.h" #include "core/ogs-misc.h"
#include "core/ogs-getopt.h" #include "core/ogs-getopt.h"
#include "core/ogs-3gpp-types.h"
#undef OGS_CORE_INSIDE #undef OGS_CORE_INSIDE

View File

@ -34,69 +34,116 @@ const char *OGS_FSM_NAME_INIT_SIG = "INIT";
const char *OGS_FSM_NAME_ENTRY_SIG = "ENTRY"; const char *OGS_FSM_NAME_ENTRY_SIG = "ENTRY";
const char *OGS_FSM_NAME_EXIT_SIG = "EXIT"; const char *OGS_FSM_NAME_EXIT_SIG = "EXIT";
void ogs_fsm_init(void *sm, void *event) static void fsm_entry(ogs_fsm_t *sm, ogs_fsm_handler_t state, fsm_event_t *e)
{ {
ogs_fsm_t *s = sm; ogs_assert(sm);
fsm_event_t *e = event; ogs_assert(state);
ogs_assert(s);
if (s->init != NULL) { if (e) {
(*s->init)(s, e); e->id = OGS_FSM_ENTRY_SIG;
if (s->init != s->state) { (*state)(sm, e);
if (e) { } else {
e->id = OGS_FSM_ENTRY_SIG; (*state)(sm, &entry_event);
(*s->state)(s, e); }
} else { }
(*s->state)(s, &entry_event);
} static void fsm_exit(ogs_fsm_t *sm, ogs_fsm_handler_t state, fsm_event_t *e)
{
ogs_assert(sm);
ogs_assert(state);
if (e) {
e->id = OGS_FSM_EXIT_SIG;
(*state)(sm, e);
} else {
(*state)(sm, &exit_event);
}
}
static void fsm_change(
ogs_fsm_t *sm,
ogs_fsm_handler_t oldstate,
ogs_fsm_handler_t newstate,
fsm_event_t *e)
{
ogs_assert(sm);
ogs_assert(oldstate);
ogs_assert(newstate);
fsm_exit(sm, oldstate, e);
fsm_entry(sm, newstate, e);
}
void ogs_fsm_init(void *fsm, void *init, void *fini, void *event)
{
ogs_fsm_t *sm = fsm;
fsm_event_t *e = event;
ogs_assert(sm);
sm->init = sm->state = init;
sm->fini = fini;
if (sm->init) {
(*sm->init)(sm, e);
if (sm->init != sm->state) {
ogs_assert(sm->state);
fsm_entry(sm, sm->state, e);
} }
} }
} }
void ogs_fsm_dispatch(void *sm, void *event) void ogs_fsm_tran(void *fsm, void *state, void *event)
{ {
ogs_fsm_t *s = sm; ogs_fsm_t *sm = fsm;
fsm_event_t *e = event; fsm_event_t *e = event;
ogs_assert(s); ogs_fsm_handler_t tmp = NULL;
ogs_fsm_handler_t tmp = s->state;
ogs_assert(sm);
tmp = sm->state;
ogs_assert(tmp);
sm->state = state;
ogs_assert(sm->state);
if (sm->state != tmp)
fsm_change(fsm, tmp, sm->state, e);
}
void ogs_fsm_dispatch(void *fsm, void *event)
{
ogs_fsm_t *sm = fsm;
fsm_event_t *e = event;
ogs_fsm_handler_t tmp = NULL;
ogs_assert(sm);
tmp = sm->state;
ogs_assert(tmp);
if (e) if (e)
(*tmp)(s, e); (*tmp)(sm, e);
if (s->state != tmp) { if (sm->state != tmp)
if (e) { fsm_change(fsm, tmp, sm->state, e);
e->id = OGS_FSM_EXIT_SIG;
(*tmp)(s, e);
} else {
(*tmp)(s, &exit_event);
}
if (e) {
e->id = OGS_FSM_ENTRY_SIG;
(*s->state)(s, e);
} else {
(*s->state)(s, &entry_event);
}
}
} }
void ogs_fsm_fini(void *sm, void *event) void ogs_fsm_fini(void *fsm, void *event)
{ {
ogs_fsm_t *s = sm; ogs_fsm_t *sm = fsm;
fsm_event_t *e = event; fsm_event_t *e = event;
ogs_assert(s);
if (s->fini != s->state) { ogs_assert(sm);
if (e) {
e->id = OGS_FSM_EXIT_SIG; if (sm->fini != sm->state) {
(*s->state)(s, e); ogs_assert(sm->state);
} else { fsm_exit(sm, sm->state, e);
(*s->state)(s, &exit_event);
} if (sm->fini)
(*sm->fini)(sm, e);
} }
if (s->fini != NULL) { sm->init = sm->state = sm->fini = NULL;
(*s->fini)(s, e);
}
s->state = s->init;
} }

View File

@ -46,16 +46,10 @@ typedef struct _ogs_fsm_t {
ogs_fsm_handler_t state; ogs_fsm_handler_t state;
} ogs_fsm_t; } ogs_fsm_t;
#define ogs_fsm_create(__s, __i, __f) \ void ogs_fsm_init(void *fsm, void *init, void *fini, void *event);
(((__s)->init = (__s)->state = (ogs_fsm_handler_t)(__i)), \ void ogs_fsm_tran(void *fsm, void *state, void *event);
(__s)->fini = (ogs_fsm_handler_t)(__f)) void ogs_fsm_dispatch(void *fsm, void *event);
void ogs_fsm_fini(void *fsm, void *event);
#define ogs_fsm_delete(__s) \
((__s)->init = (__s)->state = (__s)->fini = NULL)
void ogs_fsm_init(void *sm, void *event);
void ogs_fsm_dispatch(void *sm, void *event);
void ogs_fsm_fini(void *sm, void *event);
#define OGS_FSM_TRAN(__s, __target) \ #define OGS_FSM_TRAN(__s, __target) \
((ogs_fsm_t *)__s)->state = (ogs_fsm_handler_t)(__target) ((ogs_fsm_t *)__s)->state = (ogs_fsm_handler_t)(__target)

View File

@ -210,6 +210,14 @@ static ogs_inline ogs_uint24_t ogs_htobe24(ogs_uint24_t x)
#define ogs_uint64_to_uint32(x) ((x >= 0xffffffffUL) ? 0xffffffffU : x) #define ogs_uint64_to_uint32(x) ((x >= 0xffffffffUL) ? 0xffffffffU : x)
#define OGS_OBJECT_REF(__oBJ) \
((__oBJ)->reference_count)++, \
ogs_debug("[REF] %d", ((__oBJ)->reference_count))
#define OGS_OBJECT_UNREF(__oBJ) \
ogs_debug("[UNREF] %d", ((__oBJ)->reference_count)), \
((__oBJ)->reference_count)--
#define OGS_OBJECT_IS_REF(__oBJ) ((__oBJ)->reference_count > 1)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -245,7 +245,7 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
} }
memset(pkbuf, 0, sizeof(*pkbuf)); memset(pkbuf, 0, sizeof(*pkbuf));
cluster->ref++; OGS_OBJECT_REF(cluster);
pkbuf->cluster = cluster; pkbuf->cluster = cluster;
@ -283,8 +283,9 @@ void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf)
cluster = pkbuf->cluster; cluster = pkbuf->cluster;
ogs_assert(cluster); ogs_assert(cluster);
cluster->ref--; if (OGS_OBJECT_IS_REF(cluster))
if (cluster->ref == 0) OGS_OBJECT_UNREF(cluster);
else
cluster_free(pool, pkbuf->cluster); cluster_free(pool, pkbuf->cluster);
ogs_pool_free(&pool->pkbuf, pkbuf); ogs_pool_free(&pool->pkbuf, pkbuf);
@ -337,7 +338,7 @@ ogs_pkbuf_t *ogs_pkbuf_copy_debug(ogs_pkbuf_t *pkbuf, const char *file_line)
ogs_assert(newbuf); ogs_assert(newbuf);
memcpy(newbuf, pkbuf, sizeof *pkbuf); memcpy(newbuf, pkbuf, sizeof *pkbuf);
newbuf->cluster->ref++; OGS_OBJECT_REF(newbuf->cluster);
ogs_thread_mutex_unlock(&pool->mutex); ogs_thread_mutex_unlock(&pool->mutex);
#endif #endif

View File

@ -32,7 +32,7 @@ typedef struct ogs_cluster_s {
unsigned char *buffer; unsigned char *buffer;
unsigned int size; unsigned int size;
unsigned int ref; unsigned int reference_count;
} ogs_cluster_t; } ogs_cluster_t;
#if OGS_USE_TALLOC #if OGS_USE_TALLOC

View File

@ -35,6 +35,7 @@ typedef struct ogs_sockopt_s {
uint32_t srto_initial; uint32_t srto_initial;
uint32_t srto_min; uint32_t srto_min;
uint32_t srto_max; uint32_t srto_max;
#define OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30
uint16_t sinit_num_ostreams; uint16_t sinit_num_ostreams;
uint16_t sinit_max_instreams; uint16_t sinit_max_instreams;
uint16_t sinit_max_attempts; uint16_t sinit_max_attempts;

View File

@ -52,10 +52,10 @@ libcrypt = library('ogscrypt',
version : libogslib_version, version : libogslib_version,
c_args : '-DOGS_CRYPT_COMPILATION', c_args : '-DOGS_CRYPT_COMPILATION',
include_directories : [libcrypt_inc, libinc], include_directories : [libcrypt_inc, libinc],
dependencies : libcore_dep, dependencies : libproto_dep,
install : true) install : true)
libcrypt_dep = declare_dependency( libcrypt_dep = declare_dependency(
link_with : libcrypt, link_with : libcrypt,
include_directories : [libcrypt_inc, libinc], include_directories : [libcrypt_inc, libinc],
dependencies : libcore_dep) dependencies : libproto_dep)

View File

@ -20,7 +20,7 @@
#ifndef OGS_CRYPT_H #ifndef OGS_CRYPT_H
#define OGS_CRYPT_H #define OGS_CRYPT_H
#include "ogs-core.h" #include "ogs-proto.h"
#define OGS_CRYPT_INSIDE #define OGS_CRYPT_INSIDE

View File

@ -51,10 +51,10 @@ libdiameter_common = library('ogsdiameter-common',
version : libogslib_version, version : libogslib_version,
c_args : libdiameter_common_cc_flags, c_args : libdiameter_common_cc_flags,
include_directories : [libdiameter_common_inc, libinc], include_directories : [libdiameter_common_inc, libinc],
dependencies : [libcore_dep, libfdcore_dep], dependencies : [libproto_dep, libfdcore_dep],
install : true) install : true)
libdiameter_common_dep = declare_dependency( libdiameter_common_dep = declare_dependency(
link_with : libdiameter_common, link_with : libdiameter_common,
include_directories : [libdiameter_common_inc, libinc], include_directories : [libdiameter_common_inc, libinc],
dependencies : [libcore_dep, libfdcore_dep]) dependencies : [libproto_dep, libfdcore_dep])

View File

@ -37,7 +37,7 @@
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#include "ogs-core.h" #include "ogs-proto.h"
#define OGS_DIAMETER_INSIDE #define OGS_DIAMETER_INSIDE

View File

@ -191,7 +191,8 @@ static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t
xact->gtp_version = gtp_version; xact->gtp_version = gtp_version;
xact->org = OGS_GTP_REMOTE_ORIGINATOR; xact->org = OGS_GTP_REMOTE_ORIGINATOR;
xact->xid = (gtp_version == 1) ? OGS_GTP1_SQN_TO_XID(sqn) : OGS_GTP2_SQN_TO_XID(sqn); xact->xid = (gtp_version == 1) ?
OGS_GTP1_SQN_TO_XID(sqn) : OGS_GTP2_SQN_TO_XID(sqn);
xact->gnode = gnode; xact->gnode = gnode;
xact->tm_response = ogs_timer_add( xact->tm_response = ogs_timer_add(

View File

@ -80,10 +80,10 @@ libipfw = library('ogsipfw',
version : libogslib_version, version : libogslib_version,
c_args : ['-include', 'glue.h', ipfw_cc_flags], c_args : ['-include', 'glue.h', ipfw_cc_flags],
include_directories : libipfw_inc, include_directories : libipfw_inc,
dependencies : libcore_dep, dependencies : libproto_dep,
install : true) install : true)
libipfw_dep = declare_dependency( libipfw_dep = declare_dependency(
link_with : libipfw, link_with : libipfw,
include_directories : libinc, include_directories : libinc,
dependencies : libcore_dep) dependencies : libproto_dep)

View File

@ -24,7 +24,7 @@
extern "C" { extern "C" {
#endif #endif
#include "ogs-core.h" #include "ogs-proto.h"
typedef struct ogs_ipfw_rule_s { typedef struct ogs_ipfw_rule_s {
uint8_t proto; uint8_t proto;

View File

@ -18,8 +18,9 @@
libinc = include_directories('.') libinc = include_directories('.')
subdir('core') subdir('core')
subdir('ipfw') subdir('proto')
subdir('crypt') subdir('crypt')
subdir('ipfw')
subdir('app') subdir('app')
subdir('metrics') subdir('metrics')
subdir('sctp') subdir('sctp')

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -17,19 +17,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef NSSF_NNRF_BUILD_H #include "ogs-proto.h"
#define NSSF_NNRF_BUILD_H
#include "context.h" void ogs_extract_digit_from_string(char *digit, char *string)
{
bool extracting = false;
int i = 0;
#ifdef __cplusplus ogs_assert(string);
extern "C" { ogs_assert(digit);
#endif
ogs_sbi_request_t *nssf_nnrf_nfm_build_register(void); while (*string && i < OGS_MAX_IMSI_BCD_LEN) {
if (*string >= '0' && *string <= '9') {
*digit++ = *string;
extracting = true;
} else if (extracting == true) {
break;
}
string++;
i++;
}
#ifdef __cplusplus *digit = 0;
} }
#endif
#endif /* NSSF_NNRF_BUILD_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -17,19 +17,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef AUSF_NNRF_BUILD_H #if !defined(OGS_PROTO_INSIDE) && !defined(OGS_PROTO_COMPILATION)
#define AUSF_NNRF_BUILD_H #error "This header cannot be included directly."
#endif
#include "context.h" #ifndef OGS_PROTO_CONV_H
#define OGS_PROTO_CONV_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
ogs_sbi_request_t *ausf_nnrf_nfm_build_register(void); void ogs_extract_digit_from_string(char *digit, char *string);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* AUSF_NNRF_BUILD_H */ #endif /* OGS_PROTO_CONV_H */

74
lib/proto/event.c Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-proto.h"
const char *OGS_EVENT_NAME_SBI_SERVER = "OGS_EVENT_NAME_SBI_SERVER";
const char *OGS_EVENT_NAME_SBI_CLIENT = "OGS_EVENT_NAME_SBI_CLIENT";
const char *OGS_EVENT_NAME_SBI_TIMER = "OGS_EVENT_NAME_SBI_TIMER";
void *ogs_event_size(int id, size_t size)
{
ogs_event_t *e = NULL;
e = ogs_calloc(1, size);
ogs_assert(e);
e->id = id;
return e;
}
ogs_event_t *ogs_event_new(int id)
{
return ogs_event_size(id, sizeof(ogs_event_t));
}
void ogs_event_free(void *e)
{
ogs_assert(e);
ogs_free(e);
}
const char *ogs_event_get_name(ogs_event_t *e)
{
if (e == NULL) {
return OGS_FSM_NAME_INIT_SIG;
}
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case OGS_EVENT_SBI_SERVER:
return OGS_EVENT_NAME_SBI_SERVER;
case OGS_EVENT_SBI_CLIENT:
return OGS_EVENT_NAME_SBI_CLIENT;
case OGS_EVENT_SBI_TIMER:
return OGS_EVENT_NAME_SBI_TIMER;
default:
break;
}
ogs_error("Unknown Event[%d]", e->id);
return "UNKNOWN_EVENT";
}

74
lib/proto/event.h Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_PROTO_INSIDE) && !defined(OGS_PROTO_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_PROTO_EVENT_H
#define OGS_PROTO_EVENT_H
#ifdef __cplusplus
extern "C" {
#endif
extern const char *OGS_EVENT_NAME_SBI_SERVER;
extern const char *OGS_EVENT_NAME_SBI_CLIENT;
extern const char *OGS_EVENT_NAME_SBI_TIMER;
typedef enum {
OGS_EVENT_BASE = OGS_FSM_USER_SIG,
OGS_EVENT_SBI_SERVER,
OGS_EVENT_SBI_CLIENT,
OGS_EVENT_SBI_TIMER,
OGS_MAX_NUM_OF_PROTO_EVENT,
} ogs_event_e;
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
typedef struct ogs_sbi_response_s ogs_sbi_response_t;
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
typedef struct ogs_event_s {
int id;
int timer_id;
struct {
ogs_sbi_request_t *request;
ogs_sbi_response_t *response;
void *data;
int state;
ogs_sbi_message_t *message;
} sbi;
} ogs_event_t;
void *ogs_event_size(int id, size_t size);
ogs_event_t *ogs_event_new(int id);
void ogs_event_free(void *e);
const char *ogs_event_get_name(ogs_event_t *e);
#ifdef __cplusplus
}
#endif
#endif /* OGS_PROTO_EVENT_H */

45
lib/proto/meson.build Normal file
View File

@ -0,0 +1,45 @@
# Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
# This file is part of Open5GS.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
libproto_sources = files('''
ogs-proto.h
types.h
conv.h
event.h
timer.h
types.c
conv.c
event.c
timer.c
'''.split())
libproto_inc = include_directories('.')
libproto = library('ogsproto',
sources : libproto_sources,
version : libogslib_version,
c_args : '-DOGS_PROTO_COMPILATION',
include_directories : [libproto_inc, libinc],
dependencies : libcore_dep,
install : true)
libproto_dep = declare_dependency(
link_with : libproto,
include_directories : [libproto_inc, libinc],
dependencies : libcore_dep)

View File

@ -17,19 +17,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef SCP_NNRF_BUILD_H #ifndef OGS_PROTO_H
#define SCP_NNRF_BUILD_H #define OGS_PROTO_H
#include "context.h" #include "ogs-core.h"
#define OGS_PROTO_INSIDE
#include "proto/types.h"
#include "proto/conv.h"
#include "proto/event.h"
#include "proto/timer.h"
#undef OGS_PROTO_INSIDE
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
ogs_sbi_request_t *scp_nnrf_nfm_build_register(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* SCP_NNRF_BUILD_H */ #endif /* OGS_PROTO_H */

56
lib/proto/timer.c Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-proto.h"
const char *OGS_TIMER_NAME_NF_INSTANCE_REGISTRATION_INTERVAL =
"OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL";
const char *OGS_TIMER_NAME_NF_INSTANCE_HEARTBEAT_INTERVAL =
"OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL";
const char *OGS_TIMER_NAME_NF_INSTANCE_NO_HEARTBEAT =
"OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT";
const char *OGS_TIMER_NAME_NF_INSTANCE_VALIDITY =
"OGS_TIMER_NF_INSTANCE_VALIDITY";
const char *OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY =
"OGS_TIMER_SUBSCRIPTION_VALIDITY";
const char *OGS_TIMER_NAME_SBI_CLIENT_WAIT =
"OGS_TIMER_SBI_CLIENT_WAIT";
const char *ogs_timer_get_name(int timer_id)
{
switch (timer_id) {
case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
return OGS_TIMER_NAME_NF_INSTANCE_REGISTRATION_INTERVAL;
case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
return OGS_TIMER_NAME_NF_INSTANCE_HEARTBEAT_INTERVAL;
case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
return OGS_TIMER_NAME_NF_INSTANCE_NO_HEARTBEAT;
case OGS_TIMER_NF_INSTANCE_VALIDITY:
return OGS_TIMER_NAME_NF_INSTANCE_VALIDITY;
case OGS_TIMER_SUBSCRIPTION_VALIDITY:
return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY;
case OGS_TIMER_SBI_CLIENT_WAIT:
return OGS_TIMER_NAME_SBI_CLIENT_WAIT;
default:
break;
}
ogs_error("Unknown Timer[%d]", timer_id);
return "UNKNOWN_TIMER";
}

59
lib/proto/timer.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_PROTO_INSIDE) && !defined(OGS_PROTO_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_PROTO_TIMER_H
#define OGS_PROTO_TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
extern const char *OGS_TIMER_NAME_NF_INSTANCE_REGISTRATION_INTERVAL;
extern const char *OGS_TIMER_NAME_NF_INSTANCE_HEARTBEAT_INTERVAL;
extern const char *OGS_TIMER_NAME_NF_INSTANCE_NO_HEARTBEAT;
extern const char *OGS_TIMER_NAME_NF_INSTANCE_VALIDITY;
extern const char *OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY;
extern const char *OGS_TIMER_NAME_SBI_CLIENT_WAIT;
/* forward declaration */
typedef enum {
OGS_TIMER_BASE = 0,
OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL,
OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL,
OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT,
OGS_TIMER_NF_INSTANCE_VALIDITY,
OGS_TIMER_SUBSCRIPTION_VALIDITY,
OGS_TIMER_SBI_CLIENT_WAIT,
OGS_MAX_NUM_OF_PROTO_TIMER,
} ogs_timer_e;
const char *ogs_timer_get_name(int timer_id);
#ifdef __cplusplus
}
#endif
#endif /* OGS_PROTO_TIMER_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "ogs-core.h" #include "ogs-proto.h"
#define PLMN_ID_DIGIT1(x) (((x) / 100) % 10) #define PLMN_ID_DIGIT1(x) (((x) / 100) % 10)
#define PLMN_ID_DIGIT2(x) (((x) / 10) % 10) #define PLMN_ID_DIGIT2(x) (((x) / 10) % 10)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -17,12 +17,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#if !defined(OGS_CORE_INSIDE) && !defined(OGS_CORE_COMPILATION) #if !defined(OGS_PROTO_INSIDE) && !defined(OGS_PROTO_COMPILATION)
#error "This header cannot be included directly." #error "This header cannot be included directly."
#endif #endif
#ifndef OGS_3GPP_TYPES_H #ifndef OGS_PROTO_TYPES_H
#define OGS_3GPP_TYPES_H #define OGS_PROTO_TYPES_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -107,8 +107,6 @@ extern "C" {
#define OGS_MAX_QOS_FLOW_ID 63 #define OGS_MAX_QOS_FLOW_ID 63
#define OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30
/************************************ /************************************
* PLMN_ID Structure */ * PLMN_ID Structure */
#define OGS_MAX_NUM_OF_PLMN 6 #define OGS_MAX_NUM_OF_PLMN 6
@ -778,4 +776,4 @@ int ogs_pcc_rule_update_qos_from_media(
} }
#endif #endif
#endif /* OGS_3GPP_TYPES_H */ #endif /* OGS_PROTO_TYPES_H */

View File

@ -102,8 +102,8 @@ ogs_sbi_client_t *ogs_sbi_client_add(ogs_sockaddr_t *addr)
ogs_assert(client); ogs_assert(client);
memset(client, 0, sizeof(ogs_sbi_client_t)); memset(client, 0, sizeof(ogs_sbi_client_t));
client->reference_count++; ogs_debug("ogs_sbi_client_add()");
ogs_trace("ogs_sbi_client_add()"); OGS_OBJECT_REF(client);
ogs_assert(OGS_OK == ogs_copyaddrinfo(&client->node.addr, addr)); ogs_assert(OGS_OK == ogs_copyaddrinfo(&client->node.addr, addr));
@ -128,17 +128,22 @@ ogs_sbi_client_t *ogs_sbi_client_add(ogs_sockaddr_t *addr)
void ogs_sbi_client_remove(ogs_sbi_client_t *client) void ogs_sbi_client_remove(ogs_sbi_client_t *client)
{ {
ogs_sockaddr_t *addr = NULL;
char buf[OGS_ADDRSTRLEN];
ogs_assert(client); ogs_assert(client);
addr = client->node.addr;
ogs_assert(addr);
ogs_debug("ogs_sbi_client_remove() [%s:%d]",
OGS_ADDR(addr, buf), OGS_PORT(addr));
/* ogs_sbi_client_t is always created with reference context */ /* ogs_sbi_client_t is always created with reference context */
ogs_assert(client->reference_count > 0); if (OGS_OBJECT_IS_REF(client)) {
OGS_OBJECT_UNREF(client);
ogs_trace("client->reference_count = %d", client->reference_count);
client->reference_count--;
if (client->reference_count > 0)
return; return;
}
ogs_trace("ogs_sbi_client_remove()");
ogs_list_remove(&ogs_sbi_self()->client_list, client); ogs_list_remove(&ogs_sbi_self()->client_list, client);
connection_remove_all(client); connection_remove_all(client);

View File

@ -47,10 +47,8 @@ extern "C" {
ogs_sbi_client_remove(client); \ ogs_sbi_client_remove(client); \
} \ } \
\ \
(__pClient)->reference_count++; \ OGS_OBJECT_REF(__pClient); \
((__cTX)->client) = (__pClient); \ ((__cTX)->client) = (__pClient); \
ogs_trace("client->reference_count = %d", \
(__pClient)->reference_count); \
} while(0) } while(0)
typedef int (*ogs_sbi_client_cb_f)( typedef int (*ogs_sbi_client_cb_f)(

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "app/ogs-app.h" #include "ogs-app.h"
#include "ogs-sbi.h" #include "ogs-sbi.h"
int __ogs_sbi_domain; int __ogs_sbi_domain;
@ -727,6 +727,16 @@ int ogs_sbi_context_parse_config(
return OGS_OK; return OGS_OK;
} }
void ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_e nf_type)
{
ogs_assert(nf_type);
if (self.num_of_to_be_notified_nf_type < OGS_SBI_MAX_NUM_OF_NF_TYPE) {
self.to_be_notified_nf_type[self.num_of_to_be_notified_nf_type] = nf_type;
self.num_of_to_be_notified_nf_type++;
}
}
bool ogs_sbi_nf_service_is_available(const char *name) bool ogs_sbi_nf_service_is_available(const char *name)
{ {
int i; int i;
@ -753,8 +763,9 @@ ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(void)
ogs_assert(nf_instance); ogs_assert(nf_instance);
memset(nf_instance, 0, sizeof(ogs_sbi_nf_instance_t)); memset(nf_instance, 0, sizeof(ogs_sbi_nf_instance_t));
nf_instance->reference_count++; ogs_debug("ogs_sbi_nf_instance_add()");
ogs_trace("ogs_sbi_nf_instance_add()");
OGS_OBJECT_REF(nf_instance);
nf_instance->time.heartbeat_interval = nf_instance->time.heartbeat_interval =
ogs_app()->time.nf_instance.heartbeat_interval; ogs_app()->time.nf_instance.heartbeat_interval;
@ -802,7 +813,7 @@ void ogs_sbi_nf_instance_add_allowed_nf_type(
ogs_assert(allowed_nf_type); ogs_assert(allowed_nf_type);
if (nf_instance->num_of_allowed_nf_type < OGS_SBI_MAX_NUM_OF_NF_TYPE) { if (nf_instance->num_of_allowed_nf_type < OGS_SBI_MAX_NUM_OF_NF_TYPE) {
nf_instance->allowed_nf_types[nf_instance->num_of_allowed_nf_type] = nf_instance->allowed_nf_type[nf_instance->num_of_allowed_nf_type] =
allowed_nf_type; allowed_nf_type;
nf_instance->num_of_allowed_nf_type++; nf_instance->num_of_allowed_nf_type++;
} }
@ -836,13 +847,13 @@ void ogs_sbi_nf_instance_remove(ogs_sbi_nf_instance_t *nf_instance)
{ {
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_trace("nf_instance->reference_count = %d", ogs_debug("ogs_sbi_nf_instance_remove()");
nf_instance->reference_count);
nf_instance->reference_count--; if (OGS_OBJECT_IS_REF(nf_instance)) {
if (nf_instance->reference_count > 0) OGS_OBJECT_UNREF(nf_instance);
return; return;
}
ogs_trace("ogs_sbi_nf_instance_remove()");
ogs_list_remove(&ogs_sbi_self()->nf_instance_list, nf_instance); ogs_list_remove(&ogs_sbi_self()->nf_instance_list, nf_instance);
ogs_sbi_nf_info_remove_all(&nf_instance->nf_info_list); ogs_sbi_nf_info_remove_all(&nf_instance->nf_info_list);
@ -935,17 +946,17 @@ void ogs_sbi_nf_service_add_version(ogs_sbi_nf_service_t *nf_service,
ogs_assert(full); ogs_assert(full);
if (nf_service->num_of_version < OGS_SBI_MAX_NUM_OF_SERVICE_VERSION) { if (nf_service->num_of_version < OGS_SBI_MAX_NUM_OF_SERVICE_VERSION) {
nf_service->versions[nf_service->num_of_version].in_uri = nf_service->version[nf_service->num_of_version].in_uri =
ogs_strdup(in_uri); ogs_strdup(in_uri);
ogs_assert(nf_service->versions[nf_service->num_of_version].in_uri); ogs_assert(nf_service->version[nf_service->num_of_version].in_uri);
nf_service->versions[nf_service->num_of_version].full = nf_service->version[nf_service->num_of_version].full =
ogs_strdup(full); ogs_strdup(full);
ogs_assert(nf_service->versions[nf_service->num_of_version].full); ogs_assert(nf_service->version[nf_service->num_of_version].full);
if (expiry) { if (expiry) {
nf_service->versions[nf_service->num_of_version].expiry = nf_service->version[nf_service->num_of_version].expiry =
ogs_strdup(expiry); ogs_strdup(expiry);
ogs_assert( ogs_assert(
nf_service->versions[nf_service->num_of_version].expiry); nf_service->version[nf_service->num_of_version].expiry);
} }
nf_service->num_of_version++; nf_service->num_of_version++;
@ -978,12 +989,12 @@ void ogs_sbi_nf_service_clear(ogs_sbi_nf_service_t *nf_service)
ogs_free(nf_service->fqdn); ogs_free(nf_service->fqdn);
for (i = 0; i < nf_service->num_of_version; i++) { for (i = 0; i < nf_service->num_of_version; i++) {
if (nf_service->versions[i].in_uri) if (nf_service->version[i].in_uri)
ogs_free(nf_service->versions[i].in_uri); ogs_free(nf_service->version[i].in_uri);
if (nf_service->versions[i].full) if (nf_service->version[i].full)
ogs_free(nf_service->versions[i].full); ogs_free(nf_service->version[i].full);
if (nf_service->versions[i].expiry) if (nf_service->version[i].expiry)
ogs_free(nf_service->versions[i].expiry); ogs_free(nf_service->version[i].expiry);
} }
nf_service->num_of_version = 0; nf_service->num_of_version = 0;
@ -1368,13 +1379,13 @@ bool ogs_sbi_discovery_param_is_matched(
ogs_sbi_discovery_option_t *discovery_option) ogs_sbi_discovery_option_t *discovery_option)
{ {
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_state_registered);
ogs_assert(target_nf_type); ogs_assert(target_nf_type);
if (!OGS_FSM_CHECK(&nf_instance->sm, if (!OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_registered))
ogs_sbi_self()->nf_state_registered)) return false; return false;
if (nf_instance->nf_type != target_nf_type) return false; if (nf_instance->nf_type != target_nf_type)
return false;
if (discovery_option) { if (discovery_option) {
if (discovery_option->target_nf_instance_id && if (discovery_option->target_nf_instance_id &&
@ -1393,7 +1404,6 @@ void ogs_sbi_select_nf(
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(ogs_sbi_self()->nf_state_registered);
ogs_assert(sbi_object); ogs_assert(sbi_object);
ogs_assert(target_nf_type); ogs_assert(target_nf_type);
@ -1407,20 +1417,18 @@ void ogs_sbi_select_nf(
} }
} }
bool ogs_sbi_client_associate(ogs_sbi_nf_instance_t *nf_instance) void ogs_sbi_client_associate(ogs_sbi_nf_instance_t *nf_instance)
{ {
ogs_sbi_client_t *client = NULL; ogs_sbi_client_t *client = NULL;
ogs_assert(nf_instance); ogs_assert(nf_instance);
client = nf_instance_find_client(nf_instance); client = nf_instance_find_client(nf_instance);
if (!client) return false; ogs_assert(client);
OGS_SBI_SETUP_CLIENT(nf_instance, client); OGS_SBI_SETUP_CLIENT(nf_instance, client);
nf_service_associate_client_all(nf_instance); nf_service_associate_client_all(nf_instance);
return true;
} }
OpenAPI_uri_scheme_e ogs_sbi_default_uri_scheme(void) OpenAPI_uri_scheme_e ogs_sbi_default_uri_scheme(void)
@ -1442,7 +1450,7 @@ ogs_sbi_client_t *ogs_sbi_client_find_by_service_name(
ogs_assert(nf_service->name); ogs_assert(nf_service->name);
if (strcmp(nf_service->name, name) == 0) { if (strcmp(nf_service->name, name) == 0) {
for (i = 0; i < nf_service->num_of_version; i++) { for (i = 0; i < nf_service->num_of_version; i++) {
if (strcmp(nf_service->versions[i].in_uri, version) == 0) { if (strcmp(nf_service->version[i].in_uri, version) == 0) {
return nf_service->client; return nf_service->client;
} }
} }
@ -1476,7 +1484,6 @@ ogs_sbi_xact_t *ogs_sbi_xact_add(
{ {
ogs_sbi_xact_t *xact = NULL; ogs_sbi_xact_t *xact = NULL;
ogs_assert(ogs_sbi_self()->client_wait_expire);
ogs_assert(sbi_object); ogs_assert(sbi_object);
ogs_pool_alloc(&xact_pool, &xact); ogs_pool_alloc(&xact_pool, &xact);
@ -1496,7 +1503,7 @@ ogs_sbi_xact_t *ogs_sbi_xact_add(
} }
xact->t_response = ogs_timer_add( xact->t_response = ogs_timer_add(
ogs_app()->timer_mgr, ogs_sbi_self()->client_wait_expire, xact); ogs_app()->timer_mgr, ogs_timer_sbi_client_wait_expire, xact);
if (!xact->t_response) { if (!xact->t_response) {
ogs_error("ogs_timer_add() failed"); ogs_error("ogs_timer_add() failed");
ogs_sbi_request_free(xact->request); ogs_sbi_request_free(xact->request);

View File

@ -65,11 +65,12 @@ typedef struct ogs_sbi_context_s {
const char *content_encoding; const char *content_encoding;
void (*client_wait_expire)(void *data);
ogs_fsm_handler_t nf_state_registered;
int num_of_service_name; int num_of_service_name;
const char *service_name[OGS_MAX_NUM_OF_NF_SERVICE]; const char *service_name[OGS_MAX_NUM_OF_NF_SERVICE];
#define OGS_SBI_MAX_NUM_OF_NF_TYPE 16
int num_of_to_be_notified_nf_type;
OpenAPI_nf_type_e to_be_notified_nf_type[OGS_SBI_MAX_NUM_OF_NF_TYPE];
} ogs_sbi_context_t; } ogs_sbi_context_t;
typedef struct ogs_sbi_nf_instance_s { typedef struct ogs_sbi_nf_instance_s {
@ -87,14 +88,14 @@ typedef struct ogs_sbi_nf_instance_s {
ogs_timer_t *t_no_heartbeat; /* check heartbeat */ ogs_timer_t *t_no_heartbeat; /* check heartbeat */
ogs_timer_t *t_validity; /* check validation */ ogs_timer_t *t_validity; /* check validation */
#define NF_INSTANCE_IS_SELF(_iD) \ #define NF_INSTANCE_ID_IS_SELF(_iD) \
(_iD) && ogs_sbi_self()->nf_instance && \ (_iD) && ogs_sbi_self()->nf_instance && \
strcmp((_iD), ogs_sbi_self()->nf_instance->id) == 0 strcmp((_iD), ogs_sbi_self()->nf_instance->id) == 0
#define NF_INSTANCE_IS_OTHERS(_iD) \ #define NF_INSTANCE_ID_IS_OTHERS(_iD) \
(_iD) && ogs_sbi_self()->nf_instance && \ (_iD) && ogs_sbi_self()->nf_instance && \
strcmp((_iD), ogs_sbi_self()->nf_instance->id) != 0 strcmp((_iD), ogs_sbi_self()->nf_instance->id) != 0
#define NF_INSTANCE_IS_NRF(__nFInstance) \ #define NF_INSTANCE_TYPE_IS_NRF(__nFInstance) \
((__nFInstance->nf_type) == OpenAPI_nf_type_NRF) ((__nFInstance->nf_type) == OpenAPI_nf_type_NRF)
char *id; /* NFInstanceId */ char *id; /* NFInstanceId */
@ -110,9 +111,8 @@ typedef struct ogs_sbi_nf_instance_s {
int num_of_ipv6; int num_of_ipv6;
ogs_sockaddr_t *ipv6[OGS_SBI_MAX_NUM_OF_IP_ADDRESS]; ogs_sockaddr_t *ipv6[OGS_SBI_MAX_NUM_OF_IP_ADDRESS];
#define OGS_SBI_MAX_NUM_OF_NF_TYPE 16
int num_of_allowed_nf_type; int num_of_allowed_nf_type;
OpenAPI_nf_type_e allowed_nf_types[OGS_SBI_MAX_NUM_OF_NF_TYPE]; OpenAPI_nf_type_e allowed_nf_type[OGS_SBI_MAX_NUM_OF_NF_TYPE];
#define OGS_SBI_DEFAULT_PRIORITY 0 #define OGS_SBI_DEFAULT_PRIORITY 0
#define OGS_SBI_DEFAULT_CAPACITY 100 #define OGS_SBI_DEFAULT_CAPACITY 100
@ -188,7 +188,7 @@ typedef struct ogs_sbi_nf_service_s {
char *in_uri; char *in_uri;
char *full; char *full;
char *expiry; char *expiry;
} versions[OGS_SBI_MAX_NUM_OF_SERVICE_VERSION]; } version[OGS_SBI_MAX_NUM_OF_SERVICE_VERSION];
char *fqdn; char *fqdn;
int num_of_addr; int num_of_addr;
@ -273,6 +273,8 @@ ogs_sbi_context_t *ogs_sbi_self(void);
int ogs_sbi_context_parse_config( int ogs_sbi_context_parse_config(
const char *local, const char *nrf, const char *scp); const char *local, const char *nrf, const char *scp);
void ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_e nf_type);
bool ogs_sbi_nf_service_is_available(const char *name); bool ogs_sbi_nf_service_is_available(const char *name);
ogs_sbi_nf_instance_t *ogs_sbi_scp_instance(void); ogs_sbi_nf_instance_t *ogs_sbi_scp_instance(void);
@ -320,7 +322,7 @@ ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
ogs_sbi_client_t *ogs_sbi_client_find_by_service_name( ogs_sbi_client_t *ogs_sbi_client_find_by_service_name(
ogs_sbi_nf_instance_t *nf_instance, char *name, char *version); ogs_sbi_nf_instance_t *nf_instance, char *name, char *version);
bool ogs_sbi_client_associate(ogs_sbi_nf_instance_t *nf_instance); void ogs_sbi_client_associate(ogs_sbi_nf_instance_t *nf_instance);
OpenAPI_uri_scheme_e ogs_sbi_default_uri_scheme(void); OpenAPI_uri_scheme_e ogs_sbi_default_uri_scheme(void);
@ -341,10 +343,8 @@ OpenAPI_uri_scheme_e ogs_sbi_default_uri_scheme(void);
OGS_SBI_NF_INSTANCE((__sBIObject), (__nFType))); \ OGS_SBI_NF_INSTANCE((__sBIObject), (__nFType))); \
} \ } \
\ \
(__nFInstance)->reference_count++; \ OGS_OBJECT_REF(__nFInstance); \
OGS_SBI_NF_INSTANCE((__sBIObject), (__nFType)) = (__nFInstance); \ OGS_SBI_NF_INSTANCE((__sBIObject), (__nFType)) = (__nFInstance); \
ogs_trace("nf_instance->reference_count = %d", \
(__nFInstance)->reference_count); \
} while(0) } while(0)
bool ogs_sbi_discovery_param_is_matched( bool ogs_sbi_discovery_param_is_matched(

View File

@ -28,6 +28,7 @@ libsbi_sources = files('''
yuarel.c yuarel.c
conv.c conv.c
timer.c
message.c message.c
mhd-server.c mhd-server.c
@ -39,8 +40,9 @@ libsbi_sources = files('''
nnrf-build.c nnrf-build.c
nnrf-handler.c nnrf-handler.c
path.c path.c
nf-sm.c
'''.split()) '''.split())
libsbi_inc = include_directories('.') libsbi_inc = include_directories('.')
@ -57,8 +59,7 @@ libsbi = library('ogssbi',
version : libogslib_version, version : libogslib_version,
c_args : sbi_cc_flags, c_args : sbi_cc_flags,
include_directories : [libsbi_inc, libinc], include_directories : [libsbi_inc, libinc],
dependencies : [libcore_dep, dependencies : [libcrypt_dep,
libcrypt_dep,
libapp_dep, libapp_dep,
libsbi_openapi_dep, libsbi_openapi_dep,
libgnutls_dep, libgnutls_dep,
@ -71,8 +72,7 @@ libsbi = library('ogssbi',
libsbi_dep = declare_dependency( libsbi_dep = declare_dependency(
link_with : libsbi, link_with : libsbi,
include_directories : [libsbi_inc, libinc], include_directories : [libsbi_inc, libinc],
dependencies : [libcore_dep, dependencies : [libcrypt_dep,
libcrypt_dep,
libapp_dep, libapp_dep,
libsbi_openapi_dep, libsbi_openapi_dep,
libgnutls_dep, libgnutls_dep,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -17,28 +17,44 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "context.h" #include "ogs-app.h"
#include "ogs-sbi.h"
#include "sbi-path.h" void ogs_sbi_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance)
#include "nnrf-handler.h"
void bsf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance)
{ {
bsf_event_t e; ogs_event_t e;
ogs_assert(nf_instance);
if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
} else if (NF_INSTANCE_ID_IS_OTHERS(nf_instance->id)) {
} else {
ogs_fatal("FSM is available in NRF or OTHERS");
ogs_assert_if_reached();
}
memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance;
ogs_fsm_init(&nf_instance->sm,
ogs_sbi_nf_state_initial, ogs_sbi_nf_state_final, &e);
}
void ogs_sbi_nf_fsm_tran(ogs_sbi_nf_instance_t *nf_instance, void *state)
{
ogs_event_t e;
ogs_assert(nf_instance); ogs_assert(nf_instance);
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance; e.sbi.data = nf_instance;
ogs_fsm_create(&nf_instance->sm, ogs_fsm_tran(&nf_instance->sm, state, &e);
bsf_nf_state_initial, bsf_nf_state_final);
ogs_fsm_init(&nf_instance->sm, &e);
} }
void bsf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance) void ogs_sbi_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance)
{ {
bsf_event_t e; ogs_event_t e;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -46,50 +62,49 @@ void bsf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance)
e.sbi.data = nf_instance; e.sbi.data = nf_instance;
ogs_fsm_fini(&nf_instance->sm, &e); ogs_fsm_fini(&nf_instance->sm, &e);
ogs_fsm_delete(&nf_instance->sm);
} }
void bsf_nf_state_initial(ogs_fsm_t *s, bsf_event_t *e) void ogs_sbi_nf_state_initial(ogs_fsm_t *s, ogs_event_t *e)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s); ogs_assert(s);
ogs_assert(e); ogs_assert(e);
bsf_sm_debug(e); ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data; nf_instance = e->sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr, nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
bsf_timer_nf_instance_registration_interval, nf_instance); ogs_timer_nf_instance_registration_interval, nf_instance);
ogs_assert(nf_instance->t_registration_interval); ogs_assert(nf_instance->t_registration_interval);
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr, nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
bsf_timer_nf_instance_heartbeat_interval, nf_instance); ogs_timer_nf_instance_heartbeat_interval, nf_instance);
ogs_assert(nf_instance->t_heartbeat_interval); ogs_assert(nf_instance->t_heartbeat_interval);
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr, nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
bsf_timer_nf_instance_no_heartbeat, nf_instance); ogs_timer_nf_instance_no_heartbeat, nf_instance);
ogs_assert(nf_instance->t_no_heartbeat); ogs_assert(nf_instance->t_no_heartbeat);
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr, nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
bsf_timer_nf_instance_validity, nf_instance); ogs_timer_nf_instance_validity, nf_instance);
ogs_assert(nf_instance->t_validity); ogs_assert(nf_instance->t_validity);
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
OGS_FSM_TRAN(s, &bsf_nf_state_will_register); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_will_register);
} else { } else {
ogs_assert(nf_instance->id); ogs_assert(nf_instance->id);
OGS_FSM_TRAN(s, &bsf_nf_state_registered); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_registered);
} }
} }
void bsf_nf_state_final(ogs_fsm_t *s, bsf_event_t *e) void ogs_sbi_nf_state_final(ogs_fsm_t *s, ogs_event_t *e)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s); ogs_assert(s);
ogs_assert(e); ogs_assert(e);
bsf_sm_debug(e); ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data; nf_instance = e->sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -100,7 +115,7 @@ void bsf_nf_state_final(ogs_fsm_t *s, bsf_event_t *e)
ogs_timer_delete(nf_instance->t_validity); ogs_timer_delete(nf_instance->t_validity);
} }
void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e) void ogs_sbi_nf_state_will_register(ogs_fsm_t *s, ogs_event_t *e)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL; ogs_sbi_client_t *client = NULL;
@ -110,27 +125,26 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
ogs_assert(s); ogs_assert(s);
ogs_assert(e); ogs_assert(e);
bsf_sm_debug(e); ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data; nf_instance = e->sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance); ogs_assert(ogs_sbi_self()->nf_instance);
ogs_assert(NF_INSTANCE_IS_NRF(nf_instance)); ogs_assert(NF_INSTANCE_TYPE_IS_NRF(nf_instance));
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
ogs_timer_start(nf_instance->t_registration_interval, ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.nf_register_interval); ogs_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register( ogs_assert(true == ogs_nnrf_nfm_send_nf_register(nf_instance));
nf_instance, bsf_nnrf_nfm_build_register));
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
ogs_timer_stop(nf_instance->t_registration_interval); ogs_timer_stop(nf_instance->t_registration_interval);
break; break;
case BSF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
message = e->sbi.message; message = e->sbi.message;
ogs_assert(message); ogs_assert(message);
@ -142,13 +156,13 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
if (message->res_status == OGS_SBI_HTTP_STATUS_OK || if (message->res_status == OGS_SBI_HTTP_STATUS_OK ||
message->res_status == OGS_SBI_HTTP_STATUS_CREATED) { message->res_status == OGS_SBI_HTTP_STATUS_CREATED) {
bsf_nnrf_handle_nf_register(nf_instance, message); ogs_sbi_nnrf_handle_nf_register(nf_instance, message);
OGS_FSM_TRAN(s, &bsf_nf_state_registered); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_registered);
} else { } else {
ogs_error("[%s] HTTP Response Status Code [%d]", ogs_error("[%s] HTTP Response Status Code [%d]",
ogs_sbi_self()->nf_instance->id, ogs_sbi_self()->nf_instance->id,
message->res_status); message->res_status);
OGS_FSM_TRAN(s, &bsf_nf_state_exception); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_exception);
} }
break; break;
@ -165,9 +179,9 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
END END
break; break;
case BSF_EVT_SBI_TIMER: case OGS_EVENT_SBI_TIMER:
switch(e->timer_id) { switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL: case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client; client = nf_instance->client;
ogs_assert(client); ogs_assert(client);
addr = client->node.addr; addr = client->node.addr;
@ -179,25 +193,23 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
ogs_timer_start(nf_instance->t_registration_interval, ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.nf_register_interval); ogs_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register( ogs_assert(true == ogs_nnrf_nfm_send_nf_register(nf_instance));
nf_instance, bsf_nnrf_nfm_build_register));
break; break;
default: default:
ogs_error("[%s] Unknown timer[%s:%d]", ogs_error("[%s] Unknown timer[%s:%d]",
ogs_sbi_self()->nf_instance->id, ogs_sbi_self()->nf_instance->id,
bsf_timer_get_name(e->timer_id), e->timer_id); ogs_timer_get_name(e->timer_id), e->timer_id);
} }
break; break;
default: default:
ogs_error("[%s] Unknown event %s", ogs_error("Unknown event %s", ogs_event_get_name(e));
ogs_sbi_self()->nf_instance->id, bsf_event_get_name(e));
break; break;
} }
} }
void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e) void ogs_sbi_nf_state_registered(ogs_fsm_t *s, ogs_event_t *e)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL; ogs_sbi_client_t *client = NULL;
@ -205,7 +217,7 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_assert(s); ogs_assert(s);
ogs_assert(e); ogs_assert(e);
bsf_sm_debug(e); ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data; nf_instance = e->sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -213,7 +225,9 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
int i;
ogs_info("[%s] NF registered [Heartbeat:%ds]", ogs_info("[%s] NF registered [Heartbeat:%ds]",
ogs_sbi_self()->nf_instance->id, ogs_sbi_self()->nf_instance->id,
nf_instance->time.heartbeat_interval); nf_instance->time.heartbeat_interval);
@ -229,12 +243,20 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
nf_instance->time.heartbeat_interval + nf_instance->time.heartbeat_interval +
ogs_app()->time.nf_instance.no_heartbeat_margin)); ogs_app()->time.nf_instance.no_heartbeat_margin));
} }
}
for (i = 0;
i < ogs_sbi_self()->num_of_to_be_notified_nf_type; i++) {
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
ogs_sbi_self()->to_be_notified_nf_type[i]));
}
}
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id); ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
if (nf_instance->time.heartbeat_interval) { if (nf_instance->time.heartbeat_interval) {
@ -242,14 +264,14 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_timer_stop(nf_instance->t_no_heartbeat); ogs_timer_stop(nf_instance->t_no_heartbeat);
} }
if (!OGS_FSM_CHECK(&nf_instance->sm, bsf_nf_state_exception)) { if (!OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) {
ogs_assert(true == ogs_assert(true ==
ogs_nnrf_nfm_send_nf_de_register(nf_instance)); ogs_nnrf_nfm_send_nf_de_register(nf_instance));
} }
} }
break; break;
case BSF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
message = e->sbi.message; message = e->sbi.message;
ogs_assert(message); ogs_assert(message);
@ -271,7 +293,7 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_warn("[%s] HTTP response error [%d]", ogs_warn("[%s] HTTP response error [%d]",
ogs_sbi_self()->nf_instance->id, ogs_sbi_self()->nf_instance->id,
message->res_status); message->res_status);
OGS_FSM_TRAN(s, &bsf_nf_state_exception); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_exception);
} }
break; break;
@ -289,9 +311,9 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
END END
break; break;
case BSF_EVT_SBI_TIMER: case OGS_EVENT_SBI_TIMER:
switch(e->timer_id) { switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL: case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
if (nf_instance->time.heartbeat_interval) if (nf_instance->time.heartbeat_interval)
ogs_timer_start(nf_instance->t_heartbeat_interval, ogs_timer_start(nf_instance->t_heartbeat_interval,
ogs_time_from_sec(nf_instance->time.heartbeat_interval)); ogs_time_from_sec(nf_instance->time.heartbeat_interval));
@ -299,24 +321,24 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_assert(true == ogs_nnrf_nfm_send_nf_update(nf_instance)); ogs_assert(true == ogs_nnrf_nfm_send_nf_update(nf_instance));
break; break;
case BSF_TIMER_NF_INSTANCE_NO_HEARTBEAT: case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
ogs_error("[%s] No heartbeat", ogs_sbi_self()->nf_instance->id); ogs_error("[%s] No heartbeat", ogs_sbi_self()->nf_instance->id);
OGS_FSM_TRAN(s, &bsf_nf_state_will_register); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_will_register);
break; break;
case BSF_TIMER_NF_INSTANCE_VALIDITY: case OGS_TIMER_NF_INSTANCE_VALIDITY:
ogs_assert(!NF_INSTANCE_IS_NRF(nf_instance)); ogs_assert(!NF_INSTANCE_TYPE_IS_NRF(nf_instance));
ogs_assert(nf_instance->id); ogs_assert(nf_instance->id);
ogs_info("[%s] NF expired", nf_instance->id); ogs_info("[%s] NF expired", nf_instance->id);
OGS_FSM_TRAN(s, &bsf_nf_state_de_registered); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_de_registered);
break; break;
default: default:
ogs_error("[%s:%s] Unknown timer[%s:%d]", ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined", nf_instance->id ? nf_instance->id : "Undefined",
bsf_timer_get_name(e->timer_id), e->timer_id); ogs_timer_get_name(e->timer_id), e->timer_id);
} }
break; break;
@ -324,18 +346,18 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_error("[%s:%s] Unknown event %s", ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined", nf_instance->id ? nf_instance->id : "Undefined",
bsf_event_get_name(e)); ogs_event_get_name(e));
break; break;
} }
} }
void bsf_nf_state_de_registered(ogs_fsm_t *s, bsf_event_t *e) void ogs_sbi_nf_state_de_registered(ogs_fsm_t *s, ogs_event_t *e)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s); ogs_assert(s);
ogs_assert(e); ogs_assert(e);
bsf_sm_debug(e); ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data; nf_instance = e->sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -343,7 +365,7 @@ void bsf_nf_state_de_registered(ogs_fsm_t *s, bsf_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id); ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
} }
break; break;
@ -355,12 +377,12 @@ void bsf_nf_state_de_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_error("[%s:%s] Unknown event %s", ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined", nf_instance->id ? nf_instance->id : "Undefined",
bsf_event_get_name(e)); ogs_event_get_name(e));
break; break;
} }
} }
void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e) void ogs_sbi_nf_state_exception(ogs_fsm_t *s, ogs_event_t *e)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL; ogs_sbi_client_t *client = NULL;
@ -369,7 +391,7 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
ogs_assert(s); ogs_assert(s);
ogs_assert(e); ogs_assert(e);
bsf_sm_debug(e); ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data; nf_instance = e->sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -377,7 +399,7 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
ogs_timer_start(nf_instance->t_registration_interval, ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi. ogs_app()->time.message.sbi.
nf_register_interval_in_exception); nf_register_interval_in_exception);
@ -385,14 +407,14 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
ogs_timer_stop(nf_instance->t_registration_interval); ogs_timer_stop(nf_instance->t_registration_interval);
} }
break; break;
case BSF_EVT_SBI_TIMER: case OGS_EVENT_SBI_TIMER:
switch(e->timer_id) { switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL: case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client; client = nf_instance->client;
ogs_assert(client); ogs_assert(client);
addr = client->node.addr; addr = client->node.addr;
@ -401,18 +423,18 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
ogs_warn("[%s] Retry to registration with NRF", ogs_warn("[%s] Retry to registration with NRF",
ogs_sbi_self()->nf_instance->id); ogs_sbi_self()->nf_instance->id);
OGS_FSM_TRAN(s, &bsf_nf_state_will_register); OGS_FSM_TRAN(s, &ogs_sbi_nf_state_will_register);
break; break;
default: default:
ogs_error("[%s:%s] Unknown timer[%s:%d]", ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined", nf_instance->id ? nf_instance->id : "Undefined",
bsf_timer_get_name(e->timer_id), e->timer_id); ogs_timer_get_name(e->timer_id), e->timer_id);
} }
break; break;
case BSF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
message = e->sbi.message; message = e->sbi.message;
ogs_assert(message); ogs_assert(message);
@ -436,7 +458,7 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
ogs_error("[%s:%s] Unknown event %s", ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined", nf_instance->id ? nf_instance->id : "Undefined",
bsf_event_get_name(e)); ogs_event_get_name(e));
break; break;
} }
} }

49
lib/sbi/nf-sm.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_SBI_NF_SM_H
#define OGS_SBI_NF_SM_H
#ifdef __cplusplus
extern "C" {
#endif
void ogs_sbi_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance);
void ogs_sbi_nf_fsm_tran(ogs_sbi_nf_instance_t *nf_instance, void *state);
void ogs_sbi_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance);
void ogs_sbi_nf_state_initial(ogs_fsm_t *s, ogs_event_t *e);
void ogs_sbi_nf_state_final(ogs_fsm_t *s, ogs_event_t *e);
void ogs_sbi_nf_state_will_register(ogs_fsm_t *s, ogs_event_t *e);
void ogs_sbi_nf_state_registered(ogs_fsm_t *s, ogs_event_t *e);
void ogs_sbi_nf_state_de_registered(ogs_fsm_t *s, ogs_event_t *e);
void ogs_sbi_nf_state_exception(ogs_fsm_t *s, ogs_event_t *e);
#define ogs_sbi_sm_debug(__e) \
ogs_debug("%s(): %s", __func__, ogs_event_get_name(__e))
#ifdef __cplusplus
}
#endif
#endif /* OGS_SBI_NF_SM_H */

View File

@ -32,11 +32,6 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
OpenAPI_list_t *NFServiceList = NULL; OpenAPI_list_t *NFServiceList = NULL;
int i = 0; int i = 0;
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
int fqdn_len;
char fqdn[OGS_MAX_FQDN_LEN];
#endif
char *ipstr = NULL; char *ipstr = NULL;
nf_instance = ogs_sbi_self()->nf_instance; nf_instance = ogs_sbi_self()->nf_instance;
@ -64,22 +59,8 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
NFProfile->is_nf_profile_changes_support_ind = true; NFProfile->is_nf_profile_changes_support_ind = true;
NFProfile->nf_profile_changes_support_ind = true; NFProfile->nf_profile_changes_support_ind = true;
if (nf_instance->fqdn) { if (nf_instance->fqdn)
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
memset(fqdn, 0, sizeof(fqdn));
fqdn_len = ogs_fqdn_build(fqdn,
nf_instance->fqdn, strlen(nf_instance->fqdn));
NFProfile->fqdn = ogs_memdup(fqdn, fqdn_len+1);
ogs_expect_or_return_val(NFProfile->fqdn, NULL);
NFProfile->fqdn[fqdn_len] = 0;
ogs_debug("NFInstance-FQDN[%s]", nf_instance->fqdn);
ogs_log_hexdump(OGS_LOG_DEBUG,
(unsigned char *)NFProfile->fqdn, fqdn_len);
#else
NFProfile->fqdn = ogs_strdup(nf_instance->fqdn); NFProfile->fqdn = ogs_strdup(nf_instance->fqdn);
#endif
}
NFProfile->is_priority = true; NFProfile->is_priority = true;
NFProfile->priority = nf_instance->priority; NFProfile->priority = nf_instance->priority;
@ -131,7 +112,7 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
for (i = 0; i < nf_instance->num_of_allowed_nf_type; i++) { for (i = 0; i < nf_instance->num_of_allowed_nf_type; i++) {
OpenAPI_list_add(AllowedNfTypeList, OpenAPI_list_add(AllowedNfTypeList,
(void *)(uintptr_t)nf_instance->allowed_nf_types[i]); (void *)(uintptr_t)nf_instance->allowed_nf_type[i]);
} }
if (AllowedNfTypeList->count) if (AllowedNfTypeList->count)
@ -163,21 +144,21 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
NFServiceVersion = ogs_calloc(1, sizeof(*NFServiceVersion)); NFServiceVersion = ogs_calloc(1, sizeof(*NFServiceVersion));
ogs_expect_or_return_val(NFServiceVersion, NULL); ogs_expect_or_return_val(NFServiceVersion, NULL);
if (nf_service->versions[i].in_uri) { if (nf_service->version[i].in_uri) {
NFServiceVersion->api_version_in_uri = NFServiceVersion->api_version_in_uri =
ogs_strdup(nf_service->versions[i].in_uri); ogs_strdup(nf_service->version[i].in_uri);
ogs_expect_or_return_val( ogs_expect_or_return_val(
NFServiceVersion->api_version_in_uri, NULL); NFServiceVersion->api_version_in_uri, NULL);
} }
if (nf_service->versions[i].full) { if (nf_service->version[i].full) {
NFServiceVersion->api_full_version = NFServiceVersion->api_full_version =
ogs_strdup(nf_service->versions[i].full); ogs_strdup(nf_service->version[i].full);
ogs_expect_or_return_val( ogs_expect_or_return_val(
NFServiceVersion->api_full_version, NULL); NFServiceVersion->api_full_version, NULL);
} }
if (nf_service->versions[i].expiry) { if (nf_service->version[i].expiry) {
NFServiceVersion->expiry = NFServiceVersion->expiry =
ogs_strdup(nf_service->versions[i].expiry); ogs_strdup(nf_service->version[i].expiry);
ogs_expect_or_return_val( ogs_expect_or_return_val(
NFServiceVersion->expiry, NULL); NFServiceVersion->expiry, NULL);
} }
@ -191,22 +172,8 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
NFService->scheme = nf_service->scheme; NFService->scheme = nf_service->scheme;
NFService->nf_service_status = nf_service->status; NFService->nf_service_status = nf_service->status;
if (nf_service->fqdn) { if (nf_service->fqdn)
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
memset(fqdn, 0, sizeof(fqdn));
fqdn_len = ogs_fqdn_build(fqdn,
nf_service->fqdn, strlen(nf_service->fqdn));
NFService->fqdn = ogs_memdup(fqdn, fqdn_len+1);
ogs_expect_or_return_val(NFService->fqdn, NULL);
NFService->fqdn[fqdn_len] = 0;
ogs_debug("NFService-FQDN[%s]", nf_service->fqdn);
ogs_log_hexdump(OGS_LOG_DEBUG,
(unsigned char *)NFService->fqdn, fqdn_len);
#else
NFService->fqdn = ogs_strdup(nf_service->fqdn); NFService->fqdn = ogs_strdup(nf_service->fqdn);
#endif
}
IpEndPointList = OpenAPI_list_create(); IpEndPointList = OpenAPI_list_create();
ogs_assert(IpEndPointList); ogs_assert(IpEndPointList);
@ -333,6 +300,284 @@ void ogs_sbi_nnrf_free_nf_profile(OpenAPI_nf_profile_t *NFProfile)
ogs_free(NFProfile); ogs_free(NFProfile);
} }
ogs_sbi_request_t *ogs_nnrf_nfm_build_register(void)
{
int i, j;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_nf_info_t *nf_info = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
OpenAPI_nf_profile_t *NFProfile = NULL;
OpenAPI_list_t *SmfInfoList = NULL;
OpenAPI_map_t *SmfInfoMap = NULL;
OpenAPI_smf_info_t *SmfInfo = NULL;
int SmfInfoMapKey;
OpenAPI_list_t *sNssaiSmfInfoList = NULL;
OpenAPI_snssai_smf_info_item_t *sNssaiSmfInfoItem = NULL;
OpenAPI_snssai_t *sNssai = NULL;
OpenAPI_list_t *DnnSmfInfoList = NULL;
OpenAPI_dnn_smf_info_item_t *DnnSmfInfoItem = NULL;
OpenAPI_list_t *TaiList = NULL;
OpenAPI_tai_t *TaiItem = NULL;
OpenAPI_list_t *TaiRangeList = NULL;
OpenAPI_tai_range_t *TaiRangeItem = NULL;
OpenAPI_list_t *TacRangeList = NULL;
OpenAPI_tac_range_t *TacRangeItem = NULL;
OpenAPI_lnode_t *node = NULL, *node2 = NULL, *node3 = NULL;
nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance);
ogs_assert(nf_instance->id);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
message.h.resource.component[1] = nf_instance->id;
message.http.content_encoding = (char*)ogs_sbi_self()->content_encoding;
SmfInfoList = OpenAPI_list_create();
ogs_assert(SmfInfoList);
SmfInfoMapKey = 0;
ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
if (nf_info->nf_type == OpenAPI_nf_type_SMF) {
if (nf_info->smf.num_of_slice == 0) {
ogs_fatal("CHECK CONFIGURATION: No S-NSSAI");
ogs_assert_if_reached();
}
SmfInfo = ogs_calloc(1, sizeof(*SmfInfo));
ogs_expect_or_return_val(SmfInfo, NULL);
sNssaiSmfInfoList = OpenAPI_list_create();
ogs_assert(sNssaiSmfInfoList);
for (i = 0; i < nf_info->smf.num_of_slice; i++) {
DnnSmfInfoList = OpenAPI_list_create();
ogs_assert(DnnSmfInfoList);
for (j = 0; j < nf_info->smf.slice[i].num_of_dnn; j++) {
DnnSmfInfoItem = ogs_calloc(1, sizeof(*DnnSmfInfoItem));
ogs_expect_or_return_val(DnnSmfInfoItem, NULL);
DnnSmfInfoItem->dnn = nf_info->smf.slice[i].dnn[j];
OpenAPI_list_add(DnnSmfInfoList, DnnSmfInfoItem);
}
if (!DnnSmfInfoList->count) {
OpenAPI_list_free(DnnSmfInfoList);
ogs_error("CHECK CONFIGURATION: No DNN");
ogs_expect_or_return_val(0, NULL);
}
sNssaiSmfInfoItem = ogs_calloc(1, sizeof(*sNssaiSmfInfoItem));
ogs_expect_or_return_val(sNssaiSmfInfoItem, NULL);
sNssaiSmfInfoItem->dnn_smf_info_list = DnnSmfInfoList;
sNssaiSmfInfoItem->s_nssai = sNssai =
ogs_calloc(1, sizeof(*sNssai));
ogs_expect_or_return_val(sNssai, NULL);
sNssai->sst = nf_info->smf.slice[i].s_nssai.sst;
sNssai->sd =
ogs_s_nssai_sd_to_string(nf_info->smf.slice[i].s_nssai.sd);
OpenAPI_list_add(sNssaiSmfInfoList, sNssaiSmfInfoItem);
}
if (sNssaiSmfInfoList->count)
SmfInfo->s_nssai_smf_info_list = sNssaiSmfInfoList;
else
OpenAPI_list_free(sNssaiSmfInfoList);
TaiList = OpenAPI_list_create();
ogs_assert(TaiList);
for (i = 0; i < nf_info->smf.num_of_nr_tai; i++) {
TaiItem = ogs_calloc(1, sizeof(*TaiItem));
ogs_expect_or_return_val(TaiItem, NULL);
TaiItem->plmn_id = ogs_sbi_build_plmn_id(
&nf_info->smf.nr_tai[i].plmn_id);
ogs_expect_or_return_val(TaiItem->plmn_id, NULL);
TaiItem->tac =
ogs_uint24_to_0string(nf_info->smf.nr_tai[i].tac);
ogs_expect_or_return_val(TaiItem->tac, NULL);
OpenAPI_list_add(TaiList, TaiItem);
}
if (TaiList->count)
SmfInfo->tai_list = TaiList;
else
OpenAPI_list_free(TaiList);
TaiRangeList = OpenAPI_list_create();
ogs_assert(TaiRangeList);
for (i = 0; i < nf_info->smf.num_of_nr_tai_range; i++) {
TacRangeList = OpenAPI_list_create();
ogs_assert(TacRangeList);
for (j = 0;
j < nf_info->smf.nr_tai_range[i].num_of_tac_range;
j++) {
TacRangeItem = ogs_calloc(1, sizeof(*TacRangeItem));
ogs_expect_or_return_val(TacRangeItem, NULL);
TacRangeItem->start = ogs_uint24_to_0string(
nf_info->smf.nr_tai_range[i].start[j]);
ogs_expect_or_return_val(TacRangeItem->start, NULL);
TacRangeItem->end =
ogs_uint24_to_0string(
nf_info->smf.nr_tai_range[i].end[j]);
ogs_expect_or_return_val(TacRangeItem->end, NULL);
OpenAPI_list_add(TacRangeList, TacRangeItem);
}
if (!TacRangeList->count) {
OpenAPI_list_free(TacRangeList);
ogs_error("CHECK CONFIGURATION: No Start/End in TacRange");
ogs_expect_or_return_val(0, NULL);
}
TaiRangeItem = ogs_calloc(1, sizeof(*TaiRangeItem));
ogs_expect_or_return_val(TaiRangeItem, NULL);
TaiRangeItem->plmn_id = ogs_sbi_build_plmn_id(
&nf_info->smf.nr_tai_range[i].plmn_id);
ogs_expect_or_return_val(TaiRangeItem->plmn_id, NULL);
TaiRangeItem->tac_range_list = TacRangeList;
OpenAPI_list_add(TaiRangeList, TaiRangeItem);
}
if (TaiRangeList->count)
SmfInfo->tai_range_list = TaiRangeList;
else
OpenAPI_list_free(TaiRangeList);
SmfInfoMap = OpenAPI_map_create(
ogs_msprintf("%d", ++SmfInfoMapKey), SmfInfo);
ogs_assert(SmfInfoMap);
OpenAPI_list_add(SmfInfoList, SmfInfoMap);
} else {
ogs_fatal("Not implemented NF-type[%s]",
OpenAPI_nf_type_ToString(nf_info->nf_type));
ogs_assert_if_reached();
}
}
NFProfile = ogs_nnrf_nfm_build_nf_profile();
ogs_expect_or_return_val(NFProfile, NULL);
if (SmfInfoList->count == 1) {
NFProfile->smf_info = SmfInfo;
} else if (SmfInfoList->count > 1) {
NFProfile->smf_info_list = SmfInfoList;
}
message.NFProfile = NFProfile;
request = ogs_sbi_build_request(&message);
ogs_sbi_nnrf_free_nf_profile(NFProfile);
OpenAPI_list_for_each(SmfInfoList, node) {
SmfInfoMap = node->data;
if (SmfInfoMap) {
SmfInfo = SmfInfoMap->value;
if (SmfInfo) {
sNssaiSmfInfoList = SmfInfo->s_nssai_smf_info_list;
OpenAPI_list_for_each(sNssaiSmfInfoList, node2) {
sNssaiSmfInfoItem = node2->data;
ogs_assert(sNssaiSmfInfoItem);
DnnSmfInfoList = sNssaiSmfInfoItem->dnn_smf_info_list;
OpenAPI_list_for_each(DnnSmfInfoList, node3) {
DnnSmfInfoItem = node3->data;
ogs_assert(DnnSmfInfoItem);
ogs_free(DnnSmfInfoItem);
}
OpenAPI_list_free(DnnSmfInfoList);
sNssai = sNssaiSmfInfoItem->s_nssai;
if (sNssai) {
if (sNssai->sd)
ogs_free(sNssai->sd);
ogs_free(sNssai);
}
ogs_free(sNssaiSmfInfoItem);
}
OpenAPI_list_free(sNssaiSmfInfoList);
TaiList = SmfInfo->tai_list;
OpenAPI_list_for_each(TaiList, node2) {
TaiItem = node2->data;
ogs_assert(TaiItem);
if (TaiItem->plmn_id)
ogs_sbi_free_plmn_id(TaiItem->plmn_id);
if (TaiItem->tac)
ogs_free(TaiItem->tac);
ogs_free(TaiItem);
}
OpenAPI_list_free(TaiList);
TaiRangeList = SmfInfo->tai_range_list;
OpenAPI_list_for_each(TaiRangeList, node2) {
TaiRangeItem = node2->data;
ogs_assert(TaiRangeItem);
if (TaiRangeItem->plmn_id)
ogs_sbi_free_plmn_id(TaiRangeItem->plmn_id);
TacRangeList = TaiRangeItem->tac_range_list;
OpenAPI_list_for_each(TacRangeList, node3) {
TacRangeItem = node3->data;
ogs_assert(TacRangeItem);
if (TacRangeItem->start)
ogs_free(TacRangeItem->start);
if (TacRangeItem->end)
ogs_free(TacRangeItem->end);
ogs_free(TacRangeItem);
}
OpenAPI_list_free(TacRangeList);
ogs_free(TaiRangeItem);
}
OpenAPI_list_free(TaiRangeList);
ogs_free(SmfInfo);
}
if (SmfInfoMap->key)
ogs_free(SmfInfoMap->key);
ogs_free(SmfInfoMap);
}
}
OpenAPI_list_free(SmfInfoList);
return request;
}
ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void)
{ {
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;

View File

@ -27,6 +27,7 @@ extern "C" {
OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void); OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void);
void ogs_sbi_nnrf_free_nf_profile(OpenAPI_nf_profile_t *NFProfile); void ogs_sbi_nnrf_free_nf_profile(OpenAPI_nf_profile_t *NFProfile);
ogs_sbi_request_t *ogs_nnrf_nfm_build_register(void);
ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void); ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void);
ogs_sbi_request_t *ogs_nnrf_nfm_build_de_register(void); ogs_sbi_request_t *ogs_nnrf_nfm_build_de_register(void);

View File

@ -20,6 +20,245 @@
#include "ogs-sbi.h" #include "ogs-sbi.h"
#include "ogs-app.h" #include "ogs-app.h"
static void handle_smf_info(
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_smf_info_t *SmfInfo);
void ogs_sbi_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg)
{
OpenAPI_nf_profile_t *NFProfile = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(recvmsg);
ogs_assert(nf_instance);
client = nf_instance->client;
ogs_assert(client);
NFProfile = recvmsg->NFProfile;
if (!NFProfile) {
ogs_error("No NFProfile");
return;
}
/* TIME : Update heartbeat from NRF */
if (NFProfile->is_heart_beat_timer == true)
nf_instance->time.heartbeat_interval = NFProfile->heart_beat_timer;
}
void ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance,
OpenAPI_nf_profile_t *NFProfile,
ogs_sbi_stream_t *stream, ogs_sbi_message_t *message)
{
int rv;
OpenAPI_lnode_t *node;
ogs_sbi_nf_service_t *nf_service = NULL, *next_nf_service = NULL;
ogs_assert(nf_instance);
ogs_assert(NFProfile);
ogs_assert(NFProfile->nf_instance_id);
ogs_assert(NFProfile->nf_type);
ogs_assert(NFProfile->nf_status);
ogs_list_for_each_safe(&nf_instance->nf_service_list,
next_nf_service, nf_service) {
bool nf_service_should_not_be_deleted = false;
ogs_assert(nf_service->id);
OpenAPI_list_for_each(NFProfile->nf_services, node) {
OpenAPI_nf_service_t *NFService = node->data;
if (!NFService) continue;
if (!NFService->service_instance_id) continue;
if (!NFService->service_name) continue;
if (strcmp(nf_service->id, NFService->service_instance_id) == 0) {
nf_service_should_not_be_deleted = true;
break;
}
}
if (nf_service_should_not_be_deleted == false) {
ogs_warn("NFService[%s:%s] removed",
nf_service->id, nf_service->name);
OpenAPI_list_for_each(NFProfile->nf_services, node) {
OpenAPI_nf_service_t *NFService = node->data;
if (!NFService) continue;
if (!NFService->service_instance_id) continue;
if (!NFService->service_name) continue;
ogs_warn("NFService[%s:%s] will be added",
NFService->service_instance_id, NFService->service_name);
}
ogs_sbi_nf_service_remove(nf_service);
}
}
ogs_sbi_nf_instance_clear(nf_instance);
nf_instance->nf_type = NFProfile->nf_type;
nf_instance->nf_status = NFProfile->nf_status;
if (NFProfile->is_heart_beat_timer == true)
nf_instance->time.heartbeat_interval = NFProfile->heart_beat_timer;
if (NFProfile->fqdn)
nf_instance->fqdn = ogs_strdup(NFProfile->fqdn);
if (NFProfile->is_priority == true)
nf_instance->priority = NFProfile->priority;
if (NFProfile->is_capacity == true)
nf_instance->capacity = NFProfile->capacity;
if (NFProfile->is_load == true)
nf_instance->load = NFProfile->load;
/* Only one time handles RegisterNFInstance operation */
OpenAPI_list_for_each(NFProfile->ipv4_addresses, node) {
ogs_sockaddr_t *addr = NULL;
if (!node->data) continue;
if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
node->data, ogs_sbi_self()->sbi_port, 0);
if (rv != OGS_OK) continue;
nf_instance->ipv4[nf_instance->num_of_ipv4] = addr;
nf_instance->num_of_ipv4++;
}
}
OpenAPI_list_for_each(NFProfile->ipv6_addresses, node) {
ogs_sockaddr_t *addr = NULL;
if (!node->data) continue;
if (nf_instance->num_of_ipv6 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
node->data, ogs_sbi_self()->sbi_port, 0);
if (rv != OGS_OK) continue;
nf_instance->ipv6[nf_instance->num_of_ipv6] = addr;
nf_instance->num_of_ipv6++;
}
}
OpenAPI_list_for_each(NFProfile->nf_services, node) {
OpenAPI_nf_service_t *NFService = node->data;
OpenAPI_list_t *VersionList = NULL;
OpenAPI_list_t *IpEndPointList = NULL;
OpenAPI_list_t *AllowedNfTypeList = NULL;
OpenAPI_lnode_t *node2 = NULL;
if (!NFService) continue;
if (!NFService->service_instance_id) continue;
if (!NFService->service_name) continue;
VersionList = NFService->versions;
IpEndPointList = NFService->ip_end_points;
AllowedNfTypeList = NFService->allowed_nf_types;
nf_service = ogs_sbi_nf_service_find_by_id(nf_instance,
NFService->service_instance_id);
if (!nf_service) {
nf_service = ogs_sbi_nf_service_add(nf_instance,
NFService->service_instance_id,
NFService->service_name, NFService->scheme);
ogs_assert(nf_service);
}
ogs_sbi_nf_service_clear(nf_service);
OpenAPI_list_for_each(VersionList, node2) {
OpenAPI_nf_service_version_t *NFServiceVersion = node2->data;
if (!NFServiceVersion) continue;
ogs_sbi_nf_service_add_version(nf_service,
NFServiceVersion->api_version_in_uri,
NFServiceVersion->api_full_version,
NFServiceVersion->expiry);
}
if (NFService->fqdn)
nf_service->fqdn = ogs_strdup(NFService->fqdn);
OpenAPI_list_for_each(IpEndPointList, node2) {
OpenAPI_ip_end_point_t *IpEndPoint = node2->data;
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
int port = 0;
if (!IpEndPoint) continue;
if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
if (!IpEndPoint->is_port) {
if (nf_service->scheme == OpenAPI_uri_scheme_http)
port = OGS_SBI_HTTP_PORT;
else if (nf_service->scheme == OpenAPI_uri_scheme_https)
port = OGS_SBI_HTTPS_PORT;
else
continue;
} else {
port = IpEndPoint->port;
}
if (IpEndPoint->ipv4_address) {
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
IpEndPoint->ipv4_address, port, 0);
if (rv != OGS_OK) continue;
}
if (IpEndPoint->ipv6_address) {
rv = ogs_getaddrinfo(&addr6, AF_UNSPEC,
IpEndPoint->ipv6_address, port, 0);
if (rv != OGS_OK) continue;
}
if (addr || addr6) {
nf_service->addr[nf_service->num_of_addr].
port = port;
nf_service->addr[nf_service->num_of_addr].
ipv4 = addr;
nf_service->addr[nf_service->num_of_addr].
ipv6 = addr6;
nf_service->num_of_addr++;
}
}
}
OpenAPI_list_for_each(AllowedNfTypeList, node2) {
OpenAPI_nf_type_e AllowedNfType = (uintptr_t)node2->data;
if (!AllowedNfType) continue;
if (nf_service->num_of_allowed_nf_type <
OGS_SBI_MAX_NUM_OF_NF_TYPE) {
nf_service->allowed_nf_types[
nf_service->num_of_allowed_nf_type] = AllowedNfType;
nf_service->num_of_allowed_nf_type++;
}
}
if (NFService->is_priority == true)
nf_service->priority = NFService->priority;
if (NFService->is_capacity == true)
nf_service->capacity = NFService->capacity;
if (NFService->is_load == true)
nf_service->load = NFService->load;
}
ogs_sbi_nf_info_remove_all(&nf_instance->nf_info_list);
if (NFProfile->smf_info)
handle_smf_info(nf_instance, NFProfile->smf_info);
OpenAPI_list_for_each(NFProfile->smf_info_list, node) {
OpenAPI_map_t *SmfInfoMap = node->data;
if (SmfInfoMap && SmfInfoMap->value)
handle_smf_info(nf_instance, SmfInfoMap->value);
}
}
static void handle_smf_info( static void handle_smf_info(
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_smf_info_t *SmfInfo) ogs_sbi_nf_instance_t *nf_instance, OpenAPI_smf_info_t *SmfInfo)
{ {
@ -153,291 +392,306 @@ static void handle_smf_info(
} }
} }
bool ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance, void ogs_nnrf_handle_nf_status_subscribe(
OpenAPI_nf_profile_t *NFProfile, ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg)
ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) {
OpenAPI_subscription_data_t *SubscriptionData = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(recvmsg);
ogs_assert(subscription);
client = subscription->client;
ogs_assert(client);
SubscriptionData = recvmsg->SubscriptionData;
if (!SubscriptionData) {
ogs_error("No SubscriptionData");
return;
}
if (!SubscriptionData->subscription_id) {
ogs_error("No SubscriptionId");
return;
}
ogs_sbi_subscription_set_id(
subscription, SubscriptionData->subscription_id);
if (SubscriptionData->validity_time) {
#define VALIDITY_MINIMUM (10LL * OGS_USEC_PER_SEC) /* 10 seconds */
ogs_time_t time, duration;
if (ogs_sbi_time_from_string(
&time, SubscriptionData->validity_time) == true) {
duration = time - ogs_time_now();
if (duration < VALIDITY_MINIMUM) {
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %lld seconds", subscription->id,
(long long)ogs_time_sec(VALIDITY_MINIMUM));
}
subscription->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
ogs_timer_subscription_validity, subscription);
ogs_assert(subscription->t_validity);
ogs_timer_start(subscription->t_validity, duration);
} else {
ogs_error("Cannot parse validitiyTime [%s]",
SubscriptionData->validity_time);
}
}
}
bool ogs_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{ {
int rv; int rv;
OpenAPI_lnode_t *node; ogs_sbi_response_t *response = NULL;
ogs_sbi_nf_service_t *nf_service = NULL, *next_nf_service = NULL; OpenAPI_notification_data_t *NotificationData = NULL;
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH ogs_sbi_nf_instance_t *nf_instance = NULL;
char fqdn[OGS_MAX_FQDN_LEN+1];
#endif
ogs_assert(nf_instance); ogs_sbi_message_t message;
ogs_assert(NFProfile); ogs_sbi_header_t header;
if (!NFProfile) { ogs_assert(stream);
ogs_error("No NFProfile"); ogs_assert(recvmsg);
if (stream)
ogs_assert(true == NotificationData = recvmsg->NotificationData;
ogs_sbi_server_send_error( if (!NotificationData) {
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, ogs_error("No NotificationData");
message, "No NFProfile", NULL)); ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NotificationData", NULL));
return false; return false;
} }
if (!NFProfile->nf_instance_id) { if (!NotificationData->nf_instance_uri) {
ogs_error("No NFProfile.NFInstanceId"); ogs_error("No nfInstanceUri");
if (stream) ogs_assert(true ==
ogs_assert(true == ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
ogs_sbi_server_send_error( recvmsg, "No nfInstanceUri", NULL));
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "NFProfile", "No NFInstanceId"));
return false; return false;
} }
if (!NFProfile->nf_type) { memset(&header, 0, sizeof(header));
ogs_error("No NFProfile.NFType"); header.uri = NotificationData->nf_instance_uri;
if (stream)
ogs_assert(true == rv = ogs_sbi_parse_header(&message, &header);
ogs_sbi_server_send_error( if (rv != OGS_OK) {
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, ogs_error("Cannot parse nfInstanceUri [%s]", header.uri);
message, "NFProfile", "No NFType")); ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot parse nfInstanceUri", header.uri));
return false; return false;
} }
if (!NFProfile->nf_status) { if (!message.h.resource.component[1]) {
ogs_error("No NFProfile.NFStatus"); ogs_error("No nfInstanceId [%s]", header.uri);
if (stream) ogs_assert(true ==
ogs_assert(true == ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
ogs_sbi_server_send_error( recvmsg, "Cannot parse nfInstanceUri", header.uri));
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, ogs_sbi_header_free(&header);
message, "NFProfile", "No NFStatus"));
return false; return false;
} }
ogs_list_for_each_safe(&nf_instance->nf_service_list, if (NF_INSTANCE_ID_IS_SELF(message.h.resource.component[1])) {
next_nf_service, nf_service) { ogs_warn("[%s] The notification is not allowed",
bool nf_service_should_not_be_deleted = false; message.h.resource.component[1]);
ogs_assert(true ==
ogs_assert(nf_service->id); ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN,
recvmsg, "The notification is not allowed",
OpenAPI_list_for_each(NFProfile->nf_services, node) { message.h.resource.component[1]));
OpenAPI_nf_service_t *NFService = node->data; ogs_sbi_header_free(&header);
return false;
if (!NFService) continue;
if (!NFService->service_instance_id) continue;
if (!NFService->service_name) continue;
if (strcmp(nf_service->id, NFService->service_instance_id) == 0) {
nf_service_should_not_be_deleted = true;
break;
}
}
if (nf_service_should_not_be_deleted == false) {
ogs_warn("NFService[%s:%s] removed",
nf_service->id, nf_service->name);
OpenAPI_list_for_each(NFProfile->nf_services, node) {
OpenAPI_nf_service_t *NFService = node->data;
if (!NFService) continue;
if (!NFService->service_instance_id) continue;
if (!NFService->service_name) continue;
ogs_warn("NFService[%s:%s] will be added",
NFService->service_instance_id, NFService->service_name);
}
ogs_sbi_nf_service_remove(nf_service);
}
} }
ogs_sbi_nf_instance_clear(nf_instance);
nf_instance->nf_type = NFProfile->nf_type; if (NotificationData->event ==
nf_instance->nf_status = NFProfile->nf_status; OpenAPI_notification_event_type_NF_REGISTERED) {
if (NFProfile->is_heart_beat_timer == true)
nf_instance->time.heartbeat_interval = NFProfile->heart_beat_timer;
if (NFProfile->fqdn) { OpenAPI_nf_profile_t *NFProfile = NULL;
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
if (ogs_fqdn_parse(
fqdn, NFProfile->fqdn,
ogs_min(strlen(NFProfile->fqdn), OGS_MAX_FQDN_LEN)) > 0) {
/* Nothing : succeeded to parse FQDN */ NFProfile = NotificationData->nf_profile;
nf_instance->fqdn = ogs_strdup(fqdn); if (!NFProfile) {
ogs_assert(nf_instance); ogs_error("No NFProfile");
ogs_assert(true ==
} else { ogs_sbi_server_send_error(
ogs_error("ogs_fqdn_parse() failed[%s]", NFProfile->fqdn); stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NFProfile", NULL));
ogs_sbi_header_free(&header);
return false; return false;
} }
#else
nf_instance->fqdn = ogs_strdup(NFProfile->fqdn);
#endif
}
if (NFProfile->is_priority == true) if (!NFProfile->nf_instance_id) {
nf_instance->priority = NFProfile->priority; ogs_error("No NFProfile.NFInstanceId");
if (NFProfile->is_capacity == true) ogs_assert(true ==
nf_instance->capacity = NFProfile->capacity; ogs_sbi_server_send_error(
if (NFProfile->is_load == true) stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
nf_instance->load = NFProfile->load; recvmsg, "No NFProfile.NFInstanceId", NULL));
ogs_sbi_header_free(&header);
/* Only one time handles RegisterNFInstance operation */ return false;
OpenAPI_list_for_each(NFProfile->ipv4_addresses, node) {
ogs_sockaddr_t *addr = NULL;
if (!node->data) continue;
if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
node->data, ogs_sbi_self()->sbi_port, 0);
if (rv != OGS_OK) continue;
nf_instance->ipv4[nf_instance->num_of_ipv4] = addr;
nf_instance->num_of_ipv4++;
}
}
OpenAPI_list_for_each(NFProfile->ipv6_addresses, node) {
ogs_sockaddr_t *addr = NULL;
if (!node->data) continue;
if (nf_instance->num_of_ipv6 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
node->data, ogs_sbi_self()->sbi_port, 0);
if (rv != OGS_OK) continue;
nf_instance->ipv6[nf_instance->num_of_ipv6] = addr;
nf_instance->num_of_ipv6++;
}
}
OpenAPI_list_for_each(NFProfile->nf_services, node) {
OpenAPI_nf_service_t *NFService = node->data;
OpenAPI_list_t *VersionList = NULL;
OpenAPI_list_t *IpEndPointList = NULL;
OpenAPI_list_t *AllowedNfTypeList = NULL;
OpenAPI_lnode_t *node2 = NULL;
if (!NFService) continue;
if (!NFService->service_instance_id) continue;
if (!NFService->service_name) continue;
VersionList = NFService->versions;
IpEndPointList = NFService->ip_end_points;
AllowedNfTypeList = NFService->allowed_nf_types;
nf_service = ogs_sbi_nf_service_find_by_id(nf_instance,
NFService->service_instance_id);
if (!nf_service) {
nf_service = ogs_sbi_nf_service_add(nf_instance,
NFService->service_instance_id,
NFService->service_name, NFService->scheme);
ogs_assert(nf_service);
} }
ogs_sbi_nf_service_clear(nf_service); if (!NFProfile->nf_type) {
ogs_error("No NFProfile.NFType");
OpenAPI_list_for_each(VersionList, node2) { ogs_assert(true ==
OpenAPI_nf_service_version_t *NFServiceVersion = node2->data; ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
if (!NFServiceVersion) continue; recvmsg, "No NFProfile.NFType", NULL));
ogs_sbi_header_free(&header);
ogs_sbi_nf_service_add_version(nf_service, return false;
NFServiceVersion->api_version_in_uri,
NFServiceVersion->api_full_version,
NFServiceVersion->expiry);
} }
if (NFService->fqdn) { if (!NFProfile->nf_status) {
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH ogs_error("No NFProfile.NFStatus");
if (ogs_fqdn_parse( ogs_assert(true ==
fqdn, NFService->fqdn, ogs_sbi_server_send_error(
ogs_min(strlen(NFService->fqdn), OGS_MAX_FQDN_LEN)) > 0) { stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NFProfile.NFStatus", NULL));
ogs_sbi_header_free(&header);
return false;
}
/* Nothing : succeeded to parse FQDN */ nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
nf_service->fqdn = ogs_strdup(fqdn); if (!nf_instance) {
ogs_assert(nf_service); nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(
nf_instance, message.h.resource.component[1]);
ogs_sbi_nf_fsm_init(nf_instance);
ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id);
} else {
ogs_sbi_nf_fsm_tran(nf_instance, ogs_sbi_nf_state_registered);
ogs_warn("[%s] (NRF-notify) NF has already been added",
message.h.resource.component[1]);
}
ogs_sbi_nnrf_handle_nf_profile(nf_instance, NFProfile, stream, recvmsg);
ogs_info("[%s] (NRF-notify) NF Profile updated", nf_instance->id);
ogs_sbi_client_associate(nf_instance);
} else if (NotificationData->event ==
OpenAPI_notification_event_type_NF_DEREGISTERED) {
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
if (nf_instance) {
if (OGS_OBJECT_IS_REF(nf_instance)) {
/* There are references to other contexts. */
ogs_warn("[%s:%d] NF was referenced in other contexts",
nf_instance->id, nf_instance->reference_count);
ogs_sbi_nf_fsm_tran(
nf_instance, ogs_sbi_nf_state_de_registered);
} else { } else {
ogs_error("ogs_fqdn_parse() failed[%s]", NFService->fqdn); ogs_info("[%s] NF removed", nf_instance->id);
return false; ogs_sbi_nf_fsm_fini((nf_instance));
ogs_sbi_nf_instance_remove(nf_instance);
} }
#else } else {
nf_service->fqdn = ogs_strdup(NFService->fqdn); ogs_warn("[%s] (NRF-notify) Not found",
ogs_assert(nf_service); message.h.resource.component[1]);
#endif ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_NOT_FOUND,
recvmsg, "Not found", message.h.resource.component[1]));
ogs_sbi_header_free(&header);
return false;
} }
} else {
OpenAPI_list_for_each(IpEndPointList, node2) { char *eventstr = OpenAPI_notification_event_type_ToString(
OpenAPI_ip_end_point_t *IpEndPoint = node2->data; NotificationData->event);
ogs_sockaddr_t *addr = NULL, *addr6 = NULL; ogs_error("Not supported event [%d:%s]",
int port = 0; NotificationData->event, eventstr ? eventstr : "Unknown");
ogs_assert(true ==
if (!IpEndPoint) continue; ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Not supported event",
if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) { eventstr ? eventstr : "Unknown"));
if (!IpEndPoint->is_port) { ogs_sbi_header_free(&header);
if (nf_service->scheme == OpenAPI_uri_scheme_http) return false;
port = OGS_SBI_HTTP_PORT;
else if (nf_service->scheme == OpenAPI_uri_scheme_https)
port = OGS_SBI_HTTPS_PORT;
else
continue;
} else {
port = IpEndPoint->port;
}
if (IpEndPoint->ipv4_address) {
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
IpEndPoint->ipv4_address, port, 0);
if (rv != OGS_OK) continue;
}
if (IpEndPoint->ipv6_address) {
rv = ogs_getaddrinfo(&addr6, AF_UNSPEC,
IpEndPoint->ipv6_address, port, 0);
if (rv != OGS_OK) continue;
}
if (addr || addr6) {
nf_service->addr[nf_service->num_of_addr].
port = port;
nf_service->addr[nf_service->num_of_addr].
ipv4 = addr;
nf_service->addr[nf_service->num_of_addr].
ipv6 = addr6;
nf_service->num_of_addr++;
}
}
}
OpenAPI_list_for_each(AllowedNfTypeList, node2) {
OpenAPI_nf_type_e AllowedNfType = (uintptr_t)node2->data;
if (!AllowedNfType) continue;
if (nf_service->num_of_allowed_nf_type <
OGS_SBI_MAX_NUM_OF_NF_TYPE) {
nf_service->allowed_nf_types[
nf_service->num_of_allowed_nf_type] = AllowedNfType;
nf_service->num_of_allowed_nf_type++;
}
}
if (NFService->is_priority == true)
nf_service->priority = NFService->priority;
if (NFService->is_capacity == true)
nf_service->capacity = NFService->capacity;
if (NFService->is_load == true)
nf_service->load = NFService->load;
} }
ogs_sbi_nf_info_remove_all(&nf_instance->nf_info_list); response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
if (NFProfile->smf_info) ogs_assert(true == ogs_sbi_server_send_response(stream, response));
handle_smf_info(nf_instance, NFProfile->smf_info);
OpenAPI_list_for_each(NFProfile->smf_info_list, node) {
OpenAPI_map_t *SmfInfoMap = node->data;
if (SmfInfoMap && SmfInfoMap->value)
handle_smf_info(nf_instance, SmfInfoMap->value);
}
ogs_sbi_header_free(&header);
return true; return true;
} }
void ogs_nnrf_handle_nf_discover_search_result(
ogs_sbi_object_t *sbi_object,
OpenAPI_nf_type_e target_nf_type,
ogs_sbi_discovery_option_t *discovery_option,
OpenAPI_search_result_t *SearchResult)
{
OpenAPI_lnode_t *node = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(sbi_object);
ogs_assert(SearchResult);
OpenAPI_list_for_each(SearchResult->nf_instances, node) {
OpenAPI_nf_profile_t *NFProfile = NULL;
if (!node->data) continue;
NFProfile = node->data;
if (!NFProfile) {
ogs_error("No NFProfile");
continue;
}
if (!NFProfile->nf_instance_id) {
ogs_error("No NFProfile.NFInstanceId");
continue;
}
if (!NFProfile->nf_type) {
ogs_error("No NFProfile.NFType");
continue;
}
if (!NFProfile->nf_status) {
ogs_error("No NFProfile.NFStatus");
continue;
}
nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id);
if (!nf_instance) {
nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(nf_instance, NFProfile->nf_instance_id);
ogs_sbi_nf_fsm_init(nf_instance);
ogs_info("[%s] (NF-discover) NF registered", nf_instance->id);
} else {
ogs_sbi_nf_fsm_tran(nf_instance, ogs_sbi_nf_state_registered);
ogs_warn("[%s] (NF-discover) NF has already been added",
NFProfile->nf_instance_id);
}
if (NF_INSTANCE_ID_IS_OTHERS(nf_instance->id)) {
ogs_sbi_nnrf_handle_nf_profile(nf_instance, NFProfile, NULL, NULL);
ogs_sbi_client_associate(nf_instance);
/* TIME : Update validity from NRF */
if (SearchResult->is_validity_period &&
SearchResult->validity_period) {
nf_instance->time.validity_duration =
SearchResult->validity_period;
ogs_assert(nf_instance->t_validity);
ogs_timer_start(nf_instance->t_validity,
ogs_time_from_sec(nf_instance->time.validity_duration));
} else
ogs_warn("[%s] NF Instance validity-time should not 0",
nf_instance->id);
ogs_info("[%s] (NF-discover) NF Profile updated", nf_instance->id);
}
}
}

View File

@ -24,10 +24,23 @@
extern "C" { extern "C" {
#endif #endif
bool ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance, void ogs_sbi_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg);
void ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance,
OpenAPI_nf_profile_t *NFProfile, OpenAPI_nf_profile_t *NFProfile,
ogs_sbi_stream_t *stream, ogs_sbi_message_t *message); ogs_sbi_stream_t *stream, ogs_sbi_message_t *message);
void ogs_nnrf_handle_nf_status_subscribe(
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg);
bool ogs_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
void ogs_nnrf_handle_nf_discover_search_result(
ogs_sbi_object_t *sbi_object,
OpenAPI_nf_type_e target_nf_type,
ogs_sbi_discovery_option_t *discovery_option,
OpenAPI_search_result_t *SearchResult);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -20,7 +20,7 @@
#ifndef OGS_SBI_H #ifndef OGS_SBI_H
#define OGS_SBI_H #define OGS_SBI_H
#include "ogs-core.h" #include "ogs-proto.h"
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -86,12 +86,15 @@
#define OGS_SBI_INSIDE #define OGS_SBI_INSIDE
#include "sbi/conv.h" #include "sbi/conv.h"
#include "sbi/timer.h"
#include "sbi/message.h" #include "sbi/message.h"
#include "sbi/server.h" #include "sbi/server.h"
#include "sbi/client.h" #include "sbi/client.h"
#include "sbi/context.h" #include "sbi/context.h"
#include "sbi/nf-sm.h"
#include "sbi/nnrf-build.h" #include "sbi/nnrf-build.h"
#include "sbi/nnrf-handler.h" #include "sbi/nnrf-handler.h"

View File

@ -124,8 +124,7 @@ bool ogs_sbi_discover_and_send(
return false; return false;
} }
bool ogs_nnrf_nfm_send_nf_register( bool ogs_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_request_t *(*build)(void))
{ {
ogs_sbi_request_t *request = NULL; ogs_sbi_request_t *request = NULL;
ogs_sbi_client_t *client = NULL; ogs_sbi_client_t *client = NULL;
@ -133,9 +132,8 @@ bool ogs_nnrf_nfm_send_nf_register(
ogs_assert(nf_instance); ogs_assert(nf_instance);
client = nf_instance->client; client = nf_instance->client;
ogs_assert(client); ogs_assert(client);
ogs_assert(build);
request = (*build)(); request = ogs_nnrf_nfm_build_register();
ogs_expect_or_return_val(request, false); ogs_expect_or_return_val(request, false);
return ogs_sbi_scp_send_request(client, client->cb, request, nf_instance); return ogs_sbi_scp_send_request(client, client->cb, request, nf_instance);

View File

@ -35,8 +35,7 @@ bool ogs_sbi_discover_and_send(
ogs_sbi_discovery_option_t *discovery_option, ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_client_cb_f client_cb, void *data); ogs_sbi_client_cb_f client_cb, void *data);
bool ogs_nnrf_nfm_send_nf_register( bool ogs_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance);
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_request_t *(*build)(void));
bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance); bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance);
bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance); bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance);
bool ogs_nnrf_nfm_send_nf_profile_retrieve(ogs_sbi_nf_instance_t *nf_instance, bool ogs_nnrf_nfm_send_nf_profile_retrieve(ogs_sbi_nf_instance_t *nf_instance,

83
lib/sbi/timer.c Normal file
View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-sbi.h"
#include "ogs-app.h"
static void timer_send_event(int timer_id, void *data)
{
int rv;
ogs_event_t *e = NULL;
ogs_assert(data);
switch (timer_id) {
case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case OGS_TIMER_NF_INSTANCE_VALIDITY:
case OGS_TIMER_SUBSCRIPTION_VALIDITY:
case OGS_TIMER_SBI_CLIENT_WAIT:
e = ogs_event_new(OGS_EVENT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();
break;
}
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed [%d] in %s",
(int)rv, ogs_timer_get_name(e->timer_id));
ogs_event_free(e);
}
}
void ogs_timer_nf_instance_registration_interval(void *data)
{
timer_send_event(OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL, data);
}
void ogs_timer_nf_instance_heartbeat_interval(void *data)
{
timer_send_event(OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL, data);
}
void ogs_timer_nf_instance_no_heartbeat(void *data)
{
timer_send_event(OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT, data);
}
void ogs_timer_nf_instance_validity(void *data)
{
timer_send_event(OGS_TIMER_NF_INSTANCE_VALIDITY, data);
}
void ogs_timer_subscription_validity(void *data)
{
timer_send_event(OGS_TIMER_SUBSCRIPTION_VALIDITY, data);
}
void ogs_timer_sbi_client_wait_expire(void *data)
{
timer_send_event(OGS_TIMER_SBI_CLIENT_WAIT, data);
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -17,25 +17,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef NSSF_NNRF_HANDLER_H #if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
#define NSSF_NNRF_HANDLER_H #error "This header cannot be included directly."
#endif
#include "context.h" #ifndef OGS_SBI_TIMER_H
#define OGS_SBI_TIMER_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void nssf_nnrf_handle_nf_register( void ogs_timer_nf_instance_registration_interval(void *data);
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg); void ogs_timer_nf_instance_heartbeat_interval(void *data);
void nssf_nnrf_handle_nf_status_subscribe( void ogs_timer_nf_instance_no_heartbeat(void *data);
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg); void ogs_timer_nf_instance_validity(void *data);
void ogs_timer_subscription_validity(void *data);
bool nssf_nnrf_handle_nf_status_notify( void ogs_timer_sbi_client_wait_expire(void *data);
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* NSSF_NNRF_HANDLER_H */ #endif /* OGS_SBI_TIMER_H */

View File

@ -36,10 +36,10 @@ libtun = library('ogstun',
version : libogslib_version, version : libogslib_version,
c_args : '-DOGS_TUN_COMPILATION', c_args : '-DOGS_TUN_COMPILATION',
include_directories : [libtun_inc, libinc], include_directories : [libtun_inc, libinc],
dependencies : [libcore_dep, libipfw_dep], dependencies : libipfw_dep,
install : true) install : true)
libtun_dep = declare_dependency( libtun_dep = declare_dependency(
link_with : libtun, link_with : libtun,
include_directories : [libtun_inc, libinc], include_directories : [libtun_inc, libinc],
dependencies : [libcore_dep, libipfw_dep]) dependencies : libipfw_dep)

View File

@ -20,7 +20,7 @@
#ifndef OGS_TUN_H #ifndef OGS_TUN_H
#define OGS_TUN_H #define OGS_TUN_H
#include "ogs-core.h" #include "ogs-proto.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -79,17 +79,17 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(s); ogs_assert(s);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_SBI_SERVER: case OGS_EVENT_SBI_SERVER:
sbi_request = e->sbi.request; sbi_request = e->h.sbi.request;
ogs_assert(sbi_request); ogs_assert(sbi_request);
stream = e->sbi.data; stream = e->h.sbi.data;
ogs_assert(stream); ogs_assert(stream);
rv = ogs_sbi_parse_request(&sbi_message, sbi_request); rv = ogs_sbi_parse_request(&sbi_message, sbi_request);
@ -129,7 +129,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY) CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
SWITCH(sbi_message.h.method) SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST) CASE(OGS_SBI_HTTP_METHOD_POST)
amf_nnrf_handle_nf_status_notify(stream, &sbi_message); ogs_nnrf_handle_nf_status_notify(stream, &sbi_message);
break; break;
DEFAULT DEFAULT
@ -240,10 +240,10 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_message_free(&sbi_message); ogs_sbi_message_free(&sbi_message);
break; break;
case AMF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
ogs_assert(e); ogs_assert(e);
sbi_response = e->sbi.response; sbi_response = e->h.sbi.response;
ogs_assert(sbi_response); ogs_assert(sbi_response);
rv = ogs_sbi_parse_response(&sbi_message, sbi_response); rv = ogs_sbi_parse_response(&sbi_message, sbi_response);
if (rv != OGS_OK) { if (rv != OGS_OK) {
@ -275,23 +275,23 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
SWITCH(sbi_message.h.resource.component[0]) SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES) CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data; nf_instance = e->h.sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &sbi_message; e->h.sbi.message = &sbi_message;
ogs_fsm_dispatch(&nf_instance->sm, e); ogs_fsm_dispatch(&nf_instance->sm, e);
break; break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS) CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data; subscription = e->h.sbi.data;
ogs_assert(subscription); ogs_assert(subscription);
SWITCH(sbi_message.h.method) SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST) CASE(OGS_SBI_HTTP_METHOD_POST)
if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_CREATED || if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK) { sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK) {
amf_nnrf_handle_nf_status_subscribe( ogs_nnrf_handle_nf_status_subscribe(
subscription, &sbi_message); subscription, &sbi_message);
} else { } else {
ogs_error("[%s] HTTP response error [%d]", ogs_error("[%s] HTTP response error [%d]",
@ -325,7 +325,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC) CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
SWITCH(sbi_message.h.resource.component[0]) SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES) CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
SWITCH(sbi_message.h.method) SWITCH(sbi_message.h.method)
@ -354,7 +354,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM) CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM) CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL) CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
sbi_xact = ogs_sbi_xact_cycle(sbi_xact); sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
@ -376,7 +376,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(OGS_FSM_STATE(&amf_ue->sm)); ogs_assert(OGS_FSM_STATE(&amf_ue->sm));
e->amf_ue = amf_ue; e->amf_ue = amf_ue;
e->sbi.message = &sbi_message;; e->h.sbi.message = &sbi_message;;
ogs_fsm_dispatch(&amf_ue->sm, e); ogs_fsm_dispatch(&amf_ue->sm, e);
} else { } else {
@ -385,7 +385,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break; break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION) CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
sbi_xact = ogs_sbi_xact_cycle(sbi_xact); sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
@ -449,7 +449,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
e->amf_ue = amf_ue; e->amf_ue = amf_ue;
e->sess = sess; e->sess = sess;
e->sbi.message = &sbi_message;; e->h.sbi.message = &sbi_message;;
SWITCH(sbi_message.h.resource.component[2]) SWITCH(sbi_message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY) CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
@ -502,7 +502,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break; break;
CASE(OGS_SBI_SERVICE_NAME_NNSSF_NSSELECTION) CASE(OGS_SBI_SERVICE_NAME_NNSSF_NSSELECTION)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
sbi_xact = ogs_sbi_xact_cycle(sbi_xact); sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
@ -535,7 +535,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
e->amf_ue = amf_ue; e->amf_ue = amf_ue;
e->sess = sess; e->sess = sess;
e->sbi.message = &sbi_message;; e->h.sbi.message = &sbi_message;;
amf_nnssf_nsselection_handle_get(sess, &sbi_message); amf_nnssf_nsselection_handle_get(sess, &sbi_message);
break; break;
@ -549,27 +549,27 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_response_free(sbi_response); ogs_sbi_response_free(sbi_response);
break; break;
case AMF_EVT_SBI_TIMER: case OGS_EVENT_SBI_TIMER:
ogs_assert(e); ogs_assert(e);
switch(e->timer_id) { switch(e->h.timer_id) {
case AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL: case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL: case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT: case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case AMF_TIMER_NF_INSTANCE_VALIDITY: case OGS_TIMER_NF_INSTANCE_VALIDITY:
nf_instance = e->sbi.data; nf_instance = e->h.sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
ogs_fsm_dispatch(&nf_instance->sm, e); ogs_fsm_dispatch(&nf_instance->sm, e);
if (OGS_FSM_CHECK(&nf_instance->sm, amf_nf_state_exception)) if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception))
ogs_error("[%s:%s] State machine exception [%d]", ogs_error("[%s:%s] State machine exception [%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id, e->timer_id); nf_instance->id, e->h.timer_id);
break; break;
case AMF_TIMER_SUBSCRIPTION_VALIDITY: case OGS_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data; subscription = e->h.sbi.data;
ogs_assert(subscription); ogs_assert(subscription);
ogs_assert(ogs_sbi_self()->nf_instance); ogs_assert(ogs_sbi_self()->nf_instance);
@ -583,8 +583,8 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_subscription_remove(subscription); ogs_sbi_subscription_remove(subscription);
break; break;
case AMF_TIMER_SBI_CLIENT_WAIT: case OGS_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
sbi_object = sbi_xact->sbi_object; sbi_object = sbi_xact->sbi_object;
@ -647,11 +647,11 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
amf_timer_get_name(e->timer_id), e->timer_id); ogs_timer_get_name(e->h.timer_id), e->h.timer_id);
} }
break; break;
case AMF_EVT_NGAP_LO_ACCEPT: case AMF_EVENT_NGAP_LO_ACCEPT:
sock = e->ngap.sock; sock = e->ngap.sock;
ogs_assert(sock); ogs_assert(sock);
addr = e->ngap.addr; addr = e->ngap.addr;
@ -674,7 +674,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break; break;
case AMF_EVT_NGAP_LO_SCTP_COMM_UP: case AMF_EVENT_NGAP_LO_SCTP_COMM_UP:
sock = e->ngap.sock; sock = e->ngap.sock;
ogs_assert(sock); ogs_assert(sock);
addr = e->ngap.addr; addr = e->ngap.addr;
@ -701,7 +701,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break; break;
case AMF_EVT_NGAP_LO_CONNREFUSED: case AMF_EVENT_NGAP_LO_CONNREFUSED:
sock = e->ngap.sock; sock = e->ngap.sock;
ogs_assert(sock); ogs_assert(sock);
addr = e->ngap.addr; addr = e->ngap.addr;
@ -720,7 +720,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_free(addr); ogs_free(addr);
break; break;
case AMF_EVT_NGAP_MESSAGE: case AMF_EVENT_NGAP_MESSAGE:
sock = e->ngap.sock; sock = e->ngap.sock;
ogs_assert(sock); ogs_assert(sock);
addr = e->ngap.addr; addr = e->ngap.addr;
@ -751,11 +751,11 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_pkbuf_free(pkbuf); ogs_pkbuf_free(pkbuf);
break; break;
case AMF_EVT_NGAP_TIMER: case AMF_EVENT_NGAP_TIMER:
ran_ue = e->ran_ue; ran_ue = e->ran_ue;
ogs_assert(ran_ue); ogs_assert(ran_ue);
switch (e->timer_id) { switch (e->h.timer_id) {
case AMF_TIMER_NG_DELAYED_SEND: case AMF_TIMER_NG_DELAYED_SEND:
gnb = e->gnb; gnb = e->gnb;
ogs_assert(gnb); ogs_assert(gnb);
@ -774,12 +774,12 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break; break;
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
amf_timer_get_name(e->timer_id), e->timer_id); amf_timer_get_name(e->h.timer_id), e->h.timer_id);
break; break;
} }
break; break;
case AMF_EVT_5GMM_MESSAGE: case AMF_EVENT_5GMM_MESSAGE:
ran_ue = e->ran_ue; ran_ue = e->ran_ue;
ogs_assert(ran_ue); ogs_assert(ran_ue);
pkbuf = e->pkbuf; pkbuf = e->pkbuf;
@ -867,7 +867,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_pkbuf_free(pkbuf); ogs_pkbuf_free(pkbuf);
break; break;
case AMF_EVT_5GMM_TIMER: case AMF_EVENT_5GMM_TIMER:
amf_ue = e->amf_ue; amf_ue = e->amf_ue;
ogs_assert(amf_ue); ogs_assert(amf_ue);
ogs_assert(OGS_FSM_STATE(&amf_ue->sm)); ogs_assert(OGS_FSM_STATE(&amf_ue->sm));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -30,16 +30,6 @@ void amf_state_initial(ogs_fsm_t *s, amf_event_t *e);
void amf_state_final(ogs_fsm_t *s, amf_event_t *e); void amf_state_final(ogs_fsm_t *s, amf_event_t *e);
void amf_state_operational(ogs_fsm_t *s, amf_event_t *e); void amf_state_operational(ogs_fsm_t *s, amf_event_t *e);
void amf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance);
void amf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance);
void amf_nf_state_initial(ogs_fsm_t *s, amf_event_t *e);
void amf_nf_state_final(ogs_fsm_t *s, amf_event_t *e);
void amf_nf_state_will_register(ogs_fsm_t *s, amf_event_t *e);
void amf_nf_state_registered(ogs_fsm_t *s, amf_event_t *e);
void amf_nf_state_de_registered(ogs_fsm_t *s, amf_event_t *e);
void amf_nf_state_exception(ogs_fsm_t *s, amf_event_t *e);
void ngap_state_initial(ogs_fsm_t *s, amf_event_t *e); void ngap_state_initial(ogs_fsm_t *s, amf_event_t *e);
void ngap_state_final(ogs_fsm_t *s, amf_event_t *e); void ngap_state_final(ogs_fsm_t *s, amf_event_t *e);
void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e); void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -870,8 +870,7 @@ amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.gnb = gnb; e.gnb = gnb;
ogs_fsm_create(&gnb->sm, ngap_state_initial, ngap_state_final); ogs_fsm_init(&gnb->sm, ngap_state_initial, ngap_state_final, &e);
ogs_fsm_init(&gnb->sm, &e);
ogs_list_add(&self.gnb_list, gnb); ogs_list_add(&self.gnb_list, gnb);
amf_metrics_inst_global_inc(AMF_METR_GLOB_GAUGE_GNB); amf_metrics_inst_global_inc(AMF_METR_GLOB_GAUGE_GNB);
@ -894,7 +893,6 @@ void amf_gnb_remove(amf_gnb_t *gnb)
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.gnb = gnb; e.gnb = gnb;
ogs_fsm_fini(&gnb->sm, &e); ogs_fsm_fini(&gnb->sm, &e);
ogs_fsm_delete(&gnb->sm);
ogs_hash_set(self.gnb_addr_hash, ogs_hash_set(self.gnb_addr_hash,
gnb->sctp.addr, sizeof(ogs_sockaddr_t), NULL); gnb->sctp.addr, sizeof(ogs_sockaddr_t), NULL);
@ -1311,8 +1309,7 @@ void amf_ue_fsm_init(amf_ue_t *amf_ue)
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.amf_ue = amf_ue; e.amf_ue = amf_ue;
ogs_fsm_create(&amf_ue->sm, gmm_state_initial, gmm_state_final); ogs_fsm_init(&amf_ue->sm, gmm_state_initial, gmm_state_final, &e);
ogs_fsm_init(&amf_ue->sm, &e);
} }
void amf_ue_fsm_fini(amf_ue_t *amf_ue) void amf_ue_fsm_fini(amf_ue_t *amf_ue)
@ -1324,7 +1321,6 @@ void amf_ue_fsm_fini(amf_ue_t *amf_ue)
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.amf_ue = amf_ue; e.amf_ue = amf_ue;
ogs_fsm_fini(&amf_ue->sm, &e); ogs_fsm_fini(&amf_ue->sm, &e);
ogs_fsm_delete(&amf_ue->sm);
} }
amf_ue_t *amf_ue_find_by_guti(ogs_nas_5gs_guti_t *guti) amf_ue_t *amf_ue_find_by_guti(ogs_nas_5gs_guti_t *guti)
@ -1792,7 +1788,6 @@ void amf_sbi_select_nf(
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
amf_sess_t *sess = NULL; amf_sess_t *sess = NULL;
ogs_assert(ogs_sbi_self()->nf_state_registered);
ogs_assert(sbi_object); ogs_assert(sbi_object);
ogs_assert(target_nf_type); ogs_assert(target_nf_type);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -197,22 +197,6 @@ struct ran_ue_s {
amf_ue_t *amf_ue; amf_ue_t *amf_ue;
}; };
#define AMF_NF_INSTANCE_CLEAR(_cAUSE, _nFInstance) \
do { \
ogs_assert(_nFInstance); \
if ((_nFInstance)->reference_count == 1) { \
ogs_info("[%s] (%s) NF removed", (_nFInstance)->id, (_cAUSE)); \
amf_nf_fsm_fini((_nFInstance)); \
ogs_sbi_nf_instance_remove(_nFInstance); \
} else { \
/* There is an assocation with other context */ \
ogs_info("[%s:%d] (%s) NF suspended", \
_nFInstance->id, _nFInstance->reference_count, (_cAUSE)); \
OGS_FSM_TRAN(&_nFInstance->sm, amf_nf_state_de_registered); \
ogs_fsm_dispatch(&_nFInstance->sm, NULL); \
} \
} while(0)
struct amf_ue_s { struct amf_ue_s {
ogs_sbi_object_t sbi; ogs_sbi_object_t sbi;
ogs_fsm_t sm; ogs_fsm_t sm;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,90 +20,66 @@
#include "event.h" #include "event.h"
#include "context.h" #include "context.h"
static OGS_POOL(pool, amf_event_t); amf_event_t *amf_event_new(int id)
static ogs_thread_mutex_t amf_event_alloc_mutex;
void amf_event_init(void)
{
ogs_pool_init(&pool, ogs_app()->pool.event);
ogs_thread_mutex_init(&amf_event_alloc_mutex);
}
void amf_event_final(void)
{
ogs_pool_final(&pool);
ogs_thread_mutex_destroy(&amf_event_alloc_mutex);
}
amf_event_t *amf_event_new(amf_event_e id)
{ {
amf_event_t *e = NULL; amf_event_t *e = NULL;
ogs_thread_mutex_lock(&amf_event_alloc_mutex); e = ogs_event_size(id, sizeof(amf_event_t));
ogs_pool_alloc(&pool, &e);
ogs_thread_mutex_unlock(&amf_event_alloc_mutex);
ogs_assert(e); ogs_assert(e);
memset(e, 0, sizeof(*e));
e->id = id; e->h.id = id;
return e; return e;
} }
void amf_event_free(amf_event_t *e)
{
ogs_assert(e);
ogs_thread_mutex_lock(&amf_event_alloc_mutex);
ogs_pool_free(&pool, e);
ogs_thread_mutex_unlock(&amf_event_alloc_mutex);
}
const char *amf_event_get_name(amf_event_t *e) const char *amf_event_get_name(amf_event_t *e)
{ {
if (e == NULL) if (e == NULL) {
return OGS_FSM_NAME_INIT_SIG; return OGS_FSM_NAME_INIT_SIG;
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case AMF_EVT_SBI_SERVER:
return "AMF_EVT_SBI_SERVER";
case AMF_EVT_SBI_CLIENT:
return "AMF_EVT_SBI_CLIENT";
case AMF_EVT_SBI_TIMER:
return "AMF_EVT_SBI_TIMER";
case AMF_EVT_NGAP_MESSAGE:
return "AMF_EVT_NGAP_MESSAGE";
case AMF_EVT_NGAP_TIMER:
return "AMF_EVT_NGAP_TIMER";
case AMF_EVT_NGAP_LO_ACCEPT:
return "AMF_EVT_NGAP_LO_ACCEPT";
case AMF_EVT_NGAP_LO_SCTP_COMM_UP:
return "AMF_EVT_NGAP_LO_SCTP_COMM_UP";
case AMF_EVT_NGAP_LO_CONNREFUSED:
return "AMF_EVT_NGAP_LO_CONNREFUSED";
case AMF_EVT_5GMM_MESSAGE:
return "AMF_EVT_5GMM_MESSAGE";
case AMF_EVT_5GMM_TIMER:
return "AMF_EVT_5GMM_TIMER";
case AMF_EVT_5GSM_MESSAGE:
return "AMF_EVT_5GSM_MESSAGE";
case AMF_EVT_5GSM_TIMER:
return "AMF_EVT_5GSM_TIMER";
default:
break;
} }
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case OGS_EVENT_SBI_SERVER:
return OGS_EVENT_NAME_SBI_SERVER;
case OGS_EVENT_SBI_CLIENT:
return OGS_EVENT_NAME_SBI_CLIENT;
case OGS_EVENT_SBI_TIMER:
return OGS_EVENT_NAME_SBI_TIMER;
case AMF_EVENT_NGAP_MESSAGE:
return "AMF_EVENT_NGAP_MESSAGE";
case AMF_EVENT_NGAP_TIMER:
return "AMF_EVENT_NGAP_TIMER";
case AMF_EVENT_NGAP_LO_ACCEPT:
return "AMF_EVENT_NGAP_LO_ACCEPT";
case AMF_EVENT_NGAP_LO_SCTP_COMM_UP:
return "AMF_EVENT_NGAP_LO_SCTP_COMM_UP";
case AMF_EVENT_NGAP_LO_CONNREFUSED:
return "AMF_EVENT_NGAP_LO_CONNREFUSED";
case AMF_EVENT_5GMM_MESSAGE:
return "AMF_EVENT_5GMM_MESSAGE";
case AMF_EVENT_5GMM_TIMER:
return "AMF_EVENT_5GMM_TIMER";
case AMF_EVENT_5GSM_MESSAGE:
return "AMF_EVENT_5GSM_MESSAGE";
case AMF_EVENT_5GSM_TIMER:
return "AMF_EVENT_5GSM_TIMER";
default:
break;
}
ogs_error("Unknown Event[%d]", e->h.id);
return "UNKNOWN_EVENT"; return "UNKNOWN_EVENT";
} }
void amf_sctp_event_push(amf_event_e id, void amf_sctp_event_push(int id,
void *sock, ogs_sockaddr_t *addr, ogs_pkbuf_t *pkbuf, void *sock, ogs_sockaddr_t *addr, ogs_pkbuf_t *pkbuf,
uint16_t max_num_of_istreams, uint16_t max_num_of_ostreams) uint16_t max_num_of_istreams, uint16_t max_num_of_ostreams)
{ {
@ -130,7 +106,7 @@ void amf_sctp_event_push(amf_event_e id,
ogs_free(e->ngap.addr); ogs_free(e->ngap.addr);
if (e->pkbuf) if (e->pkbuf)
ogs_pkbuf_free(e->pkbuf); ogs_pkbuf_free(e->pkbuf);
amf_event_free(e); ogs_event_free(e);
} }
#if HAVE_USRSCTP #if HAVE_USRSCTP
else { else {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,18 +20,12 @@
#ifndef AMF_EVENT_H #ifndef AMF_EVENT_H
#define AMF_EVENT_H #define AMF_EVENT_H
#include "ogs-core.h" #include "ogs-proto.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
typedef struct ogs_sbi_response_s ogs_sbi_response_t;
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
typedef struct ogs_sbi_nf_instance_s ogs_sbi_nf_instance_t;
typedef struct ogs_sbi_subscription_s ogs_sbi_subscription_t;
typedef struct ogs_nas_5gs_message_s ogs_nas_5gs_message_t; typedef struct ogs_nas_5gs_message_s ogs_nas_5gs_message_t;
typedef struct NGAP_NGAP_PDU ogs_ngap_message_t; typedef struct NGAP_NGAP_PDU ogs_ngap_message_t;
typedef long NGAP_ProcedureCode_t; typedef long NGAP_ProcedureCode_t;
@ -43,39 +37,27 @@ typedef struct amf_sess_s amf_sess_t;
typedef struct amf_bearer_s amf_bearer_t; typedef struct amf_bearer_s amf_bearer_t;
typedef enum { typedef enum {
AMF_EVT_BASE = OGS_FSM_USER_SIG, AMF_EVENT_BASE = OGS_MAX_NUM_OF_PROTO_EVENT,
AMF_EVT_SBI_SERVER, AMF_EVENT_NGAP_MESSAGE,
AMF_EVT_SBI_CLIENT, AMF_EVENT_NGAP_TIMER,
AMF_EVT_SBI_TIMER, AMF_EVENT_NGAP_LO_ACCEPT,
AMF_EVENT_NGAP_LO_SCTP_COMM_UP,
AMF_EVENT_NGAP_LO_CONNREFUSED,
AMF_EVT_NGAP_MESSAGE, AMF_EVENT_5GMM_MESSAGE,
AMF_EVT_NGAP_TIMER, AMF_EVENT_5GMM_TIMER,
AMF_EVT_NGAP_LO_ACCEPT, AMF_EVENT_5GSM_MESSAGE,
AMF_EVT_NGAP_LO_SCTP_COMM_UP, AMF_EVENT_5GSM_TIMER,
AMF_EVT_NGAP_LO_CONNREFUSED,
AMF_EVT_5GMM_MESSAGE, MAX_NUM_OF_AMF_EVENT,
AMF_EVT_5GMM_TIMER,
AMF_EVT_5GSM_MESSAGE,
AMF_EVT_5GSM_TIMER,
AMF_EVT_TOP,
} amf_event_e; } amf_event_e;
typedef struct amf_event_s { typedef struct amf_event_s {
int id; ogs_event_t h;
ogs_pkbuf_t *pkbuf; ogs_pkbuf_t *pkbuf;
int timer_id;
struct {
ogs_sbi_request_t *request;
ogs_sbi_response_t *response;
void *data;
ogs_sbi_message_t *message;
} sbi;
struct { struct {
ogs_sock_t *sock; ogs_sock_t *sock;
@ -101,15 +83,11 @@ typedef struct amf_event_s {
ogs_timer_t *timer; ogs_timer_t *timer;
} amf_event_t; } amf_event_t;
void amf_event_init(void); amf_event_t *amf_event_new(int id);
void amf_event_final(void);
amf_event_t *amf_event_new(amf_event_e id);
void amf_event_free(amf_event_t *e);
const char *amf_event_get_name(amf_event_t *e); const char *amf_event_get_name(amf_event_t *e);
void amf_sctp_event_push(amf_event_e id, void amf_sctp_event_push(int id,
void *sock, ogs_sockaddr_t *addr, ogs_pkbuf_t *pkbuf, void *sock, ogs_sockaddr_t *addr, ogs_pkbuf_t *pkbuf,
uint16_t max_num_of_istreams, uint16_t max_num_of_ostreams); uint16_t max_num_of_istreams, uint16_t max_num_of_ostreams);

View File

@ -62,7 +62,7 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
amf_ue = e->amf_ue; amf_ue = e->amf_ue;
ogs_assert(amf_ue); ogs_assert(amf_ue);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
AMF_UE_CLEAR_PAGING_INFO(amf_ue); AMF_UE_CLEAR_PAGING_INFO(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request); AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
@ -113,13 +113,13 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(amf_ue); ogs_assert(amf_ue);
} }
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_5GMM_MESSAGE: case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message; nas_message = e->nas.message;
ogs_assert(nas_message); ogs_assert(nas_message);
@ -367,8 +367,8 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
} }
break; break;
case AMF_EVT_5GMM_TIMER: case AMF_EVENT_5GMM_TIMER:
switch (e->timer_id) { switch (e->h.timer_id) {
case AMF_TIMER_T3513: case AMF_TIMER_T3513:
if (amf_ue->t3513.retry_count >= if (amf_ue->t3513.retry_count >=
amf_timer_cfg(AMF_TIMER_T3513)->max_count) { amf_timer_cfg(AMF_TIMER_T3513)->max_count) {
@ -457,14 +457,14 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
amf_timer_get_name(e->timer_id), e->timer_id); amf_timer_get_name(e->h.timer_id), e->h.timer_id);
} }
break; break;
case AMF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
sbi_response = e->sbi.response; sbi_response = e->h.sbi.response;
ogs_assert(sbi_response); ogs_assert(sbi_response);
sbi_message = e->sbi.message; sbi_message = e->h.sbi.message;
ogs_assert(sbi_message); ogs_assert(sbi_message);
SWITCH(sbi_message->h.service.name) SWITCH(sbi_message->h.service.name)
@ -536,12 +536,12 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(amf_ue); ogs_assert(amf_ue);
} }
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_5GMM_MESSAGE: case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message; nas_message = e->nas.message;
ogs_assert(nas_message); ogs_assert(nas_message);
@ -651,8 +651,8 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
break; break;
} }
break; break;
case AMF_EVT_5GMM_TIMER: case AMF_EVENT_5GMM_TIMER:
switch (e->timer_id) { switch (e->h.timer_id) {
case AMF_TIMER_T3560: case AMF_TIMER_T3560:
if (amf_ue->t3560.retry_count >= if (amf_ue->t3560.retry_count >=
amf_timer_cfg(AMF_TIMER_T3560)->max_count) { amf_timer_cfg(AMF_TIMER_T3560)->max_count) {
@ -673,14 +673,14 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
break; break;
default: default:
ogs_error("[%s] Unknown timer[%s:%d]", amf_ue->suci, ogs_error("[%s] Unknown timer[%s:%d]", amf_ue->suci,
amf_timer_get_name(e->timer_id), e->timer_id); amf_timer_get_name(e->h.timer_id), e->h.timer_id);
break; break;
} }
break; break;
case AMF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
sbi_response = e->sbi.response; sbi_response = e->h.sbi.response;
ogs_assert(sbi_response); ogs_assert(sbi_response);
sbi_message = e->sbi.message; sbi_message = e->h.sbi.message;
ogs_assert(sbi_message); ogs_assert(sbi_message);
SWITCH(sbi_message->h.service.name) SWITCH(sbi_message->h.service.name)
@ -772,7 +772,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
amf_ue = e->amf_ue; amf_ue = e->amf_ue;
ogs_assert(amf_ue); ogs_assert(amf_ue);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
CLEAR_AMF_UE_TIMER(amf_ue->t3560); CLEAR_AMF_UE_TIMER(amf_ue->t3560);
ogs_assert(OGS_OK == ogs_assert(OGS_OK ==
@ -780,7 +780,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_5GMM_MESSAGE: case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message; nas_message = e->nas.message;
ogs_assert(nas_message); ogs_assert(nas_message);
@ -901,8 +901,8 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
break; break;
} }
break; break;
case AMF_EVT_5GMM_TIMER: case AMF_EVENT_5GMM_TIMER:
switch (e->timer_id) { switch (e->h.timer_id) {
case AMF_TIMER_T3560: case AMF_TIMER_T3560:
if (amf_ue->t3560.retry_count >= if (amf_ue->t3560.retry_count >=
amf_timer_cfg(AMF_TIMER_T3560)->max_count) { amf_timer_cfg(AMF_TIMER_T3560)->max_count) {
@ -923,7 +923,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
break; break;
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
amf_timer_get_name(e->timer_id), e->timer_id); amf_timer_get_name(e->h.timer_id), e->h.timer_id);
break; break;
} }
break; break;
@ -962,16 +962,16 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(amf_ue); ogs_assert(amf_ue);
} }
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
sbi_response = e->sbi.response; sbi_response = e->h.sbi.response;
ogs_assert(sbi_response); ogs_assert(sbi_response);
sbi_message = e->sbi.message; sbi_message = e->h.sbi.message;
ogs_assert(sbi_message); ogs_assert(sbi_message);
SWITCH(sbi_message->h.service.name) SWITCH(sbi_message->h.service.name)
@ -1105,7 +1105,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
END END
break; break;
case AMF_EVT_5GMM_MESSAGE: case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message; nas_message = e->nas.message;
ogs_assert(nas_message); ogs_assert(nas_message);
@ -1228,8 +1228,8 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
break; break;
} }
break; break;
case AMF_EVT_5GMM_TIMER: case AMF_EVENT_5GMM_TIMER:
switch (e->timer_id) { switch (e->h.timer_id) {
case AMF_TIMER_T3550: case AMF_TIMER_T3550:
if (amf_ue->t3550.retry_count >= if (amf_ue->t3550.retry_count >=
amf_timer_cfg(AMF_TIMER_T3550)->max_count) { amf_timer_cfg(AMF_TIMER_T3550)->max_count) {
@ -1248,7 +1248,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
break; break;
default: default:
ogs_error("[%s] Unknown timer[%s:%d]", amf_ue->suci, ogs_error("[%s] Unknown timer[%s:%d]", amf_ue->suci,
amf_timer_get_name(e->timer_id), e->timer_id); amf_timer_get_name(e->h.timer_id), e->h.timer_id);
break; break;
} }
break; break;
@ -1281,7 +1281,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(amf_ue); ogs_assert(amf_ue);
} }
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
AMF_UE_CLEAR_PAGING_INFO(amf_ue); AMF_UE_CLEAR_PAGING_INFO(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request); AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
@ -1300,7 +1300,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_5GMM_MESSAGE: case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message; nas_message = e->nas.message;
ogs_assert(nas_message); ogs_assert(nas_message);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -33,7 +33,6 @@ int amf_initialize()
ogs_sbi_context_init(); ogs_sbi_context_init();
amf_context_init(); amf_context_init();
amf_event_init();
rv = ogs_sbi_context_parse_config("amf", "nrf", "scp"); rv = ogs_sbi_context_parse_config("amf", "nrf", "scp");
if (rv != OGS_OK) return rv; if (rv != OGS_OK) return rv;
@ -76,7 +75,7 @@ static void event_termination(void)
/* Sending NF Instance De-registeration to NRF */ /* Sending NF Instance De-registeration to NRF */
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
amf_nf_fsm_fini(nf_instance); ogs_sbi_nf_fsm_fini(nf_instance);
/* Starting holding timer */ /* Starting holding timer */
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL); t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
@ -105,8 +104,6 @@ void amf_terminate(void)
amf_context_final(); amf_context_final();
ogs_sbi_context_final(); ogs_sbi_context_final();
ogs_metrics_context_final(); ogs_metrics_context_final();
amf_event_final(); /* Destroy event */
} }
static void amf_main(void *data) static void amf_main(void *data)
@ -114,8 +111,7 @@ static void amf_main(void *data)
ogs_fsm_t amf_sm; ogs_fsm_t amf_sm;
int rv; int rv;
ogs_fsm_create(&amf_sm, amf_state_initial, amf_state_final); ogs_fsm_init(&amf_sm, amf_state_initial, amf_state_final, 0);
ogs_fsm_init(&amf_sm, 0);
for ( ;; ) { for ( ;; ) {
ogs_pollset_poll(ogs_app()->pollset, ogs_pollset_poll(ogs_app()->pollset,
@ -148,11 +144,10 @@ static void amf_main(void *data)
ogs_assert(e); ogs_assert(e);
ogs_fsm_dispatch(&amf_sm, e); ogs_fsm_dispatch(&amf_sm, e);
amf_event_free(e); ogs_event_free(e);
} }
} }
done: done:
ogs_fsm_fini(&amf_sm, 0); ogs_fsm_fini(&amf_sm, 0);
ogs_fsm_delete(&amf_sm);
} }

View File

@ -1,4 +1,4 @@
# Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> # Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
# This file is part of Open5GS. # This file is part of Open5GS.
@ -43,8 +43,6 @@ libamf_sources = files('''
namf-handler.c namf-handler.c
sbi-path.c sbi-path.c
nf-sm.c
ngap-sctp.c ngap-sctp.c
ngap-build.c ngap-build.c
ngap-handler.c ngap-handler.c

View File

@ -1,467 +0,0 @@
/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "context.h"
#include "sbi-path.h"
#include "nnrf-handler.h"
void amf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance)
{
amf_event_t e;
ogs_assert(nf_instance);
memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance;
ogs_fsm_create(&nf_instance->sm,
amf_nf_state_initial, amf_nf_state_final);
ogs_fsm_init(&nf_instance->sm, &e);
}
void amf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance)
{
amf_event_t e;
ogs_assert(nf_instance);
memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance;
ogs_fsm_fini(&nf_instance->sm, &e);
ogs_fsm_delete(&nf_instance->sm);
}
void amf_nf_state_initial(ogs_fsm_t *s, amf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
amf_timer_nf_instance_registration_interval, nf_instance);
ogs_assert(nf_instance->t_registration_interval);
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
amf_timer_nf_instance_heartbeat_interval, nf_instance);
ogs_assert(nf_instance->t_heartbeat_interval);
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
amf_timer_nf_instance_no_heartbeat, nf_instance);
ogs_assert(nf_instance->t_no_heartbeat);
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
amf_timer_nf_instance_validity, nf_instance);
ogs_assert(nf_instance->t_validity);
if (NF_INSTANCE_IS_NRF(nf_instance)) {
OGS_FSM_TRAN(s, &amf_nf_state_will_register);
} else {
ogs_assert(nf_instance->id);
OGS_FSM_TRAN(s, &amf_nf_state_registered);
}
}
void amf_nf_state_final(ogs_fsm_t *s, amf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_timer_delete(nf_instance->t_registration_interval);
ogs_timer_delete(nf_instance->t_heartbeat_interval);
ogs_timer_delete(nf_instance->t_no_heartbeat);
ogs_timer_delete(nf_instance->t_validity);
}
void amf_nf_state_will_register(ogs_fsm_t *s, amf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL;
ogs_sbi_message_t *message = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
ogs_assert(NF_INSTANCE_IS_NRF(nf_instance));
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
nf_instance, amf_nnrf_nfm_build_register));
break;
case OGS_FSM_EXIT_SIG:
ogs_timer_stop(nf_instance->t_registration_interval);
break;
case AMF_EVT_SBI_CLIENT:
message = e->sbi.message;
ogs_assert(message);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
if (message->res_status == OGS_SBI_HTTP_STATUS_OK ||
message->res_status == OGS_SBI_HTTP_STATUS_CREATED) {
amf_nnrf_handle_nf_register(nf_instance, message);
OGS_FSM_TRAN(s, &amf_nf_state_registered);
} else {
ogs_error("[%s] HTTP Response Status Code [%d]",
ogs_sbi_self()->nf_instance->id,
message->res_status);
OGS_FSM_TRAN(s, &amf_nf_state_exception);
}
break;
DEFAULT
ogs_error("[%s] Invalid resource name [%s]",
ogs_sbi_self()->nf_instance->id,
message->h.resource.component[0]);
END
break;
DEFAULT
ogs_error("[%s] Invalid API name [%s]",
ogs_sbi_self()->nf_instance->id, message->h.service.name);
END
break;
case AMF_EVT_SBI_TIMER:
switch(e->timer_id) {
case AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client;
ogs_assert(client);
addr = client->node.addr;
ogs_assert(addr);
ogs_warn("[%s] Retry to registration with NRF",
ogs_sbi_self()->nf_instance->id);
ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
nf_instance, amf_nnrf_nfm_build_register));
break;
default:
ogs_error("[%s] Unknown timer[%s:%d]",
ogs_sbi_self()->nf_instance->id,
amf_timer_get_name(e->timer_id), e->timer_id);
}
break;
default:
ogs_error("Unknown event %s", amf_event_get_name(e));
break;
}
}
void amf_nf_state_registered(ogs_fsm_t *s, amf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL;
ogs_sbi_message_t *message = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF registered [Heartbeat:%ds]",
ogs_sbi_self()->nf_instance->id,
nf_instance->time.heartbeat_interval);
client = nf_instance->client;
ogs_assert(client);
if (nf_instance->time.heartbeat_interval) {
ogs_timer_start(nf_instance->t_heartbeat_interval,
ogs_time_from_sec(nf_instance->time.heartbeat_interval));
ogs_timer_start(nf_instance->t_no_heartbeat,
ogs_time_from_sec(
nf_instance->time.heartbeat_interval +
ogs_app()->time.nf_instance.no_heartbeat_margin));
}
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
OpenAPI_nf_type_AUSF));
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
OpenAPI_nf_type_UDM));
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
OpenAPI_nf_type_PCF));
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
OpenAPI_nf_type_SMF));
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
OpenAPI_nf_type_NSSF));
}
break;
case OGS_FSM_EXIT_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
if (nf_instance->time.heartbeat_interval) {
ogs_timer_stop(nf_instance->t_heartbeat_interval);
ogs_timer_stop(nf_instance->t_no_heartbeat);
}
if (!OGS_FSM_CHECK(&nf_instance->sm, amf_nf_state_exception)) {
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_de_register(nf_instance));
}
}
break;
case AMF_EVT_SBI_CLIENT:
message = e->sbi.message;
ogs_assert(message);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
if (message->res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT ||
message->res_status == OGS_SBI_HTTP_STATUS_OK) {
if (nf_instance->time.heartbeat_interval)
ogs_timer_start(nf_instance->t_no_heartbeat,
ogs_time_from_sec(
nf_instance->time.heartbeat_interval +
ogs_app()->time.nf_instance.
no_heartbeat_margin));
} else {
ogs_warn("[%s] HTTP response error [%d]",
ogs_sbi_self()->nf_instance->id,
message->res_status);
OGS_FSM_TRAN(s, &amf_nf_state_exception);
}
break;
DEFAULT
ogs_error("[%s] Invalid resource name [%s]",
ogs_sbi_self()->nf_instance->id,
message->h.resource.component[0]);
END
break;
DEFAULT
ogs_error("[%s] Invalid API name [%s]",
ogs_sbi_self()->nf_instance->id, message->h.service.name);
END
break;
case AMF_EVT_SBI_TIMER:
switch(e->timer_id) {
case AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
if (nf_instance->time.heartbeat_interval)
ogs_timer_start(nf_instance->t_heartbeat_interval,
ogs_time_from_sec(nf_instance->time.heartbeat_interval));
ogs_assert(true == ogs_nnrf_nfm_send_nf_update(nf_instance));
break;
case AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
ogs_error("[%s] No heartbeat", ogs_sbi_self()->nf_instance->id);
OGS_FSM_TRAN(s, &amf_nf_state_will_register);
break;
case AMF_TIMER_NF_INSTANCE_VALIDITY:
ogs_assert(!NF_INSTANCE_IS_NRF(nf_instance));
ogs_assert(nf_instance->id);
ogs_info("[%s] NF expired", nf_instance->id);
OGS_FSM_TRAN(s, &amf_nf_state_de_registered);
break;
default:
ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
amf_timer_get_name(e->timer_id), e->timer_id);
}
break;
default:
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
amf_event_get_name(e));
break;
}
}
void amf_nf_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
}
break;
case OGS_FSM_EXIT_SIG:
break;
default:
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
amf_event_get_name(e));
break;
}
}
void amf_nf_state_exception(ogs_fsm_t *s, amf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL;
ogs_sbi_message_t *message = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
amf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.
nf_register_interval_in_exception);
}
break;
case OGS_FSM_EXIT_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_timer_stop(nf_instance->t_registration_interval);
}
break;
case AMF_EVT_SBI_TIMER:
switch(e->timer_id) {
case AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client;
ogs_assert(client);
addr = client->node.addr;
ogs_assert(addr);
ogs_warn("[%s] Retry to registration with NRF",
ogs_sbi_self()->nf_instance->id);
OGS_FSM_TRAN(s, &amf_nf_state_will_register);
break;
default:
ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
amf_timer_get_name(e->timer_id), e->timer_id);
}
break;
case AMF_EVT_SBI_CLIENT:
message = e->sbi.message;
ogs_assert(message);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
message->h.resource.component[0]);
END
break;
DEFAULT
ogs_error("Invalid API name [%s]", message->h.service.name);
END
break;
default:
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
amf_event_get_name(e));
break;
}
}

View File

@ -104,7 +104,7 @@ int ngap_delayed_send_to_ran_ue(
if (duration) { if (duration) {
amf_event_t *e = NULL; amf_event_t *e = NULL;
e = amf_event_new(AMF_EVT_NGAP_TIMER); e = amf_event_new(AMF_EVENT_NGAP_TIMER);
ogs_assert(e); ogs_assert(e);
e->timer = ogs_timer_add( e->timer = ogs_timer_add(
ogs_app()->timer_mgr, amf_timer_ng_delayed_send, e); ogs_app()->timer_mgr, amf_timer_ng_delayed_send, e);
@ -132,7 +132,7 @@ int ngap_send_to_5gsm(amf_ue_t *amf_ue, ogs_pkbuf_t *esmbuf)
ogs_assert(amf_ue); ogs_assert(amf_ue);
ogs_assert(esmbuf); ogs_assert(esmbuf);
e = amf_event_new(AMF_EVT_5GSM_MESSAGE); e = amf_event_new(AMF_EVENT_5GSM_MESSAGE);
ogs_assert(e); ogs_assert(e);
e->amf_ue = amf_ue; e->amf_ue = amf_ue;
e->pkbuf = esmbuf; e->pkbuf = esmbuf;
@ -140,7 +140,7 @@ int ngap_send_to_5gsm(amf_ue_t *amf_ue, ogs_pkbuf_t *esmbuf)
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf); ogs_pkbuf_free(e->pkbuf);
amf_event_free(e); ogs_event_free(e);
} }
return rv; return rv;
@ -212,7 +212,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
if (h->extended_protocol_discriminator == if (h->extended_protocol_discriminator ==
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) { OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
int rv; int rv;
e = amf_event_new(AMF_EVT_5GMM_MESSAGE); e = amf_event_new(AMF_EVENT_5GMM_MESSAGE);
if (!e) { if (!e) {
ogs_error("ngap_send_to_nas() failed"); ogs_error("ngap_send_to_nas() failed");
ogs_pkbuf_free(nasbuf); ogs_pkbuf_free(nasbuf);
@ -226,7 +226,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ngap_send_to_nas() failed:%d", (int)rv); ogs_error("ngap_send_to_nas() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf); ogs_pkbuf_free(e->pkbuf);
amf_event_free(e); ogs_event_free(e);
} }
return rv; return rv;
} else if (h->extended_protocol_discriminator == } else if (h->extended_protocol_discriminator ==

View File

@ -113,7 +113,7 @@ void ngap_accept_handler(ogs_sock_t *sock)
ogs_info("gNB-N2 accepted[%s]:%d in ng-path module", ogs_info("gNB-N2 accepted[%s]:%d in ng-path module",
OGS_ADDR(addr, buf), OGS_PORT(addr)); OGS_ADDR(addr, buf), OGS_PORT(addr));
ngap_event_push(AMF_EVT_NGAP_LO_ACCEPT, ngap_event_push(AMF_EVENT_NGAP_LO_ACCEPT,
new, addr, NULL, 0, 0); new, addr, NULL, 0, 0);
} else { } else {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "accept() failed"); ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "accept() failed");
@ -164,7 +164,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr); ogs_assert(addr);
memcpy(addr, &from, sizeof(ogs_sockaddr_t)); memcpy(addr, &from, sizeof(ogs_sockaddr_t));
ngap_event_push(AMF_EVT_NGAP_LO_SCTP_COMM_UP, ngap_event_push(AMF_EVENT_NGAP_LO_SCTP_COMM_UP,
sock, addr, NULL, sock, addr, NULL,
not->sn_assoc_change.sac_inbound_streams, not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams); not->sn_assoc_change.sac_outbound_streams);
@ -180,7 +180,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr); ogs_assert(addr);
memcpy(addr, &from, sizeof(ogs_sockaddr_t)); memcpy(addr, &from, sizeof(ogs_sockaddr_t));
ngap_event_push(AMF_EVT_NGAP_LO_CONNREFUSED, ngap_event_push(AMF_EVENT_NGAP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0); sock, addr, NULL, 0, 0);
} }
break; break;
@ -193,7 +193,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr); ogs_assert(addr);
memcpy(addr, &from, sizeof(ogs_sockaddr_t)); memcpy(addr, &from, sizeof(ogs_sockaddr_t));
ngap_event_push(AMF_EVT_NGAP_LO_CONNREFUSED, ngap_event_push(AMF_EVENT_NGAP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0); sock, addr, NULL, 0, 0);
break; break;
@ -235,7 +235,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr); ogs_assert(addr);
memcpy(addr, &from, sizeof(ogs_sockaddr_t)); memcpy(addr, &from, sizeof(ogs_sockaddr_t));
ngap_event_push(AMF_EVT_NGAP_MESSAGE, sock, addr, pkbuf, 0, 0); ngap_event_push(AMF_EVENT_NGAP_MESSAGE, sock, addr, pkbuf, 0, 0);
return; return;
} else { } else {
if (ogs_socket_errno != OGS_EAGAIN) { if (ogs_socket_errno != OGS_EAGAIN) {

View File

@ -55,12 +55,12 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
gnb = e->gnb; gnb = e->gnb;
ogs_assert(gnb); ogs_assert(gnb);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AMF_EVT_NGAP_MESSAGE: case AMF_EVENT_NGAP_MESSAGE:
pdu = e->ngap.message; pdu = e->ngap.message;
ogs_assert(pdu); ogs_assert(pdu);
@ -190,8 +190,8 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
} }
break; break;
case AMF_EVT_NGAP_TIMER: case AMF_EVENT_NGAP_TIMER:
switch (e->timer_id) { switch (e->h.timer_id) {
case AMF_TIMER_NG_DELAYED_SEND: case AMF_TIMER_NG_DELAYED_SEND:
ogs_assert(e->ran_ue); ogs_assert(e->ran_ue);
ogs_assert(e->pkbuf); ogs_assert(e->pkbuf);
@ -201,7 +201,7 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
break; break;
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
amf_timer_get_name(e->timer_id), e->timer_id); amf_timer_get_name(e->h.timer_id), e->h.timer_id);
break; break;
} }
break; break;
@ -218,7 +218,7 @@ void ngap_state_exception(ogs_fsm_t *s, amf_event_t *e)
amf_sm_debug(e); amf_sm_debug(e);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -19,41 +19,6 @@
#include "nnrf-build.h" #include "nnrf-build.h"
ogs_sbi_request_t *amf_nnrf_nfm_build_register(void)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
OpenAPI_nf_profile_t *NFProfile = NULL;
nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance);
ogs_assert(nf_instance->id);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
message.h.resource.component[1] = nf_instance->id;
message.http.content_encoding = (char*)ogs_sbi_self()->content_encoding;
NFProfile = ogs_nnrf_nfm_build_nf_profile();
ogs_expect_or_return_val(NFProfile, NULL);
message.NFProfile = NFProfile;
request = ogs_sbi_build_request(&message);
ogs_sbi_nnrf_free_nf_profile(NFProfile);
return request;
}
ogs_sbi_request_t *amf_nnrf_disc_build_discover( ogs_sbi_request_t *amf_nnrf_disc_build_discover(
char *nrf_id, char *nrf_id,
OpenAPI_nf_type_e target_nf_type, OpenAPI_nf_type_e requester_nf_type) OpenAPI_nf_type_e target_nf_type, OpenAPI_nf_type_e requester_nf_type)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -26,8 +26,6 @@
extern "C" { extern "C" {
#endif #endif
ogs_sbi_request_t *amf_nnrf_nfm_build_register(void);
ogs_sbi_request_t *amf_nnrf_disc_build_discover( ogs_sbi_request_t *amf_nnrf_disc_build_discover(
char *nrf_id, char *nrf_id,
OpenAPI_nf_type_e target_nf_type, OpenAPI_nf_type_e requester_nf_type); OpenAPI_nf_type_e target_nf_type, OpenAPI_nf_type_e requester_nf_type);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -22,233 +22,6 @@
#include "ngap-path.h" #include "ngap-path.h"
#include "nnrf-handler.h" #include "nnrf-handler.h"
void amf_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg)
{
OpenAPI_nf_profile_t *NFProfile = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(recvmsg);
ogs_assert(nf_instance);
client = nf_instance->client;
ogs_assert(client);
NFProfile = recvmsg->NFProfile;
if (!NFProfile) {
ogs_error("No NFProfile");
return;
}
/* TIME : Update heartbeat from NRF */
if (NFProfile->is_heart_beat_timer == true)
nf_instance->time.heartbeat_interval = NFProfile->heart_beat_timer;
}
void amf_nnrf_handle_nf_status_subscribe(
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg)
{
OpenAPI_subscription_data_t *SubscriptionData = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(recvmsg);
ogs_assert(subscription);
client = subscription->client;
ogs_assert(client);
SubscriptionData = recvmsg->SubscriptionData;
if (!SubscriptionData) {
ogs_error("No SubscriptionData");
return;
}
if (!SubscriptionData->subscription_id) {
ogs_error("No SubscriptionId");
return;
}
ogs_sbi_subscription_set_id(
subscription, SubscriptionData->subscription_id);
if (SubscriptionData->validity_time) {
#define VALIDITY_MINIMUM (10LL * OGS_USEC_PER_SEC) /* 10 seconds */
ogs_time_t time, duration;
if (ogs_sbi_time_from_string(
&time, SubscriptionData->validity_time) == true) {
duration = time - ogs_time_now();
if (duration < VALIDITY_MINIMUM) {
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %lld seconds", subscription->id,
(long long)ogs_time_sec(VALIDITY_MINIMUM));
}
subscription->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
amf_timer_subscription_validity, subscription);
ogs_assert(subscription->t_validity);
ogs_timer_start(subscription->t_validity, duration);
} else {
ogs_error("Cannot parse validitiyTime [%s]",
SubscriptionData->validity_time);
}
}
}
bool amf_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
int rv;
bool handled;
ogs_sbi_response_t *response = NULL;
OpenAPI_notification_data_t *NotificationData = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_message_t message;
ogs_sbi_header_t header;
ogs_assert(stream);
ogs_assert(recvmsg);
NotificationData = recvmsg->NotificationData;
if (!NotificationData) {
ogs_error("No NotificationData");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NotificationData", NULL));
return false;
}
if (!NotificationData->nf_instance_uri) {
ogs_error("No nfInstanceUri");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No nfInstanceUri", NULL));
return false;
}
memset(&header, 0, sizeof(header));
header.uri = NotificationData->nf_instance_uri;
rv = ogs_sbi_parse_header(&message, &header);
if (rv != OGS_OK) {
ogs_error("Cannot parse nfInstanceUri [%s]", header.uri);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot parse nfInstanceUri", header.uri));
return false;
}
if (!message.h.resource.component[1]) {
ogs_error("No nfInstanceId [%s]", header.uri);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot parse nfInstanceUri", header.uri));
ogs_sbi_header_free(&header);
return false;
}
if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) {
ogs_warn("[%s] The notification is not allowed",
message.h.resource.component[1]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN,
recvmsg, "The notification is not allowed",
message.h.resource.component[1]));
ogs_sbi_header_free(&header);
return false;
}
if (NotificationData->event ==
OpenAPI_notification_event_type_NF_REGISTERED) {
OpenAPI_nf_profile_t *NFProfile = NULL;
NFProfile = NotificationData->nf_profile;
if (!NFProfile) {
ogs_error("No NFProfile");
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NFProfile", NULL));
ogs_sbi_header_free(&header);
return false;
}
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
if (!nf_instance) {
nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(nf_instance,
message.h.resource.component[1]);
amf_nf_fsm_init(nf_instance);
ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id);
} else {
OGS_FSM_TRAN(&nf_instance->sm, amf_nf_state_registered);
ogs_fsm_dispatch(&nf_instance->sm, NULL);
ogs_warn("[%s] (NRF-notify) NF has already been added",
message.h.resource.component[1]);
}
handled = ogs_sbi_nnrf_handle_nf_profile(
nf_instance, NFProfile, stream, recvmsg);
if (!handled) {
AMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
ogs_sbi_header_free(&header);
return false;
}
ogs_info("[%s] (NRF-notify) NF Profile updated", nf_instance->id);
handled = ogs_sbi_client_associate(nf_instance);
if (!handled) {
ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot find NF EndPoint", nf_instance->id));
AMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
ogs_sbi_header_free(&header);
return false;
}
} else if (NotificationData->event ==
OpenAPI_notification_event_type_NF_DEREGISTERED) {
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
if (nf_instance) {
AMF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
} else {
ogs_warn("[%s] (NRF-notify) Not found",
message.h.resource.component[1]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_NOT_FOUND,
recvmsg, "Not found", message.h.resource.component[1]));
ogs_sbi_header_free(&header);
return false;
}
} else {
char *eventstr = OpenAPI_notification_event_type_ToString(
NotificationData->event);
ogs_error("Not supported event [%d:%s]",
NotificationData->event, eventstr ? eventstr : "Unknown");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Not supported event",
eventstr ? eventstr : "Unknown"));
ogs_sbi_header_free(&header);
return false;
}
response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
ogs_sbi_header_free(&header);
return true;
}
void amf_nnrf_handle_nf_discover( void amf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
{ {
@ -273,84 +46,10 @@ void amf_nnrf_handle_nf_discover(
return; return;
} }
amf_nnrf_handle_nf_discover_search_result( ogs_nnrf_handle_nf_discover_search_result(
sbi_object, target_nf_type, discovery_option, SearchResult); sbi_object, target_nf_type, discovery_option, SearchResult);
amf_sbi_select_nf(sbi_object, target_nf_type, discovery_option); amf_sbi_select_nf(sbi_object, target_nf_type, discovery_option);
ogs_expect(true == amf_sbi_send_request(sbi_object, target_nf_type, xact)); ogs_expect(true == amf_sbi_send_request(sbi_object, target_nf_type, xact));
} }
void amf_nnrf_handle_nf_discover_search_result(
ogs_sbi_object_t *sbi_object,
OpenAPI_nf_type_e target_nf_type,
ogs_sbi_discovery_option_t *discovery_option,
OpenAPI_search_result_t *SearchResult)
{
bool handled;
OpenAPI_lnode_t *node = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(sbi_object);
ogs_assert(SearchResult);
OpenAPI_list_for_each(SearchResult->nf_instances, node) {
OpenAPI_nf_profile_t *NFProfile = NULL;
if (!node->data) continue;
NFProfile = node->data;
nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id);
if (!nf_instance) {
nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(nf_instance, NFProfile->nf_instance_id);
amf_nf_fsm_init(nf_instance);
ogs_info("[%s] (NF-discover) NF registered", nf_instance->id);
} else {
OGS_FSM_TRAN(&nf_instance->sm, amf_nf_state_registered);
ogs_fsm_dispatch(&nf_instance->sm, NULL);
ogs_warn("[%s] (NF-discover) NF has already been added",
NFProfile->nf_instance_id);
}
if (NF_INSTANCE_IS_OTHERS(nf_instance->id)) {
handled = ogs_sbi_nnrf_handle_nf_profile(
nf_instance, NFProfile, NULL, NULL);
if (!handled) {
ogs_error("ogs_sbi_nnrf_handle_nf_profile() failed [%s]",
nf_instance->id);
AMF_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
continue;
}
handled = ogs_sbi_client_associate(nf_instance);
if (!handled) {
ogs_error("[%s] Cannot assciate NF EndPoint", nf_instance->id);
AMF_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
continue;
}
/* TIME : Update validity from NRF */
if (SearchResult->is_validity_period &&
SearchResult->validity_period) {
nf_instance->time.validity_duration =
SearchResult->validity_period;
ogs_assert(nf_instance->t_validity);
ogs_timer_start(nf_instance->t_validity,
ogs_time_from_sec(nf_instance->time.validity_duration));
} else
ogs_warn("[%s] NF Instance validity-time should not 0",
nf_instance->id);
ogs_info("[%s] (NF-discover) NF Profile updated", nf_instance->id);
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -26,21 +26,8 @@
extern "C" { extern "C" {
#endif #endif
void amf_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg);
void amf_nnrf_handle_nf_status_subscribe(
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg);
bool amf_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
void amf_nnrf_handle_nf_discover( void amf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg);
void amf_nnrf_handle_nf_discover_search_result(
ogs_sbi_object_t *sbi_object,
OpenAPI_nf_type_e target_nf_type,
ogs_sbi_discovery_option_t *discovery_option,
OpenAPI_search_result_t *SearchResult);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -174,6 +174,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
amf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg) amf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg)
{ {
amf_ue_t *amf_ue = NULL; amf_ue_t *amf_ue = NULL;
ran_ue_t *ran_ue = NULL;
ogs_assert(sess); ogs_assert(sess);
amf_ue = sess->amf_ue; amf_ue = sess->amf_ue;
ogs_assert(amf_ue); ogs_assert(amf_ue);
@ -356,7 +358,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!n2smbuf) { if (!n2smbuf) {
ogs_error("[%s:%d] No N2 SM Content", ogs_error("[%s:%d] No N2 SM Content",
amf_ue->supi, sess->psi); amf_ue->supi, sess->psi);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error)); NGAP_CauseProtocol_semantic_error));
@ -380,7 +382,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!n2smbuf) { if (!n2smbuf) {
ogs_error("[%s:%d] No N2 SM Content", ogs_error("[%s:%d] No N2 SM Content",
amf_ue->supi, sess->psi); amf_ue->supi, sess->psi);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error)); NGAP_CauseProtocol_semantic_error));
@ -402,7 +404,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
default: default:
ogs_error("Not implemented [%d]", ogs_error("Not implemented [%d]",
SmContextUpdatedData->n2_sm_info_type); SmContextUpdatedData->n2_sm_info_type);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error)); NGAP_CauseProtocol_semantic_error));
@ -605,7 +607,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED) { } else if (state == AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED) {
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) { if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); ran_ue = ran_ue_cycle(amf_ue->ran_ue);
amf_ue_deassociate(amf_ue); amf_ue_deassociate(amf_ue);
@ -644,7 +646,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL) { } else if (state == AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL) {
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) { if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
ran_ue_t *iter = NULL; ran_ue_t *iter = NULL;
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); ran_ue = ran_ue_cycle(amf_ue->ran_ue);
amf_ue_deassociate(amf_ue); amf_ue_deassociate(amf_ue);
@ -701,8 +703,6 @@ int amf_nsmf_pdusession_handle_update_sm_context(
} }
} }
} else { } else {
amf_ue_t *amf_ue = NULL;
OpenAPI_sm_context_update_error_t *SmContextUpdateError = NULL; OpenAPI_sm_context_update_error_t *SmContextUpdateError = NULL;
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL; OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
ogs_pkbuf_t *n1smbuf = NULL; ogs_pkbuf_t *n1smbuf = NULL;
@ -719,7 +719,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!SmContextUpdateError) { if (!SmContextUpdateError) {
ogs_error("[%d:%d] No SmContextUpdateError [%d]", ogs_error("[%d:%d] No SmContextUpdateError [%d]",
sess->psi, sess->pti, recvmsg->res_status); sess->psi, sess->pti, recvmsg->res_status);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error)); NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
@ -728,7 +728,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!SmContextUpdateError->error) { if (!SmContextUpdateError->error) {
ogs_error("[%d:%d] No Error [%d]", ogs_error("[%d:%d] No Error [%d]",
sess->psi, sess->pti, recvmsg->res_status); sess->psi, sess->pti, recvmsg->res_status);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error)); NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
@ -761,7 +761,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
n2SmInfo = SmContextUpdateError->n2_sm_info; n2SmInfo = SmContextUpdateError->n2_sm_info;
if (!n2SmInfo || !n2SmInfo->content_id) { if (!n2SmInfo || !n2SmInfo->content_id) {
ogs_error("[%d:%d] No N2 SM Message", sess->psi, sess->pti); ogs_error("[%d:%d] No N2 SM Message", sess->psi, sess->pti);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error)); NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
@ -773,7 +773,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!n2smbuf) { if (!n2smbuf) {
ogs_error("[%d:%d] No N2 SM Content [%s]", ogs_error("[%d:%d] No N2 SM Content [%s]",
sess->psi, sess->pti, n2SmInfo->content_id); sess->psi, sess->pti, n2SmInfo->content_id);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error)); NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
@ -783,7 +783,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_error("[%d:%d] Error Indication", sess->psi, sess->pti); ogs_error("[%d:%d] Error Indication", sess->psi, sess->pti);
ogs_assert(OGS_OK == ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue, ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error)); NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -30,17 +30,17 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
ogs_assert(request); ogs_assert(request);
ogs_assert(data); ogs_assert(data);
e = amf_event_new(AMF_EVT_SBI_SERVER); e = amf_event_new(OGS_EVENT_SBI_SERVER);
ogs_assert(e); ogs_assert(e);
e->sbi.request = request; e->h.sbi.request = request;
e->sbi.data = data; e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_request_free(request); ogs_sbi_request_free(request);
amf_event_free(e); ogs_event_free(e);
return OGS_ERROR; return OGS_ERROR;
} }
@ -61,16 +61,16 @@ static int client_cb(int status, ogs_sbi_response_t *response, void *data)
ogs_assert(response); ogs_assert(response);
e = amf_event_new(AMF_EVT_SBI_CLIENT); e = amf_event_new(OGS_EVENT_SBI_CLIENT);
ogs_assert(e); ogs_assert(e);
e->sbi.response = response; e->h.sbi.response = response;
e->sbi.data = data; e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_response_free(response); ogs_sbi_response_free(response);
amf_event_free(e); ogs_event_free(e);
return OGS_ERROR; return OGS_ERROR;
} }
@ -82,6 +82,14 @@ int amf_sbi_open(void)
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_nf_service_t *service = NULL; ogs_sbi_nf_service_t *service = NULL;
/* To be notified when NF Instances registered/deregistered in NRF
* or when their profile is modified */
ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_AUSF);
ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_UDM);
ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_PCF);
ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_SMF);
ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_NSSF);
/* Add SELF NF instance */ /* Add SELF NF instance */
nf_instance = ogs_sbi_self()->nf_instance; nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -123,16 +131,9 @@ int amf_sbi_open(void)
/* NFRegister is sent and the response is received /* NFRegister is sent and the response is received
* by the above client callback. */ * by the above client callback. */
amf_nf_fsm_init(nf_instance); ogs_sbi_nf_fsm_init(nf_instance);
} }
/* Timer expiration handler of client wait timer */
ogs_sbi_self()->client_wait_expire = amf_timer_sbi_client_wait_expire;
/* NF register state in NF state machine */
ogs_sbi_self()->nf_state_registered =
(ogs_fsm_handler_t)amf_nf_state_registered;
if (ogs_sbi_server_start_all(server_cb) != OGS_OK) if (ogs_sbi_server_start_all(server_cb) != OGS_OK)
return OGS_ERROR; return OGS_ERROR;
@ -332,7 +333,7 @@ static int client_discover_cb(
goto cleanup; goto cleanup;
} }
amf_nnrf_handle_nf_discover_search_result( ogs_nnrf_handle_nf_discover_search_result(
&sess->sbi, OpenAPI_nf_type_SMF, NULL, message.SearchResult); &sess->sbi, OpenAPI_nf_type_SMF, NULL, message.SearchResult);
amf_sbi_select_nf(&sess->sbi, OpenAPI_nf_type_SMF, NULL); amf_sbi_select_nf(&sess->sbi, OpenAPI_nf_type_SMF, NULL);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,36 +20,33 @@
#include "context.h" #include "context.h"
static amf_timer_cfg_t g_amf_timer_cfg[MAX_NUM_OF_AMF_TIMER] = { static amf_timer_cfg_t g_amf_timer_cfg[MAX_NUM_OF_AMF_TIMER] = {
[AMF_TIMER_SBI_CLIENT_WAIT] =
{ .duration = ogs_time_from_msec(500) },
/* Paging procedure for EPS services initiated */ /* Paging procedure for EPS services initiated */
[AMF_TIMER_T3513] = [AMF_TIMER_T3513] =
{ .max_count = 2, .duration = ogs_time_from_sec(2) }, { .have = true, .max_count = 2, .duration = ogs_time_from_sec(2) },
/* DEREGISTRATION REQUEST sent */ /* DEREGISTRATION REQUEST sent */
[AMF_TIMER_T3522] = [AMF_TIMER_T3522] =
{ .max_count = 4, .duration = ogs_time_from_sec(3) }, { .have = true, .max_count = 4, .duration = ogs_time_from_sec(3) },
/* REGISTRATION ACCEPT sent */ /* REGISTRATION ACCEPT sent */
[AMF_TIMER_T3550] = [AMF_TIMER_T3550] =
{ .max_count = 4, .duration = ogs_time_from_sec(6) }, { .have = true, .max_count = 4, .duration = ogs_time_from_sec(6) },
/* CONFIGURATION UPDATE COMMAND sent */ /* CONFIGURATION UPDATE COMMAND sent */
[AMF_TIMER_T3555] = [AMF_TIMER_T3555] =
{ .max_count = 4, .duration = ogs_time_from_sec(6) }, { .have = true, .max_count = 4, .duration = ogs_time_from_sec(6) },
/* AUTHENTICATION REQUEST sent /* AUTHENTICATION REQUEST sent
* SECURITY MODE COMMAND sent */ * SECURITY MODE COMMAND sent */
[AMF_TIMER_T3560] = [AMF_TIMER_T3560] =
{ .max_count = 4, .duration = ogs_time_from_sec(6) }, { .have = true, .max_count = 4, .duration = ogs_time_from_sec(6) },
/* IDENTITY REQUEST sent */ /* IDENTITY REQUEST sent */
[AMF_TIMER_T3570] = [AMF_TIMER_T3570] =
{ .max_count = 4, .duration = ogs_time_from_sec(3) }, { .have = true, .max_count = 4, .duration = ogs_time_from_sec(3) },
[AMF_TIMER_NG_HOLDING] = [AMF_TIMER_NG_HOLDING] =
{ .duration = ogs_time_from_sec(30) }, { .have = true, .duration = ogs_time_from_sec(30) },
}; };
static void gmm_timer_event_send( static void gmm_timer_event_send(
@ -58,24 +55,28 @@ static void gmm_timer_event_send(
amf_timer_cfg_t *amf_timer_cfg(amf_timer_e id) amf_timer_cfg_t *amf_timer_cfg(amf_timer_e id)
{ {
ogs_assert(id < MAX_NUM_OF_AMF_TIMER); ogs_assert(id < MAX_NUM_OF_AMF_TIMER);
if (g_amf_timer_cfg[id].have != true) {
ogs_fatal("No timer[%d] configuration", id);
ogs_assert_if_reached();
}
return &g_amf_timer_cfg[id]; return &g_amf_timer_cfg[id];
} }
const char *amf_timer_get_name(amf_timer_e id) const char *amf_timer_get_name(int timer_id)
{ {
switch (id) { switch (timer_id) {
case AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL: case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
return "AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL"; return OGS_TIMER_NAME_NF_INSTANCE_REGISTRATION_INTERVAL;
case AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL: case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
return "AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL"; return OGS_TIMER_NAME_NF_INSTANCE_HEARTBEAT_INTERVAL;
case AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT: case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
return "AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT"; return OGS_TIMER_NAME_NF_INSTANCE_NO_HEARTBEAT;
case AMF_TIMER_NF_INSTANCE_VALIDITY: case OGS_TIMER_NF_INSTANCE_VALIDITY:
return "AMF_TIMER_NF_INSTANCE_VALIDITY"; return OGS_TIMER_NAME_NF_INSTANCE_VALIDITY;
case AMF_TIMER_SUBSCRIPTION_VALIDITY: case OGS_TIMER_SUBSCRIPTION_VALIDITY:
return "AMF_TIMER_SUBSCRIPTION_VALIDITY"; return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY;
case AMF_TIMER_SBI_CLIENT_WAIT: case OGS_TIMER_SBI_CLIENT_WAIT:
return "AMF_TIMER_SBI_CLIENT_WAIT"; return OGS_TIMER_NAME_SBI_CLIENT_WAIT;
case AMF_TIMER_NG_DELAYED_SEND: case AMF_TIMER_NG_DELAYED_SEND:
return "AMF_TIMER_NG_DELAYED_SEND"; return "AMF_TIMER_NG_DELAYED_SEND";
case AMF_TIMER_T3513: case AMF_TIMER_T3513:
@ -93,9 +94,10 @@ const char *amf_timer_get_name(amf_timer_e id)
case AMF_TIMER_NG_HOLDING: case AMF_TIMER_NG_HOLDING:
return "AMF_TIMER_NG_HOLDING"; return "AMF_TIMER_NG_HOLDING";
default: default:
break; break;
} }
ogs_error("Unknown Timer[%d]", timer_id);
return "UNKNOWN_TIMER"; return "UNKNOWN_TIMER";
} }
@ -105,90 +107,16 @@ void amf_timer_ng_delayed_send(void *data)
amf_event_t *e = data; amf_event_t *e = data;
ogs_assert(e); ogs_assert(e);
e->timer_id = AMF_TIMER_NG_DELAYED_SEND; e->h.timer_id = AMF_TIMER_NG_DELAYED_SEND;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_timer_delete(e->timer); ogs_timer_delete(e->timer);
amf_event_free(e); ogs_event_free(e);
} }
} }
static void sbi_timer_send_event(int timer_id, void *data)
{
int rv;
amf_event_t *e = NULL;
ogs_assert(data);
switch (timer_id) {
case AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case AMF_TIMER_NF_INSTANCE_VALIDITY:
case AMF_TIMER_SUBSCRIPTION_VALIDITY:
e = amf_event_new(AMF_EVT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
case AMF_TIMER_SBI_CLIENT_WAIT:
e = amf_event_new(AMF_EVT_SBI_TIMER);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("sbi_timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();
break;
}
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed [%d] in %s",
(int)rv, amf_timer_get_name(e->timer_id));
amf_event_free(e);
}
}
void amf_timer_nf_instance_registration_interval(void *data)
{
sbi_timer_send_event(AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL, data);
}
void amf_timer_nf_instance_heartbeat_interval(void *data)
{
sbi_timer_send_event(AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL, data);
}
void amf_timer_nf_instance_no_heartbeat(void *data)
{
sbi_timer_send_event(AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT, data);
}
void amf_timer_nf_instance_validity(void *data)
{
sbi_timer_send_event(AMF_TIMER_NF_INSTANCE_VALIDITY, data);
}
void amf_timer_subscription_validity(void *data)
{
sbi_timer_send_event(AMF_TIMER_SUBSCRIPTION_VALIDITY, data);
}
void amf_timer_sbi_client_wait_expire(void *data)
{
sbi_timer_send_event(AMF_TIMER_SBI_CLIENT_WAIT, data);
}
static void gmm_timer_event_send( static void gmm_timer_event_send(
amf_timer_e timer_id, amf_ue_t *amf_ue) amf_timer_e timer_id, amf_ue_t *amf_ue)
{ {
@ -196,15 +124,16 @@ static void gmm_timer_event_send(
amf_event_t *e = NULL; amf_event_t *e = NULL;
ogs_assert(amf_ue); ogs_assert(amf_ue);
e = amf_event_new(AMF_EVT_5GMM_TIMER); e = amf_event_new(AMF_EVENT_5GMM_TIMER);
ogs_assert(e); ogs_assert(e);
e->timer_id = timer_id; e->h.timer_id = timer_id;
e->amf_ue = amf_ue; e->amf_ue = amf_ue;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d in %s",
amf_event_free(e); (int)rv, amf_timer_get_name(timer_id));
ogs_event_free(e);
} }
} }
@ -242,15 +171,15 @@ void amf_timer_ng_holding_timer_expire(void *data)
ogs_assert(data); ogs_assert(data);
ran_ue = data; ran_ue = data;
e = amf_event_new(AMF_EVT_NGAP_TIMER); e = amf_event_new(AMF_EVENT_NGAP_TIMER);
ogs_assert(e); ogs_assert(e);
e->timer_id = AMF_TIMER_NG_HOLDING; e->h.timer_id = AMF_TIMER_NG_HOLDING;
e->ran_ue = ran_ue; e->ran_ue = ran_ue;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
amf_event_free(e); ogs_event_free(e);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,7 +20,7 @@
#ifndef AMF_TIMER_H #ifndef AMF_TIMER_H
#define AMF_TIMER_H #define AMF_TIMER_H
#include "ogs-core.h" #include "ogs-proto.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -28,14 +28,7 @@ extern "C" {
/* forward declaration */ /* forward declaration */
typedef enum { typedef enum {
AMF_TIMER_BASE = 0, AMF_TIMER_BASE = OGS_MAX_NUM_OF_PROTO_TIMER,
AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL,
AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL,
AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT,
AMF_TIMER_NF_INSTANCE_VALIDITY,
AMF_TIMER_SUBSCRIPTION_VALIDITY,
AMF_TIMER_SBI_CLIENT_WAIT,
AMF_TIMER_NG_DELAYED_SEND, AMF_TIMER_NG_DELAYED_SEND,
AMF_TIMER_NG_HOLDING, AMF_TIMER_NG_HOLDING,
@ -52,20 +45,14 @@ typedef enum {
} amf_timer_e; } amf_timer_e;
typedef struct amf_timer_cfg_s { typedef struct amf_timer_cfg_s {
bool have;
int max_count; int max_count;
ogs_time_t duration; ogs_time_t duration;
} amf_timer_cfg_t; } amf_timer_cfg_t;
amf_timer_cfg_t *amf_timer_cfg(amf_timer_e id); amf_timer_cfg_t *amf_timer_cfg(amf_timer_e id);
const char *amf_timer_get_name(amf_timer_e id); const char *amf_timer_get_name(int timer_id);
void amf_timer_nf_instance_registration_interval(void *data);
void amf_timer_nf_instance_heartbeat_interval(void *data);
void amf_timer_nf_instance_no_heartbeat(void *data);
void amf_timer_nf_instance_validity(void *data);
void amf_timer_subscription_validity(void *data);
void amf_timer_sbi_client_wait_expire(void *data);
void amf_timer_ng_delayed_send(void *data); void amf_timer_ng_delayed_send(void *data);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -53,17 +53,17 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ogs_assert(s); ogs_assert(s);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AUSF_EVT_SBI_SERVER: case OGS_EVENT_SBI_SERVER:
request = e->sbi.request; request = e->h.sbi.request;
ogs_assert(request); ogs_assert(request);
stream = e->sbi.data; stream = e->h.sbi.data;
ogs_assert(stream); ogs_assert(stream);
rv = ogs_sbi_parse_request(&message, request); rv = ogs_sbi_parse_request(&message, request);
@ -94,7 +94,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY) CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
SWITCH(message.h.method) SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST) CASE(OGS_SBI_HTTP_METHOD_POST)
ausf_nnrf_handle_nf_status_notify(stream, &message); ogs_nnrf_handle_nf_status_notify(stream, &message);
break; break;
DEFAULT DEFAULT
@ -154,7 +154,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ogs_assert(OGS_FSM_STATE(&ausf_ue->sm)); ogs_assert(OGS_FSM_STATE(&ausf_ue->sm));
e->ausf_ue = ausf_ue; e->ausf_ue = ausf_ue;
e->sbi.message = &message; e->h.sbi.message = &message;
ogs_fsm_dispatch(&ausf_ue->sm, e); ogs_fsm_dispatch(&ausf_ue->sm, e);
if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_exception)) { if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_exception)) {
ogs_error("[%s] State machine exception", ausf_ue->suci); ogs_error("[%s] State machine exception", ausf_ue->suci);
@ -174,10 +174,10 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ogs_sbi_message_free(&message); ogs_sbi_message_free(&message);
break; break;
case AUSF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
ogs_assert(e); ogs_assert(e);
response = e->sbi.response; response = e->h.sbi.response;
ogs_assert(response); ogs_assert(response);
rv = ogs_sbi_parse_response(&message, response); rv = ogs_sbi_parse_response(&message, response);
if (rv != OGS_OK) { if (rv != OGS_OK) {
@ -199,23 +199,23 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
SWITCH(message.h.resource.component[0]) SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES) CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data; nf_instance = e->h.sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &message; e->h.sbi.message = &message;
ogs_fsm_dispatch(&nf_instance->sm, e); ogs_fsm_dispatch(&nf_instance->sm, e);
break; break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS) CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data; subscription = e->h.sbi.data;
ogs_assert(subscription); ogs_assert(subscription);
SWITCH(message.h.method) SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST) CASE(OGS_SBI_HTTP_METHOD_POST)
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED || if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
message.res_status == OGS_SBI_HTTP_STATUS_OK) { message.res_status == OGS_SBI_HTTP_STATUS_OK) {
ausf_nnrf_handle_nf_status_subscribe( ogs_nnrf_handle_nf_status_subscribe(
subscription, &message); subscription, &message);
} else { } else {
ogs_error("[%s] HTTP response error [%d]", ogs_error("[%s] HTTP response error [%d]",
@ -250,7 +250,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC) CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
SWITCH(message.h.resource.component[0]) SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES) CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
SWITCH(message.h.method) SWITCH(message.h.method)
@ -276,7 +276,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
break; break;
CASE(OGS_SBI_SERVICE_NAME_NUDM_UEAU) CASE(OGS_SBI_SERVICE_NAME_NUDM_UEAU)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
sbi_xact = ogs_sbi_xact_cycle(sbi_xact); sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
@ -290,7 +290,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ausf_ue = (ausf_ue_t *)sbi_xact->sbi_object; ausf_ue = (ausf_ue_t *)sbi_xact->sbi_object;
ogs_assert(ausf_ue); ogs_assert(ausf_ue);
e->sbi.data = sbi_xact->assoc_stream; e->h.sbi.data = sbi_xact->assoc_stream;
ogs_sbi_xact_remove(sbi_xact); ogs_sbi_xact_remove(sbi_xact);
@ -301,7 +301,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
} }
e->ausf_ue = ausf_ue; e->ausf_ue = ausf_ue;
e->sbi.message = &message; e->h.sbi.message = &message;
ogs_fsm_dispatch(&ausf_ue->sm, e); ogs_fsm_dispatch(&ausf_ue->sm, e);
if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_exception)) { if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_exception)) {
@ -319,27 +319,27 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ogs_sbi_response_free(response); ogs_sbi_response_free(response);
break; break;
case AUSF_EVT_SBI_TIMER: case OGS_EVENT_SBI_TIMER:
ogs_assert(e); ogs_assert(e);
switch(e->timer_id) { switch(e->h.timer_id) {
case AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL: case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL: case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT: case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case AUSF_TIMER_NF_INSTANCE_VALIDITY: case OGS_TIMER_NF_INSTANCE_VALIDITY:
nf_instance = e->sbi.data; nf_instance = e->h.sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
ogs_fsm_dispatch(&nf_instance->sm, e); ogs_fsm_dispatch(&nf_instance->sm, e);
if (OGS_FSM_CHECK(&nf_instance->sm, ausf_nf_state_exception)) if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception))
ogs_error("[%s:%s] State machine exception [%d]", ogs_error("[%s:%s] State machine exception [%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id, e->timer_id); nf_instance->id, e->h.timer_id);
break; break;
case AUSF_TIMER_SUBSCRIPTION_VALIDITY: case OGS_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data; subscription = e->h.sbi.data;
ogs_assert(subscription); ogs_assert(subscription);
ogs_assert(ogs_sbi_self()->nf_instance); ogs_assert(ogs_sbi_self()->nf_instance);
@ -353,8 +353,8 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ogs_sbi_subscription_remove(subscription); ogs_sbi_subscription_remove(subscription);
break; break;
case AUSF_TIMER_SBI_CLIENT_WAIT: case OGS_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
stream = sbi_xact->assoc_stream; stream = sbi_xact->assoc_stream;
@ -370,7 +370,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
break; break;
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
ausf_timer_get_name(e->timer_id), e->timer_id); ogs_timer_get_name(e->h.timer_id), e->h.timer_id);
} }
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -30,16 +30,6 @@ void ausf_state_initial(ogs_fsm_t *s, ausf_event_t *e);
void ausf_state_final(ogs_fsm_t *s, ausf_event_t *e); void ausf_state_final(ogs_fsm_t *s, ausf_event_t *e);
void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e); void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e);
void ausf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance);
void ausf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance);
void ausf_nf_state_initial(ogs_fsm_t *s, ausf_event_t *e);
void ausf_nf_state_final(ogs_fsm_t *s, ausf_event_t *e);
void ausf_nf_state_will_register(ogs_fsm_t *s, ausf_event_t *e);
void ausf_nf_state_registered(ogs_fsm_t *s, ausf_event_t *e);
void ausf_nf_state_de_registered(ogs_fsm_t *s, ausf_event_t *e);
void ausf_nf_state_exception(ogs_fsm_t *s, ausf_event_t *e);
void ausf_ue_state_initial(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_initial(ogs_fsm_t *s, ausf_event_t *e);
void ausf_ue_state_final(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_final(ogs_fsm_t *s, ausf_event_t *e);
void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e); void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -141,8 +141,7 @@ ausf_ue_t *ausf_ue_add(char *suci)
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.ausf_ue = ausf_ue; e.ausf_ue = ausf_ue;
ogs_fsm_create(&ausf_ue->sm, ausf_ue_state_initial, ausf_ue_state_final); ogs_fsm_init(&ausf_ue->sm, ausf_ue_state_initial, ausf_ue_state_final, &e);
ogs_fsm_init(&ausf_ue->sm, &e);
ogs_list_add(&self.ausf_ue_list, ausf_ue); ogs_list_add(&self.ausf_ue_list, ausf_ue);
@ -160,7 +159,6 @@ void ausf_ue_remove(ausf_ue_t *ausf_ue)
memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.ausf_ue = ausf_ue; e.ausf_ue = ausf_ue;
ogs_fsm_fini(&ausf_ue->sm, &e); ogs_fsm_fini(&ausf_ue->sm, &e);
ogs_fsm_delete(&ausf_ue->sm);
/* Free SBI object memory */ /* Free SBI object memory */
ogs_sbi_object_free(&ausf_ue->sbi); ogs_sbi_object_free(&ausf_ue->sbi);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -25,7 +25,6 @@
#include "ogs-sbi.h" #include "ogs-sbi.h"
#include "ausf-sm.h" #include "ausf-sm.h"
#include "timer.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -63,22 +62,6 @@ struct ausf_ue_s {
uint8_t hxres_star[OGS_MAX_RES_LEN]; uint8_t hxres_star[OGS_MAX_RES_LEN];
uint8_t kausf[OGS_SHA256_DIGEST_SIZE]; uint8_t kausf[OGS_SHA256_DIGEST_SIZE];
uint8_t kseaf[OGS_SHA256_DIGEST_SIZE]; uint8_t kseaf[OGS_SHA256_DIGEST_SIZE];
#define AUSF_NF_INSTANCE_CLEAR(_cAUSE, _nFInstance) \
do { \
ogs_assert(_nFInstance); \
if ((_nFInstance)->reference_count == 1) { \
ogs_info("[%s] (%s) NF removed", (_nFInstance)->id, (_cAUSE)); \
ausf_nf_fsm_fini((_nFInstance)); \
ogs_sbi_nf_instance_remove(_nFInstance); \
} else { \
/* There is an assocation with other context */ \
ogs_info("[%s:%d] (%s) NF suspended", \
_nFInstance->id, _nFInstance->reference_count, (_cAUSE)); \
OGS_FSM_TRAN(&_nFInstance->sm, ausf_nf_state_de_registered); \
ogs_fsm_dispatch(&_nFInstance->sm, NULL); \
} \
} while(0)
}; };
void ausf_context_init(void); void ausf_context_init(void);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -18,60 +18,42 @@
*/ */
#include "event.h" #include "event.h"
#include "context.h"
static OGS_POOL(pool, ausf_event_t); ausf_event_t *ausf_event_new(int id)
void ausf_event_init(void)
{
ogs_pool_init(&pool, ogs_app()->pool.event);
}
void ausf_event_final(void)
{
ogs_pool_final(&pool);
}
ausf_event_t *ausf_event_new(ausf_event_e id)
{ {
ausf_event_t *e = NULL; ausf_event_t *e = NULL;
ogs_pool_alloc(&pool, &e); e = ogs_event_size(id, sizeof(ausf_event_t));
ogs_assert(e); ogs_assert(e);
memset(e, 0, sizeof(*e));
e->id = id; e->h.id = id;
return e; return e;
} }
void ausf_event_free(ausf_event_t *e)
{
ogs_assert(e);
ogs_pool_free(&pool, e);
}
const char *ausf_event_get_name(ausf_event_t *e) const char *ausf_event_get_name(ausf_event_t *e)
{ {
if (e == NULL) if (e == NULL) {
return OGS_FSM_NAME_INIT_SIG; return OGS_FSM_NAME_INIT_SIG;
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case AUSF_EVT_SBI_SERVER:
return "AUSF_EVT_SBI_SERVER";
case AUSF_EVT_SBI_CLIENT:
return "AUSF_EVT_SBI_CLIENT";
case AUSF_EVT_SBI_TIMER:
return "AUSF_EVT_SBI_TIMER";
default:
break;
} }
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case OGS_EVENT_SBI_SERVER:
return OGS_EVENT_NAME_SBI_SERVER;
case OGS_EVENT_SBI_CLIENT:
return OGS_EVENT_NAME_SBI_CLIENT;
case OGS_EVENT_SBI_TIMER:
return OGS_EVENT_NAME_SBI_TIMER;
default:
break;
}
ogs_error("Unknown Event[%d]", e->h.id);
return "UNKNOWN_EVENT"; return "UNKNOWN_EVENT";
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,53 +20,21 @@
#ifndef AUSF_EVENT_H #ifndef AUSF_EVENT_H
#define AUSF_EVENT_H #define AUSF_EVENT_H
#include "ogs-core.h" #include "ogs-proto.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
typedef struct ogs_sbi_response_s ogs_sbi_response_t;
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
typedef struct ogs_sbi_nf_instance_s ogs_sbi_nf_instance_t;
typedef struct ogs_sbi_subscription_s ogs_sbi_subscription_t;
typedef struct ausf_ue_s ausf_ue_t; typedef struct ausf_ue_s ausf_ue_t;
typedef enum {
AUSF_EVT_BASE = OGS_FSM_USER_SIG,
AUSF_EVT_SBI_SERVER,
AUSF_EVT_SBI_CLIENT,
AUSF_EVT_SBI_TIMER,
AUSF_EVT_TOP,
} ausf_event_e;
typedef struct ausf_event_s { typedef struct ausf_event_s {
int id; ogs_event_t h;
int timer_id;
struct {
ogs_sbi_request_t *request;
ogs_sbi_response_t *response;
void *data;
ogs_sbi_message_t *message;
} sbi;
ausf_ue_t *ausf_ue; ausf_ue_t *ausf_ue;
ogs_timer_t *timer;
} ausf_event_t; } ausf_event_t;
void ausf_event_init(void); ausf_event_t *ausf_event_new(int id);
void ausf_event_final(void);
ausf_event_t *ausf_event_new(ausf_event_e id);
void ausf_event_free(ausf_event_t *e);
const char *ausf_event_get_name(ausf_event_t *e); const char *ausf_event_get_name(ausf_event_t *e);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -30,7 +30,6 @@ int ausf_initialize()
ogs_sbi_context_init(); ogs_sbi_context_init();
ausf_context_init(); ausf_context_init();
ausf_event_init();
rv = ogs_sbi_context_parse_config("ausf", "nrf", "scp"); rv = ogs_sbi_context_parse_config("ausf", "nrf", "scp");
if (rv != OGS_OK) return rv; if (rv != OGS_OK) return rv;
@ -61,7 +60,7 @@ static void event_termination(void)
/* Sending NF Instance De-registeration to NRF */ /* Sending NF Instance De-registeration to NRF */
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
ausf_nf_fsm_fini(nf_instance); ogs_sbi_nf_fsm_fini(nf_instance);
/* Starting holding timer */ /* Starting holding timer */
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL); t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
@ -87,8 +86,6 @@ void ausf_terminate(void)
ausf_context_final(); ausf_context_final();
ogs_sbi_context_final(); ogs_sbi_context_final();
ausf_event_final(); /* Destroy event */
} }
static void ausf_main(void *data) static void ausf_main(void *data)
@ -96,8 +93,7 @@ static void ausf_main(void *data)
ogs_fsm_t ausf_sm; ogs_fsm_t ausf_sm;
int rv; int rv;
ogs_fsm_create(&ausf_sm, ausf_state_initial, ausf_state_final); ogs_fsm_init(&ausf_sm, ausf_state_initial, ausf_state_final, 0);
ogs_fsm_init(&ausf_sm, 0);
for ( ;; ) { for ( ;; ) {
ogs_pollset_poll(ogs_app()->pollset, ogs_pollset_poll(ogs_app()->pollset,
@ -130,11 +126,10 @@ static void ausf_main(void *data)
ogs_assert(e); ogs_assert(e);
ogs_fsm_dispatch(&ausf_sm, e); ogs_fsm_dispatch(&ausf_sm, e);
ausf_event_free(e); ogs_event_free(e);
} }
} }
done: done:
ogs_fsm_fini(&ausf_sm, 0); ogs_fsm_fini(&ausf_sm, 0);
ogs_fsm_delete(&ausf_sm);
} }

View File

@ -1,4 +1,4 @@
# Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> # Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
# This file is part of Open5GS. # This file is part of Open5GS.
@ -18,12 +18,8 @@
libausf_sources = files(''' libausf_sources = files('''
context.c context.c
event.c event.c
timer.c
nnrf-build.c
nnrf-handler.c nnrf-handler.c
nf-sm.c
nausf-handler.c nausf-handler.c
nudm-build.c nudm-build.c

View File

@ -1,447 +0,0 @@
/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "context.h"
#include "sbi-path.h"
#include "nnrf-handler.h"
void ausf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance)
{
ausf_event_t e;
ogs_assert(nf_instance);
memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance;
ogs_fsm_create(&nf_instance->sm,
ausf_nf_state_initial, ausf_nf_state_final);
ogs_fsm_init(&nf_instance->sm, &e);
}
void ausf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance)
{
ausf_event_t e;
ogs_assert(nf_instance);
memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance;
ogs_fsm_fini(&nf_instance->sm, &e);
ogs_fsm_delete(&nf_instance->sm);
}
void ausf_nf_state_initial(ogs_fsm_t *s, ausf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s);
ogs_assert(e);
ausf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
ausf_timer_nf_instance_registration_interval, nf_instance);
ogs_assert(nf_instance->t_registration_interval);
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
ausf_timer_nf_instance_heartbeat_interval, nf_instance);
ogs_assert(nf_instance->t_heartbeat_interval);
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
ausf_timer_nf_instance_no_heartbeat, nf_instance);
ogs_assert(nf_instance->t_no_heartbeat);
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
ausf_timer_nf_instance_validity, nf_instance);
ogs_assert(nf_instance->t_validity);
if (NF_INSTANCE_IS_NRF(nf_instance)) {
OGS_FSM_TRAN(s, &ausf_nf_state_will_register);
} else {
ogs_assert(nf_instance->id);
OGS_FSM_TRAN(s, &ausf_nf_state_registered);
}
}
void ausf_nf_state_final(ogs_fsm_t *s, ausf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s);
ogs_assert(e);
ausf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_timer_delete(nf_instance->t_registration_interval);
ogs_timer_delete(nf_instance->t_heartbeat_interval);
ogs_timer_delete(nf_instance->t_no_heartbeat);
ogs_timer_delete(nf_instance->t_validity);
}
void ausf_nf_state_will_register(ogs_fsm_t *s, ausf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL;
ogs_sbi_message_t *message = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
ausf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
ogs_assert(NF_INSTANCE_IS_NRF(nf_instance));
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
nf_instance, ausf_nnrf_nfm_build_register));
break;
case OGS_FSM_EXIT_SIG:
ogs_timer_stop(nf_instance->t_registration_interval);
break;
case AUSF_EVT_SBI_CLIENT:
message = e->sbi.message;
ogs_assert(message);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
if (message->res_status == OGS_SBI_HTTP_STATUS_OK ||
message->res_status == OGS_SBI_HTTP_STATUS_CREATED) {
ausf_nnrf_handle_nf_register(nf_instance, message);
OGS_FSM_TRAN(s, &ausf_nf_state_registered);
} else {
ogs_error("[%s] HTTP response error [%d]",
ogs_sbi_self()->nf_instance->id,
message->res_status);
OGS_FSM_TRAN(s, &ausf_nf_state_exception);
}
break;
DEFAULT
ogs_error("[%s] Invalid resource name [%s]",
ogs_sbi_self()->nf_instance->id,
message->h.resource.component[0]);
END
break;
DEFAULT
ogs_error("[%s] Invalid API name [%s]",
ogs_sbi_self()->nf_instance->id, message->h.service.name);
END
break;
case AUSF_EVT_SBI_TIMER:
switch(e->timer_id) {
case AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client;
ogs_assert(client);
addr = client->node.addr;
ogs_assert(addr);
ogs_warn("[%s] Retry to registration with NRF",
ogs_sbi_self()->nf_instance->id);
ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
nf_instance, ausf_nnrf_nfm_build_register));
break;
default:
ogs_error("[%s] Unknown timer[%s:%d]",
ogs_sbi_self()->nf_instance->id,
ausf_timer_get_name(e->timer_id), e->timer_id);
}
break;
default:
ogs_error("Unknown event %s", ausf_event_get_name(e));
break;
}
}
void ausf_nf_state_registered(ogs_fsm_t *s, ausf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL;
ogs_sbi_message_t *message = NULL;
ogs_assert(s);
ogs_assert(e);
ausf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF registered [Heartbeat:%ds]",
ogs_sbi_self()->nf_instance->id,
nf_instance->time.heartbeat_interval);
client = nf_instance->client;
ogs_assert(client);
if (nf_instance->time.heartbeat_interval) {
ogs_timer_start(nf_instance->t_heartbeat_interval,
ogs_time_from_sec(nf_instance->time.heartbeat_interval));
ogs_timer_start(nf_instance->t_no_heartbeat,
ogs_time_from_sec(
nf_instance->time.heartbeat_interval +
ogs_app()->time.nf_instance.no_heartbeat_margin));
}
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(client,
ogs_sbi_self()->nf_instance->nf_type,
ogs_sbi_self()->nf_instance->id,
OpenAPI_nf_type_UDM));
}
break;
case OGS_FSM_EXIT_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
if (nf_instance->time.heartbeat_interval) {
ogs_timer_stop(nf_instance->t_heartbeat_interval);
ogs_timer_stop(nf_instance->t_no_heartbeat);
}
if (!OGS_FSM_CHECK(&nf_instance->sm, ausf_nf_state_exception)) {
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_de_register(nf_instance));
}
}
break;
case AUSF_EVT_SBI_CLIENT:
message = e->sbi.message;
ogs_assert(message);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
if (message->res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT ||
message->res_status == OGS_SBI_HTTP_STATUS_OK) {
if (nf_instance->time.heartbeat_interval)
ogs_timer_start(nf_instance->t_no_heartbeat,
ogs_time_from_sec(
nf_instance->time.heartbeat_interval +
ogs_app()->time.nf_instance.
no_heartbeat_margin));
} else {
ogs_warn("[%s] HTTP response error [%d]",
ogs_sbi_self()->nf_instance->id,
message->res_status);
OGS_FSM_TRAN(s, &ausf_nf_state_exception);
}
break;
DEFAULT
ogs_error("[%s] Invalid resource name [%s]",
ogs_sbi_self()->nf_instance->id,
message->h.resource.component[0]);
END
break;
DEFAULT
ogs_error("[%s] Invalid API name [%s]",
ogs_sbi_self()->nf_instance->id, message->h.service.name);
END
break;
case AUSF_EVT_SBI_TIMER:
switch(e->timer_id) {
case AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
if (nf_instance->time.heartbeat_interval)
ogs_timer_start(nf_instance->t_heartbeat_interval,
ogs_time_from_sec(nf_instance->time.heartbeat_interval));
ogs_assert(true == ogs_nnrf_nfm_send_nf_update(nf_instance));
break;
case AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
ogs_error("[%s] No heartbeat", ogs_sbi_self()->nf_instance->id);
OGS_FSM_TRAN(s, &ausf_nf_state_will_register);
break;
case AUSF_TIMER_NF_INSTANCE_VALIDITY:
ogs_assert(!NF_INSTANCE_IS_NRF(nf_instance));
ogs_assert(nf_instance->id);
ogs_info("[%s] NF expired", nf_instance->id);
OGS_FSM_TRAN(s, &ausf_nf_state_de_registered);
break;
default:
ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
ausf_timer_get_name(e->timer_id), e->timer_id);
}
break;
default:
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
ausf_event_get_name(e));
break;
}
}
void ausf_nf_state_de_registered(ogs_fsm_t *s, ausf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(s);
ogs_assert(e);
ausf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
}
break;
case OGS_FSM_EXIT_SIG:
break;
default:
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
ausf_event_get_name(e));
break;
}
}
void ausf_nf_state_exception(ogs_fsm_t *s, ausf_event_t *e)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_client_t *client = NULL;
ogs_sbi_message_t *message = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
ausf_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_instance);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_timer_start(nf_instance->t_registration_interval,
ogs_app()->time.message.sbi.
nf_register_interval_in_exception);
}
break;
case OGS_FSM_EXIT_SIG:
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_timer_stop(nf_instance->t_registration_interval);
}
break;
case AUSF_EVT_SBI_TIMER:
switch(e->timer_id) {
case AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client;
ogs_assert(client);
addr = client->node.addr;
ogs_assert(addr);
ogs_warn("[%s] Retry to registration with NRF",
ogs_sbi_self()->nf_instance->id);
OGS_FSM_TRAN(s, &ausf_nf_state_will_register);
break;
default:
ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
ausf_timer_get_name(e->timer_id), e->timer_id);
}
break;
case AUSF_EVT_SBI_CLIENT:
message = e->sbi.message;
ogs_assert(message);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
message->h.resource.component[0]);
END
break;
DEFAULT
ogs_error("Invalid API name [%s]", message->h.service.name);
END
break;
default:
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
ausf_event_get_name(e));
break;
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "nnrf-build.h"
ogs_sbi_request_t *ausf_nnrf_nfm_build_register(void)
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
OpenAPI_nf_profile_t *NFProfile = NULL;
nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance);
ogs_assert(nf_instance->id);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
message.h.resource.component[1] = nf_instance->id;
message.http.content_encoding = (char*)ogs_sbi_self()->content_encoding;
NFProfile = ogs_nnrf_nfm_build_nf_profile();
ogs_expect_or_return_val(NFProfile, NULL);
message.NFProfile = NFProfile;
request = ogs_sbi_build_request(&message);
ogs_sbi_nnrf_free_nf_profile(NFProfile);
return request;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,243 +20,14 @@
#include "sbi-path.h" #include "sbi-path.h"
#include "nnrf-handler.h" #include "nnrf-handler.h"
void ausf_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg)
{
OpenAPI_nf_profile_t *NFProfile = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(recvmsg);
ogs_assert(nf_instance);
client = nf_instance->client;
ogs_assert(client);
NFProfile = recvmsg->NFProfile;
if (!NFProfile) {
ogs_error("No NFProfile");
return;
}
/* TIME : Update heartbeat from NRF */
if (NFProfile->is_heart_beat_timer == true)
nf_instance->time.heartbeat_interval = NFProfile->heart_beat_timer;
}
void ausf_nnrf_handle_nf_status_subscribe(
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg)
{
OpenAPI_subscription_data_t *SubscriptionData = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(recvmsg);
ogs_assert(subscription);
client = subscription->client;
ogs_assert(client);
SubscriptionData = recvmsg->SubscriptionData;
if (!SubscriptionData) {
ogs_error("No SubscriptionData");
return;
}
if (!SubscriptionData->subscription_id) {
ogs_error("No SubscriptionId");
return;
}
ogs_sbi_subscription_set_id(
subscription, SubscriptionData->subscription_id);
if (SubscriptionData->validity_time) {
#define VALIDITY_MINIMUM (10LL * OGS_USEC_PER_SEC) /* 10 seconds */
ogs_time_t time, duration;
if (ogs_sbi_time_from_string(
&time, SubscriptionData->validity_time) == true) {
duration = time - ogs_time_now();
if (duration < VALIDITY_MINIMUM) {
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %lld seconds", subscription->id,
(long long)ogs_time_sec(VALIDITY_MINIMUM));
}
subscription->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
ausf_timer_subscription_validity, subscription);
ogs_assert(subscription->t_validity);
ogs_timer_start(subscription->t_validity, duration);
} else {
ogs_error("Cannot parse validitiyTime [%s]",
SubscriptionData->validity_time);
}
}
}
bool ausf_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
int rv;
bool handled;
ogs_sbi_response_t *response = NULL;
OpenAPI_notification_data_t *NotificationData = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_message_t message;
ogs_sbi_header_t header;
ogs_assert(stream);
ogs_assert(recvmsg);
NotificationData = recvmsg->NotificationData;
if (!NotificationData) {
ogs_error("No NotificationData");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NotificationData", NULL));
return false;
}
if (!NotificationData->nf_instance_uri) {
ogs_error("No nfInstanceUri");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No nfInstanceUri", NULL));
return false;
}
memset(&header, 0, sizeof(header));
header.uri = NotificationData->nf_instance_uri;
rv = ogs_sbi_parse_header(&message, &header);
if (rv != OGS_OK) {
ogs_error("Cannot parse nfInstanceUri [%s]", header.uri);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot parse nfInstanceUri", header.uri));
return false;
}
if (!message.h.resource.component[1]) {
ogs_error("No nfInstanceId [%s]", header.uri);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot parse nfInstanceUri", header.uri));
ogs_sbi_header_free(&header);
return false;
}
if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) {
ogs_warn("[%s] The notification is not allowed",
message.h.resource.component[1]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN,
recvmsg, "The notification is not allowed",
message.h.resource.component[1]));
ogs_sbi_header_free(&header);
return false;
}
if (NotificationData->event ==
OpenAPI_notification_event_type_NF_REGISTERED) {
OpenAPI_nf_profile_t *NFProfile = NULL;
NFProfile = NotificationData->nf_profile;
if (!NFProfile) {
ogs_error("No NFProfile");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NFProfile", NULL));
ogs_sbi_header_free(&header);
return false;
}
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
if (!nf_instance) {
nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(nf_instance,
message.h.resource.component[1]);
ausf_nf_fsm_init(nf_instance);
ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id);
} else {
OGS_FSM_TRAN(&nf_instance->sm, ausf_nf_state_registered);
ogs_fsm_dispatch(&nf_instance->sm, NULL);
ogs_warn("[%s] (NRF-notify) NF has already been added",
message.h.resource.component[1]);
}
handled = ogs_sbi_nnrf_handle_nf_profile(
nf_instance, NFProfile, stream, recvmsg);
if (!handled) {
AUSF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
ogs_sbi_header_free(&header);
return false;
}
ogs_info("[%s] (NRF-notify) NF Profile updated", nf_instance->id);
handled = ogs_sbi_client_associate(nf_instance);
if (!handled) {
ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Cannot find NF EndPoint", nf_instance->id));
AUSF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
ogs_sbi_header_free(&header);
return false;
}
} else if (NotificationData->event ==
OpenAPI_notification_event_type_NF_DEREGISTERED) {
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
if (nf_instance) {
AUSF_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
} else {
ogs_warn("[%s] (NRF-notify) Not found",
message.h.resource.component[1]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_NOT_FOUND,
recvmsg, "Not found", message.h.resource.component[1]));
ogs_sbi_header_free(&header);
return false;
}
} else {
char *eventstr = OpenAPI_notification_event_type_ToString(
NotificationData->event);
ogs_error("Not supported event [%d:%s]",
NotificationData->event, eventstr ? eventstr : "Unknown");
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "Not supported event",
eventstr ? eventstr : "Unknown"));
ogs_sbi_header_free(&header);
return false;
}
response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
ogs_sbi_header_free(&header);
return true;
}
void ausf_nnrf_handle_nf_discover( void ausf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg) ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
{ {
ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_object_t *sbi_object = NULL;
OpenAPI_nf_type_e target_nf_type = 0; OpenAPI_nf_type_e target_nf_type = 0;
ogs_sbi_discovery_option_t *discovery_option = NULL; ogs_sbi_discovery_option_t *discovery_option = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
OpenAPI_search_result_t *SearchResult = NULL; OpenAPI_search_result_t *SearchResult = NULL;
OpenAPI_lnode_t *node = NULL;
bool handled;
ogs_assert(recvmsg); ogs_assert(recvmsg);
ogs_assert(xact); ogs_assert(xact);
@ -273,64 +44,8 @@ void ausf_nnrf_handle_nf_discover(
return; return;
} }
OpenAPI_list_for_each(SearchResult->nf_instances, node) { ogs_nnrf_handle_nf_discover_search_result(
OpenAPI_nf_profile_t *NFProfile = NULL; sbi_object, target_nf_type, discovery_option, SearchResult);
if (!node->data) continue;
NFProfile = node->data;
nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id);
if (!nf_instance) {
nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(nf_instance, NFProfile->nf_instance_id);
ausf_nf_fsm_init(nf_instance);
ogs_info("[%s] (NF-discover) NF registered", nf_instance->id);
} else {
OGS_FSM_TRAN(&nf_instance->sm, ausf_nf_state_registered);
ogs_fsm_dispatch(&nf_instance->sm, NULL);
ogs_warn("[%s] (NF-discover) NF has already been added",
NFProfile->nf_instance_id);
}
if (NF_INSTANCE_IS_OTHERS(nf_instance->id)) {
handled = ogs_sbi_nnrf_handle_nf_profile(
nf_instance, NFProfile, NULL, NULL);
if (!handled) {
ogs_error("[%s] ogs_sbi_nnrf_handle_nf_profile() failed",
nf_instance->id);
AUSF_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
continue;
}
handled = ogs_sbi_client_associate(nf_instance);
if (!handled) {
ogs_error("[%s] Cannot assciate NF EndPoint", nf_instance->id);
AUSF_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
continue;
}
/* TIME : Update validity from NRF */
if (SearchResult->is_validity_period &&
SearchResult->validity_period) {
nf_instance->time.validity_duration =
SearchResult->validity_period;
ogs_assert(nf_instance->t_validity);
ogs_timer_start(nf_instance->t_validity,
ogs_time_from_sec(nf_instance->time.validity_duration));
} else
ogs_warn("[%s] NF Instance validity-time should not 0",
nf_instance->id);
ogs_info("[%s] (NF-discover) NF Profile updated", nf_instance->id);
}
}
ogs_sbi_select_nf(sbi_object, target_nf_type, discovery_option); ogs_sbi_select_nf(sbi_object, target_nf_type, discovery_option);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -26,14 +26,6 @@
extern "C" { extern "C" {
#endif #endif
void ausf_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg);
void ausf_nnrf_handle_nf_status_subscribe(
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg);
bool ausf_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
void ausf_nnrf_handle_nf_discover( void ausf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -27,17 +27,17 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
ogs_assert(request); ogs_assert(request);
ogs_assert(data); ogs_assert(data);
e = ausf_event_new(AUSF_EVT_SBI_SERVER); e = ausf_event_new(OGS_EVENT_SBI_SERVER);
ogs_assert(e); ogs_assert(e);
e->sbi.request = request; e->h.sbi.request = request;
e->sbi.data = data; e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_request_free(request); ogs_sbi_request_free(request);
ausf_event_free(e); ogs_event_free(e);
return OGS_ERROR; return OGS_ERROR;
} }
@ -58,16 +58,16 @@ static int client_cb(int status, ogs_sbi_response_t *response, void *data)
ogs_assert(response); ogs_assert(response);
e = ausf_event_new(AUSF_EVT_SBI_CLIENT); e = ausf_event_new(OGS_EVENT_SBI_CLIENT);
ogs_assert(e); ogs_assert(e);
e->sbi.response = response; e->h.sbi.response = response;
e->sbi.data = data; e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e); rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv); ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_response_free(response); ogs_sbi_response_free(response);
ausf_event_free(e); ogs_event_free(e);
return OGS_ERROR; return OGS_ERROR;
} }
@ -79,6 +79,10 @@ int ausf_sbi_open(void)
ogs_sbi_nf_instance_t *nf_instance = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_nf_service_t *service = NULL; ogs_sbi_nf_service_t *service = NULL;
/* To be notified when NF Instances registered/deregistered in NRF
* or when their profile is modified */
ogs_sbi_add_to_be_notified_nf_type(OpenAPI_nf_type_UDM);
/* Add SELF NF instance */ /* Add SELF NF instance */
nf_instance = ogs_sbi_self()->nf_instance; nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance); ogs_assert(nf_instance);
@ -98,28 +102,20 @@ int ausf_sbi_open(void)
} }
/* Initialize NRF NF Instance */ /* Initialize NRF NF Instance */
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) { nf_instance = ogs_sbi_self()->nrf_instance;
if (NF_INSTANCE_IS_NRF(nf_instance)) { if (nf_instance) {
ogs_sbi_client_t *client = NULL; ogs_sbi_client_t *client = NULL;
/* Client callback is only used when NF sends to NRF */ /* Client callback is only used when NF sends to NRF */
client = nf_instance->client; client = nf_instance->client;
ogs_assert(client); ogs_assert(client);
client->cb = client_cb; client->cb = client_cb;
/* NFRegister is sent and the response is received /* NFRegister is sent and the response is received
* by the above client callback. */ * by the above client callback. */
ausf_nf_fsm_init(nf_instance); ogs_sbi_nf_fsm_init(nf_instance);
}
} }
/* Timer expiration handler of client wait timer */
ogs_sbi_self()->client_wait_expire = ausf_timer_sbi_client_wait_expire;
/* NF register state in NF state machine */
ogs_sbi_self()->nf_state_registered =
(ogs_fsm_handler_t)ausf_nf_state_registered;
if (ogs_sbi_server_start_all(server_cb) != OGS_OK) if (ogs_sbi_server_start_all(server_cb) != OGS_OK)
return OGS_ERROR; return OGS_ERROR;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,7 +20,6 @@
#ifndef AUSF_SBI_PATH_H #ifndef AUSF_SBI_PATH_H
#define AUSF_SBI_PATH_H #define AUSF_SBI_PATH_H
#include "nnrf-build.h"
#include "nudm-build.h" #include "nudm-build.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,116 +0,0 @@
/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "context.h"
const char *ausf_timer_get_name(ausf_timer_e id)
{
switch (id) {
case AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
return "AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL";
case AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
return "AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL";
case AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
return "AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT";
case AUSF_TIMER_NF_INSTANCE_VALIDITY:
return "AUSF_TIMER_NF_INSTANCE_VALIDITY";
case AUSF_TIMER_SUBSCRIPTION_VALIDITY:
return "AUSF_TIMER_SUBSCRIPTION_VALIDITY";
case AUSF_TIMER_SBI_CLIENT_WAIT:
return "AUSF_TIMER_SBI_CLIENT_WAIT";
default:
break;
}
return "UNKNOWN_TIMER";
}
static void sbi_timer_send_event(int timer_id, void *data)
{
int rv;
ausf_event_t *e = NULL;
ogs_assert(data);
switch (timer_id) {
case AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case AUSF_TIMER_NF_INSTANCE_VALIDITY:
case AUSF_TIMER_SUBSCRIPTION_VALIDITY:
e = ausf_event_new(AUSF_EVT_SBI_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->sbi.data = data;
break;
case AUSF_TIMER_SBI_CLIENT_WAIT:
e = ausf_event_new(AUSF_EVT_SBI_TIMER);
if (!e) {
ogs_sbi_xact_t *sbi_xact = data;
ogs_assert(sbi_xact);
ogs_error("sbi_timer_send_event() failed");
ogs_sbi_xact_remove(sbi_xact);
return;
}
e->timer_id = timer_id;
e->sbi.data = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();
break;
}
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed [%d] in %s",
(int)rv, ausf_timer_get_name(e->timer_id));
ausf_event_free(e);
}
}
void ausf_timer_nf_instance_registration_interval(void *data)
{
sbi_timer_send_event(AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL, data);
}
void ausf_timer_nf_instance_heartbeat_interval(void *data)
{
sbi_timer_send_event(AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL, data);
}
void ausf_timer_nf_instance_no_heartbeat(void *data)
{
sbi_timer_send_event(AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT, data);
}
void ausf_timer_nf_instance_validity(void *data)
{
sbi_timer_send_event(AUSF_TIMER_NF_INSTANCE_VALIDITY, data);
}
void ausf_timer_subscription_validity(void *data)
{
sbi_timer_send_event(AUSF_TIMER_SUBSCRIPTION_VALIDITY, data);
}
void ausf_timer_sbi_client_wait_expire(void *data)
{
sbi_timer_send_event(AUSF_TIMER_SBI_CLIENT_WAIT, data);
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef AUSF_TIMER_H
#define AUSF_TIMER_H
#include "ogs-core.h"
#ifdef __cplusplus
extern "C" {
#endif
/* forward declaration */
typedef enum {
AUSF_TIMER_BASE = 0,
AUSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL,
AUSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL,
AUSF_TIMER_NF_INSTANCE_NO_HEARTBEAT,
AUSF_TIMER_NF_INSTANCE_VALIDITY,
AUSF_TIMER_SUBSCRIPTION_VALIDITY,
AUSF_TIMER_SBI_CLIENT_WAIT,
MAX_NUM_OF_AUSF_TIMER,
} ausf_timer_e;
const char *ausf_timer_get_name(ausf_timer_e id);
void ausf_timer_nf_instance_registration_interval(void *data);
void ausf_timer_nf_instance_heartbeat_interval(void *data);
void ausf_timer_nf_instance_no_heartbeat(void *data);
void ausf_timer_nf_instance_validity(void *data);
void ausf_timer_subscription_validity(void *data);
void ausf_timer_sbi_client_wait_expire(void *data);
#ifdef __cplusplus
}
#endif
#endif /* AUSF_TIMER_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -66,17 +66,17 @@ void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ausf_ue = e->ausf_ue; ausf_ue = e->ausf_ue;
ogs_assert(ausf_ue); ogs_assert(ausf_ue);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case AUSF_EVT_SBI_SERVER: case OGS_EVENT_SBI_SERVER:
message = e->sbi.message; message = e->h.sbi.message;
ogs_assert(message); ogs_assert(message);
stream = e->sbi.data; stream = e->h.sbi.data;
ogs_assert(stream); ogs_assert(stream);
SWITCH(message->h.method) SWITCH(message->h.method)
@ -109,13 +109,13 @@ void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e)
break; break;
case AUSF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
message = e->sbi.message; message = e->h.sbi.message;
ogs_assert(message); ogs_assert(message);
ausf_ue = e->ausf_ue; ausf_ue = e->ausf_ue;
ogs_assert(ausf_ue); ogs_assert(ausf_ue);
stream = e->sbi.data; stream = e->h.sbi.data;
ogs_assert(stream); ogs_assert(stream);
SWITCH(message->h.service.name) SWITCH(message->h.service.name)
@ -178,7 +178,7 @@ void ausf_ue_state_exception(ogs_fsm_t *s, ausf_event_t *e)
ausf_ue = e->ausf_ue; ausf_ue = e->ausf_ue;
ogs_assert(ausf_ue); ogs_assert(ausf_ue);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -56,17 +56,17 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
ogs_assert(s); ogs_assert(s);
switch (e->id) { switch (e->h.id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
case BSF_EVT_SBI_SERVER: case OGS_EVENT_SBI_SERVER:
request = e->sbi.request; request = e->h.sbi.request;
ogs_assert(request); ogs_assert(request);
stream = e->sbi.data; stream = e->h.sbi.data;
ogs_assert(stream); ogs_assert(stream);
rv = ogs_sbi_parse_request(&message, request); rv = ogs_sbi_parse_request(&message, request);
@ -97,7 +97,7 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY) CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
SWITCH(message.h.method) SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST) CASE(OGS_SBI_HTTP_METHOD_POST)
bsf_nnrf_handle_nf_status_notify(stream, &message); ogs_nnrf_handle_nf_status_notify(stream, &message);
break; break;
DEFAULT DEFAULT
@ -195,10 +195,10 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
ogs_sbi_message_free(&message); ogs_sbi_message_free(&message);
break; break;
case BSF_EVT_SBI_CLIENT: case OGS_EVENT_SBI_CLIENT:
ogs_assert(e); ogs_assert(e);
response = e->sbi.response; response = e->h.sbi.response;
ogs_assert(response); ogs_assert(response);
rv = ogs_sbi_parse_response(&message, response); rv = ogs_sbi_parse_response(&message, response);
if (rv != OGS_OK) { if (rv != OGS_OK) {
@ -220,23 +220,23 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
SWITCH(message.h.resource.component[0]) SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES) CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data; nf_instance = e->h.sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &message; e->h.sbi.message = &message;
ogs_fsm_dispatch(&nf_instance->sm, e); ogs_fsm_dispatch(&nf_instance->sm, e);
break; break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS) CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data; subscription = e->h.sbi.data;
ogs_assert(subscription); ogs_assert(subscription);
SWITCH(message.h.method) SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST) CASE(OGS_SBI_HTTP_METHOD_POST)
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED || if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
message.res_status == OGS_SBI_HTTP_STATUS_OK) { message.res_status == OGS_SBI_HTTP_STATUS_OK) {
bsf_nnrf_handle_nf_status_subscribe( ogs_nnrf_handle_nf_status_subscribe(
subscription, &message); subscription, &message);
} else { } else {
ogs_error("HTTP response error : %d", ogs_error("HTTP response error : %d",
@ -269,7 +269,7 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC) CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
SWITCH(message.h.resource.component[0]) SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES) CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
SWITCH(message.h.method) SWITCH(message.h.method)
@ -303,27 +303,27 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
ogs_sbi_response_free(response); ogs_sbi_response_free(response);
break; break;
case BSF_EVT_SBI_TIMER: case OGS_EVENT_SBI_TIMER:
ogs_assert(e); ogs_assert(e);
switch(e->timer_id) { switch(e->h.timer_id) {
case BSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL: case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case BSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL: case OGS_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case BSF_TIMER_NF_INSTANCE_NO_HEARTBEAT: case OGS_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case BSF_TIMER_NF_INSTANCE_VALIDITY: case OGS_TIMER_NF_INSTANCE_VALIDITY:
nf_instance = e->sbi.data; nf_instance = e->h.sbi.data;
ogs_assert(nf_instance); ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
ogs_fsm_dispatch(&nf_instance->sm, e); ogs_fsm_dispatch(&nf_instance->sm, e);
if (OGS_FSM_CHECK(&nf_instance->sm, bsf_nf_state_exception)) if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception))
ogs_error("[%s:%s] State machine exception [%d]", ogs_error("[%s:%s] State machine exception [%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type), OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id, e->timer_id); nf_instance->id, e->h.timer_id);
break; break;
case BSF_TIMER_SUBSCRIPTION_VALIDITY: case OGS_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data; subscription = e->h.sbi.data;
ogs_assert(subscription); ogs_assert(subscription);
ogs_assert(ogs_sbi_self()->nf_instance); ogs_assert(ogs_sbi_self()->nf_instance);
@ -337,8 +337,8 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
ogs_sbi_subscription_remove(subscription); ogs_sbi_subscription_remove(subscription);
break; break;
case BSF_TIMER_SBI_CLIENT_WAIT: case OGS_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data; sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact); ogs_assert(sbi_xact);
stream = sbi_xact->assoc_stream; stream = sbi_xact->assoc_stream;
@ -358,7 +358,7 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
default: default:
ogs_error("Unknown timer[%s:%d]", ogs_error("Unknown timer[%s:%d]",
bsf_timer_get_name(e->timer_id), e->timer_id); ogs_timer_get_name(e->h.timer_id), e->h.timer_id);
} }
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -31,16 +31,6 @@ void bsf_state_final(ogs_fsm_t *s, bsf_event_t *e);
void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e); void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e);
void bsf_state_exception(ogs_fsm_t *s, bsf_event_t *e); void bsf_state_exception(ogs_fsm_t *s, bsf_event_t *e);
void bsf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance);
void bsf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance);
void bsf_nf_state_initial(ogs_fsm_t *s, bsf_event_t *e);
void bsf_nf_state_final(ogs_fsm_t *s, bsf_event_t *e);
void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e);
void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e);
void bsf_nf_state_de_registered(ogs_fsm_t *s, bsf_event_t *e);
void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e);
#define bsf_sm_debug(__pe) \ #define bsf_sm_debug(__pe) \
ogs_debug("%s(): %s", __func__, bsf_event_get_name(__pe)) ogs_debug("%s(): %s", __func__, bsf_event_get_name(__pe))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -23,7 +23,6 @@
#include "ogs-sbi.h" #include "ogs-sbi.h"
#include "ogs-app.h" #include "ogs-app.h"
#include "timer.h"
#include "bsf-sm.h" #include "bsf-sm.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -42,22 +41,6 @@ typedef struct bsf_context_s {
ogs_list_t sess_list; ogs_list_t sess_list;
} bsf_context_t; } bsf_context_t;
#define BSF_NF_INSTANCE_CLEAR(_cAUSE, _nFInstance) \
do { \
ogs_assert(_nFInstance); \
if ((_nFInstance)->reference_count == 1) { \
ogs_info("[%s] (%s) NF removed", (_nFInstance)->id, (_cAUSE)); \
bsf_nf_fsm_fini((_nFInstance)); \
ogs_sbi_nf_instance_remove(_nFInstance); \
} else { \
/* There is an assocation with other context */ \
ogs_info("[%s:%d] (%s) NF suspended", \
_nFInstance->id, _nFInstance->reference_count, (_cAUSE)); \
OGS_FSM_TRAN(&_nFInstance->sm, bsf_nf_state_de_registered); \
ogs_fsm_dispatch(&_nFInstance->sm, NULL); \
} \
} while(0)
typedef struct bsf_sess_s bsf_sess_t; typedef struct bsf_sess_s bsf_sess_t;
typedef struct bsf_sess_s { typedef struct bsf_sess_s {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -18,60 +18,42 @@
*/ */
#include "event.h" #include "event.h"
#include "context.h"
static OGS_POOL(pool, bsf_event_t); bsf_event_t *bsf_event_new(int id)
void bsf_event_init(void)
{
ogs_pool_init(&pool, ogs_app()->pool.event);
}
void bsf_event_final(void)
{
ogs_pool_final(&pool);
}
bsf_event_t *bsf_event_new(bsf_event_e id)
{ {
bsf_event_t *e = NULL; bsf_event_t *e = NULL;
ogs_pool_alloc(&pool, &e); e = ogs_event_size(id, sizeof(bsf_event_t));
ogs_assert(e); ogs_assert(e);
memset(e, 0, sizeof(*e));
e->id = id; e->h.id = id;
return e; return e;
} }
void bsf_event_free(bsf_event_t *e)
{
ogs_assert(e);
ogs_pool_free(&pool, e);
}
const char *bsf_event_get_name(bsf_event_t *e) const char *bsf_event_get_name(bsf_event_t *e)
{ {
if (e == NULL) if (e == NULL) {
return OGS_FSM_NAME_INIT_SIG; return OGS_FSM_NAME_INIT_SIG;
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case BSF_EVT_SBI_SERVER:
return "BSF_EVT_SBI_SERVER";
case BSF_EVT_SBI_CLIENT:
return "BSF_EVT_SBI_CLIENT";
case BSF_EVT_SBI_TIMER:
return "BSF_EVT_SBI_TIMER";
default:
break;
} }
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
return OGS_FSM_NAME_ENTRY_SIG;
case OGS_FSM_EXIT_SIG:
return OGS_FSM_NAME_EXIT_SIG;
case OGS_EVENT_SBI_SERVER:
return OGS_EVENT_NAME_SBI_SERVER;
case OGS_EVENT_SBI_CLIENT:
return OGS_EVENT_NAME_SBI_CLIENT;
case OGS_EVENT_SBI_TIMER:
return OGS_EVENT_NAME_SBI_TIMER;
default:
break;
}
ogs_error("Unknown Event[%d]", e->h.id);
return "UNKNOWN_EVENT"; return "UNKNOWN_EVENT";
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -20,51 +20,20 @@
#ifndef BSF_EVENT_H #ifndef BSF_EVENT_H
#define BSF_EVENT_H #define BSF_EVENT_H
#include "ogs-core.h" #include "ogs-proto.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct bsf_sess_s bsf_sess_t; typedef struct bsf_sess_s bsf_sess_t;
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
typedef struct ogs_sbi_response_s ogs_sbi_response_t;
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
typedef struct ogs_sbi_subscription_s ogs_sbi_subscription_t;
typedef enum {
BSF_EVT_BASE = OGS_FSM_USER_SIG,
BSF_EVT_SBI_SERVER,
BSF_EVT_SBI_CLIENT,
BSF_EVT_SBI_TIMER,
BSF_EVT_TOP,
} bsf_event_e;
typedef struct bsf_event_s { typedef struct bsf_event_s {
int id; ogs_event_t h;
ogs_pkbuf_t *pkbuf;
int timer_id;
struct {
ogs_sbi_request_t *request;
ogs_sbi_response_t *response;
void *data;
int state;
ogs_sbi_message_t *message;
} sbi;
bsf_sess_t *sess; bsf_sess_t *sess;
} bsf_event_t; } bsf_event_t;
void bsf_event_init(void); bsf_event_t *bsf_event_new(int id);
void bsf_event_final(void);
bsf_event_t *bsf_event_new(bsf_event_e id);
void bsf_event_free(bsf_event_t *e);
const char *bsf_event_get_name(bsf_event_t *e); const char *bsf_event_get_name(bsf_event_t *e);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> * Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* *
* This file is part of Open5GS. * This file is part of Open5GS.
* *
@ -32,7 +32,6 @@ int bsf_initialize()
ogs_sbi_context_init(); ogs_sbi_context_init();
bsf_context_init(); bsf_context_init();
bsf_event_init();
rv = ogs_sbi_context_parse_config("bsf", "nrf", "scp"); rv = ogs_sbi_context_parse_config("bsf", "nrf", "scp");
if (rv != OGS_OK) return rv; if (rv != OGS_OK) return rv;
@ -63,7 +62,7 @@ static void event_termination(void)
/* Sending NF Instance De-registeration to NRF */ /* Sending NF Instance De-registeration to NRF */
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
bsf_nf_fsm_fini(nf_instance); ogs_sbi_nf_fsm_fini(nf_instance);
/* Starting holding timer */ /* Starting holding timer */
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL); t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
@ -90,8 +89,6 @@ void bsf_terminate(void)
bsf_context_final(); bsf_context_final();
ogs_sbi_context_final(); ogs_sbi_context_final();
bsf_event_final(); /* Destroy event */
} }
static void bsf_main(void *data) static void bsf_main(void *data)
@ -99,8 +96,7 @@ static void bsf_main(void *data)
ogs_fsm_t bsf_sm; ogs_fsm_t bsf_sm;
int rv; int rv;
ogs_fsm_create(&bsf_sm, bsf_state_initial, bsf_state_final); ogs_fsm_init(&bsf_sm, bsf_state_initial, bsf_state_final, 0);
ogs_fsm_init(&bsf_sm, 0);
for ( ;; ) { for ( ;; ) {
ogs_pollset_poll(ogs_app()->pollset, ogs_pollset_poll(ogs_app()->pollset,
@ -133,11 +129,10 @@ static void bsf_main(void *data)
ogs_assert(e); ogs_assert(e);
ogs_fsm_dispatch(&bsf_sm, e); ogs_fsm_dispatch(&bsf_sm, e);
bsf_event_free(e); ogs_event_free(e);
} }
} }
done: done:
ogs_fsm_fini(&bsf_sm, 0); ogs_fsm_fini(&bsf_sm, 0);
ogs_fsm_delete(&bsf_sm);
} }

View File

@ -1,4 +1,4 @@
# Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com> # Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
# This file is part of Open5GS. # This file is part of Open5GS.
@ -18,12 +18,8 @@
libbsf_sources = files(''' libbsf_sources = files('''
context.c context.c
event.c event.c
timer.c
nnrf-build.c
nnrf-handler.c nnrf-handler.c
nf-sm.c
nbsf-handler.c nbsf-handler.c
sbi-path.c sbi-path.c

View File

@ -34,10 +34,6 @@ bool bsf_nbsf_management_handle_pcf_binding(
OpenAPI_pcf_binding_t *RecvPcfBinding = NULL; OpenAPI_pcf_binding_t *RecvPcfBinding = NULL;
OpenAPI_pcf_binding_t SendPcfBinding; OpenAPI_pcf_binding_t SendPcfBinding;
OpenAPI_snssai_t Snssai; OpenAPI_snssai_t Snssai;
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
char fqdn[OGS_MAX_FQDN_LEN+1];
int fqdn_len;
#endif
ogs_assert(stream); ogs_assert(stream);
ogs_assert(recvmsg); ogs_assert(recvmsg);
@ -103,22 +99,10 @@ bool bsf_nbsf_management_handle_pcf_binding(
bsf_sess_set_ipv6prefix(sess, RecvPcfBinding->ipv6_prefix); bsf_sess_set_ipv6prefix(sess, RecvPcfBinding->ipv6_prefix);
if (RecvPcfBinding->pcf_fqdn) { if (RecvPcfBinding->pcf_fqdn) {
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
ogs_assert(0 < ogs_fqdn_parse(
fqdn, RecvPcfBinding->pcf_fqdn,
ogs_min(strlen(RecvPcfBinding->pcf_fqdn),
OGS_MAX_FQDN_LEN)));
if (sess->pcf_fqdn)
ogs_free(sess->pcf_fqdn);
sess->pcf_fqdn = ogs_strdup(fqdn);
ogs_assert(sess->pcf_fqdn);
#else
if (sess->pcf_fqdn) if (sess->pcf_fqdn)
ogs_free(sess->pcf_fqdn); ogs_free(sess->pcf_fqdn);
sess->pcf_fqdn = ogs_strdup(RecvPcfBinding->pcf_fqdn); sess->pcf_fqdn = ogs_strdup(RecvPcfBinding->pcf_fqdn);
ogs_assert(sess->pcf_fqdn); ogs_assert(sess->pcf_fqdn);
#endif
} }
PcfIpEndPointList = RecvPcfBinding->pcf_ip_end_points; PcfIpEndPointList = RecvPcfBinding->pcf_ip_end_points;
@ -232,18 +216,8 @@ bool bsf_nbsf_management_handle_pcf_binding(
PcfIpEndPointList = OpenAPI_list_create(); PcfIpEndPointList = OpenAPI_list_create();
ogs_assert(PcfIpEndPointList); ogs_assert(PcfIpEndPointList);
if (sess->pcf_fqdn && strlen(sess->pcf_fqdn)) { if (sess->pcf_fqdn && strlen(sess->pcf_fqdn))
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
memset(fqdn, 0, sizeof(fqdn));
fqdn_len = ogs_fqdn_build(fqdn,
sess->pcf_fqdn, strlen(sess->pcf_fqdn));
SendPcfBinding.pcf_fqdn = ogs_memdup(fqdn, fqdn_len+1);
ogs_assert(SendPcfBinding.pcf_fqdn);
SendPcfBinding.pcf_fqdn[fqdn_len] = 0;
#else
SendPcfBinding.pcf_fqdn = ogs_strdup(sess->pcf_fqdn); SendPcfBinding.pcf_fqdn = ogs_strdup(sess->pcf_fqdn);
#endif
}
for (i = 0; i < sess->num_of_pcf_ip; i++) { for (i = 0; i < sess->num_of_pcf_ip; i++) {
OpenAPI_ip_end_point_t *PcfIpEndPoint = NULL; OpenAPI_ip_end_point_t *PcfIpEndPoint = NULL;

Some files were not shown because too many files have changed in this diff Show More