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,
c_args : '-DOGS_APP_COMPILATION',
include_directories : [libapp_inc, libinc],
dependencies : [libcore_dep, yaml_dep],
dependencies : [libproto_dep, yaml_dep],
install : true)
libapp_dep = declare_dependency(
link_with : libapp,
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
#define OGS_APP_H
#include "ogs-core.h"
#include "ogs-proto.h"
#define OGS_APP_INSIDE

View File

@ -170,16 +170,6 @@ static void app_context_prepare(void)
#define USRSCTP_LOCAL_UDP_PORT 9899
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;
#define MAX_NUM_OF_UE 1024 /* Num of UEs */
@ -379,48 +369,6 @@ int ogs_app_context_parse_config(void)
} else
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")) {
ogs_yaml_iter_t 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;
} 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 {
int udp_port;
} usrsctp;

View File

@ -40,7 +40,7 @@ int get_asn1c_environment_version(void); /* Run-time version */
#define REALLOC(oldptr, size) realloc(oldptr, size)
#define FREEMEM(ptr) free(ptr)
#else
#include "ogs-core.h"
#include "ogs-proto.h"
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,
c_args : libasn1c_common_cc_flags,
include_directories : libasn1c_common_inc,
dependencies : libcore_dep,
dependencies : libproto_dep,
install : true)
libasn1c_common_dep = declare_dependency(
link_with : libasn1c_common,
include_directories : libasn1c_common_inc,
dependencies : libcore_dep)
dependencies : libproto_dep)

View File

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

View File

@ -232,25 +232,3 @@ uint64_t ogs_uint64_from_string(char *str)
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);
uint64_t ogs_uint64_from_string(char *str);
void ogs_extract_digit_from_string(char *digit, char *string);
#ifdef __cplusplus
}
#endif

View File

@ -62,7 +62,6 @@
#include "core/ogs-hash.h"
#include "core/ogs-misc.h"
#include "core/ogs-getopt.h"
#include "core/ogs-3gpp-types.h"
#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_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;
fsm_event_t *e = event;
ogs_assert(s);
ogs_assert(sm);
ogs_assert(state);
if (s->init != NULL) {
(*s->init)(s, e);
if (s->init != s->state) {
if (e) {
e->id = OGS_FSM_ENTRY_SIG;
(*s->state)(s, e);
} else {
(*s->state)(s, &entry_event);
}
if (e) {
e->id = OGS_FSM_ENTRY_SIG;
(*state)(sm, e);
} else {
(*state)(sm, &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;
ogs_assert(s);
ogs_fsm_handler_t tmp = s->state;
ogs_fsm_handler_t tmp = NULL;
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)
(*tmp)(s, e);
(*tmp)(sm, e);
if (s->state != tmp) {
if (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);
}
}
if (sm->state != tmp)
fsm_change(fsm, tmp, sm->state, e);
}
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;
ogs_assert(s);
if (s->fini != s->state) {
if (e) {
e->id = OGS_FSM_EXIT_SIG;
(*s->state)(s, e);
} else {
(*s->state)(s, &exit_event);
}
ogs_assert(sm);
if (sm->fini != sm->state) {
ogs_assert(sm->state);
fsm_exit(sm, sm->state, e);
if (sm->fini)
(*sm->fini)(sm, e);
}
if (s->fini != NULL) {
(*s->fini)(s, e);
}
s->state = s->init;
sm->init = sm->state = sm->fini = NULL;
}

View File

@ -46,16 +46,10 @@ typedef struct _ogs_fsm_t {
ogs_fsm_handler_t state;
} ogs_fsm_t;
#define ogs_fsm_create(__s, __i, __f) \
(((__s)->init = (__s)->state = (ogs_fsm_handler_t)(__i)), \
(__s)->fini = (ogs_fsm_handler_t)(__f))
#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);
void ogs_fsm_init(void *fsm, void *init, void *fini, void *event);
void ogs_fsm_tran(void *fsm, void *state, void *event);
void ogs_fsm_dispatch(void *fsm, void *event);
void ogs_fsm_fini(void *fsm, void *event);
#define OGS_FSM_TRAN(__s, __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_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
}
#endif

View File

@ -245,7 +245,7 @@ ogs_pkbuf_t *ogs_pkbuf_alloc_debug(
}
memset(pkbuf, 0, sizeof(*pkbuf));
cluster->ref++;
OGS_OBJECT_REF(cluster);
pkbuf->cluster = cluster;
@ -283,8 +283,9 @@ void ogs_pkbuf_free(ogs_pkbuf_t *pkbuf)
cluster = pkbuf->cluster;
ogs_assert(cluster);
cluster->ref--;
if (cluster->ref == 0)
if (OGS_OBJECT_IS_REF(cluster))
OGS_OBJECT_UNREF(cluster);
else
cluster_free(pool, pkbuf->cluster);
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);
memcpy(newbuf, pkbuf, sizeof *pkbuf);
newbuf->cluster->ref++;
OGS_OBJECT_REF(newbuf->cluster);
ogs_thread_mutex_unlock(&pool->mutex);
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -51,10 +51,10 @@ libdiameter_common = library('ogsdiameter-common',
version : libogslib_version,
c_args : libdiameter_common_cc_flags,
include_directories : [libdiameter_common_inc, libinc],
dependencies : [libcore_dep, libfdcore_dep],
dependencies : [libproto_dep, libfdcore_dep],
install : true)
libdiameter_common_dep = declare_dependency(
link_with : libdiameter_common,
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
#endif
#include "ogs-core.h"
#include "ogs-proto.h"
#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->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->tm_response = ogs_timer_add(

View File

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

View File

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

View File

@ -18,8 +18,9 @@
libinc = include_directories('.')
subdir('core')
subdir('ipfw')
subdir('proto')
subdir('crypt')
subdir('ipfw')
subdir('app')
subdir('metrics')
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.
*
@ -17,19 +17,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NSSF_NNRF_BUILD_H
#define NSSF_NNRF_BUILD_H
#include "ogs-proto.h"
#include "context.h"
void ogs_extract_digit_from_string(char *digit, char *string)
{
bool extracting = false;
int i = 0;
#ifdef __cplusplus
extern "C" {
#endif
ogs_assert(string);
ogs_assert(digit);
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.
*
@ -17,19 +17,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef AUSF_NNRF_BUILD_H
#define AUSF_NNRF_BUILD_H
#if !defined(OGS_PROTO_INSIDE) && !defined(OGS_PROTO_COMPILATION)
#error "This header cannot be included directly."
#endif
#include "context.h"
#ifndef OGS_PROTO_CONV_H
#define OGS_PROTO_CONV_H
#ifdef __cplusplus
extern "C" {
#endif
ogs_sbi_request_t *ausf_nnrf_nfm_build_register(void);
void ogs_extract_digit_from_string(char *digit, char *string);
#ifdef __cplusplus
}
#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/>.
*/
#ifndef SCP_NNRF_BUILD_H
#define SCP_NNRF_BUILD_H
#ifndef OGS_PROTO_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
extern "C" {
#endif
ogs_sbi_request_t *scp_nnrf_nfm_build_register(void);
#ifdef __cplusplus
}
#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.
*
@ -17,7 +17,7 @@
* 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_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.
*
@ -17,12 +17,12 @@
* 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."
#endif
#ifndef OGS_3GPP_TYPES_H
#define OGS_3GPP_TYPES_H
#ifndef OGS_PROTO_TYPES_H
#define OGS_PROTO_TYPES_H
#ifdef __cplusplus
extern "C" {
@ -107,8 +107,6 @@ extern "C" {
#define OGS_MAX_QOS_FLOW_ID 63
#define OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30
/************************************
* PLMN_ID Structure */
#define OGS_MAX_NUM_OF_PLMN 6
@ -778,4 +776,4 @@ int ogs_pcc_rule_update_qos_from_media(
}
#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);
memset(client, 0, sizeof(ogs_sbi_client_t));
client->reference_count++;
ogs_trace("ogs_sbi_client_add()");
ogs_debug("ogs_sbi_client_add()");
OGS_OBJECT_REF(client);
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)
{
ogs_sockaddr_t *addr = NULL;
char buf[OGS_ADDRSTRLEN];
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_assert(client->reference_count > 0);
ogs_trace("client->reference_count = %d", client->reference_count);
client->reference_count--;
if (client->reference_count > 0)
if (OGS_OBJECT_IS_REF(client)) {
OGS_OBJECT_UNREF(client);
return;
}
ogs_trace("ogs_sbi_client_remove()");
ogs_list_remove(&ogs_sbi_self()->client_list, client);
connection_remove_all(client);

View File

@ -47,10 +47,8 @@ extern "C" {
ogs_sbi_client_remove(client); \
} \
\
(__pClient)->reference_count++; \
OGS_OBJECT_REF(__pClient); \
((__cTX)->client) = (__pClient); \
ogs_trace("client->reference_count = %d", \
(__pClient)->reference_count); \
} while(0)
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/>.
*/
#include "app/ogs-app.h"
#include "ogs-app.h"
#include "ogs-sbi.h"
int __ogs_sbi_domain;
@ -727,6 +727,16 @@ int ogs_sbi_context_parse_config(
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)
{
int i;
@ -753,8 +763,9 @@ ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(void)
ogs_assert(nf_instance);
memset(nf_instance, 0, sizeof(ogs_sbi_nf_instance_t));
nf_instance->reference_count++;
ogs_trace("ogs_sbi_nf_instance_add()");
ogs_debug("ogs_sbi_nf_instance_add()");
OGS_OBJECT_REF(nf_instance);
nf_instance->time.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);
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;
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_trace("nf_instance->reference_count = %d",
nf_instance->reference_count);
nf_instance->reference_count--;
if (nf_instance->reference_count > 0)
return;
ogs_debug("ogs_sbi_nf_instance_remove()");
if (OGS_OBJECT_IS_REF(nf_instance)) {
OGS_OBJECT_UNREF(nf_instance);
return;
}
ogs_trace("ogs_sbi_nf_instance_remove()");
ogs_list_remove(&ogs_sbi_self()->nf_instance_list, nf_instance);
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);
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_assert(nf_service->versions[nf_service->num_of_version].in_uri);
nf_service->versions[nf_service->num_of_version].full =
ogs_assert(nf_service->version[nf_service->num_of_version].in_uri);
nf_service->version[nf_service->num_of_version].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) {
nf_service->versions[nf_service->num_of_version].expiry =
nf_service->version[nf_service->num_of_version].expiry =
ogs_strdup(expiry);
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++;
@ -978,12 +989,12 @@ void ogs_sbi_nf_service_clear(ogs_sbi_nf_service_t *nf_service)
ogs_free(nf_service->fqdn);
for (i = 0; i < nf_service->num_of_version; i++) {
if (nf_service->versions[i].in_uri)
ogs_free(nf_service->versions[i].in_uri);
if (nf_service->versions[i].full)
ogs_free(nf_service->versions[i].full);
if (nf_service->versions[i].expiry)
ogs_free(nf_service->versions[i].expiry);
if (nf_service->version[i].in_uri)
ogs_free(nf_service->version[i].in_uri);
if (nf_service->version[i].full)
ogs_free(nf_service->version[i].full);
if (nf_service->version[i].expiry)
ogs_free(nf_service->version[i].expiry);
}
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_assert(nf_instance);
ogs_assert(ogs_sbi_self()->nf_state_registered);
ogs_assert(target_nf_type);
if (!OGS_FSM_CHECK(&nf_instance->sm,
ogs_sbi_self()->nf_state_registered)) return false;
if (!OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_registered))
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->target_nf_instance_id &&
@ -1393,7 +1404,6 @@ void ogs_sbi_select_nf(
{
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(ogs_sbi_self()->nf_state_registered);
ogs_assert(sbi_object);
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_assert(nf_instance);
client = nf_instance_find_client(nf_instance);
if (!client) return false;
ogs_assert(client);
OGS_SBI_SETUP_CLIENT(nf_instance, client);
nf_service_associate_client_all(nf_instance);
return true;
}
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);
if (strcmp(nf_service->name, name) == 0) {
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;
}
}
@ -1476,7 +1484,6 @@ ogs_sbi_xact_t *ogs_sbi_xact_add(
{
ogs_sbi_xact_t *xact = NULL;
ogs_assert(ogs_sbi_self()->client_wait_expire);
ogs_assert(sbi_object);
ogs_pool_alloc(&xact_pool, &xact);
@ -1496,7 +1503,7 @@ ogs_sbi_xact_t *ogs_sbi_xact_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) {
ogs_error("ogs_timer_add() failed");
ogs_sbi_request_free(xact->request);

View File

@ -65,11 +65,12 @@ typedef struct ogs_sbi_context_s {
const char *content_encoding;
void (*client_wait_expire)(void *data);
ogs_fsm_handler_t nf_state_registered;
int num_of_service_name;
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;
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_validity; /* check validation */
#define NF_INSTANCE_IS_SELF(_iD) \
#define NF_INSTANCE_ID_IS_SELF(_iD) \
(_iD) && ogs_sbi_self()->nf_instance && \
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 && \
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)
char *id; /* NFInstanceId */
@ -110,9 +111,8 @@ typedef struct ogs_sbi_nf_instance_s {
int num_of_ipv6;
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;
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_CAPACITY 100
@ -188,7 +188,7 @@ typedef struct ogs_sbi_nf_service_s {
char *in_uri;
char *full;
char *expiry;
} versions[OGS_SBI_MAX_NUM_OF_SERVICE_VERSION];
} version[OGS_SBI_MAX_NUM_OF_SERVICE_VERSION];
char *fqdn;
int num_of_addr;
@ -273,6 +273,8 @@ ogs_sbi_context_t *ogs_sbi_self(void);
int ogs_sbi_context_parse_config(
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);
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_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);
@ -341,10 +343,8 @@ OpenAPI_uri_scheme_e ogs_sbi_default_uri_scheme(void);
OGS_SBI_NF_INSTANCE((__sBIObject), (__nFType))); \
} \
\
(__nFInstance)->reference_count++; \
OGS_OBJECT_REF(__nFInstance); \
OGS_SBI_NF_INSTANCE((__sBIObject), (__nFType)) = (__nFInstance); \
ogs_trace("nf_instance->reference_count = %d", \
(__nFInstance)->reference_count); \
} while(0)
bool ogs_sbi_discovery_param_is_matched(

View File

@ -28,6 +28,7 @@ libsbi_sources = files('''
yuarel.c
conv.c
timer.c
message.c
mhd-server.c
@ -39,8 +40,9 @@ libsbi_sources = files('''
nnrf-build.c
nnrf-handler.c
path.c
nf-sm.c
'''.split())
libsbi_inc = include_directories('.')
@ -57,8 +59,7 @@ libsbi = library('ogssbi',
version : libogslib_version,
c_args : sbi_cc_flags,
include_directories : [libsbi_inc, libinc],
dependencies : [libcore_dep,
libcrypt_dep,
dependencies : [libcrypt_dep,
libapp_dep,
libsbi_openapi_dep,
libgnutls_dep,
@ -71,8 +72,7 @@ libsbi = library('ogssbi',
libsbi_dep = declare_dependency(
link_with : libsbi,
include_directories : [libsbi_inc, libinc],
dependencies : [libcore_dep,
libcrypt_dep,
dependencies : [libcrypt_dep,
libapp_dep,
libsbi_openapi_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.
*
@ -17,28 +17,44 @@
* 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"
#include "nnrf-handler.h"
void bsf_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance)
void ogs_sbi_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);
memset(&e, 0, sizeof(e));
e.sbi.data = nf_instance;
ogs_fsm_create(&nf_instance->sm,
bsf_nf_state_initial, bsf_nf_state_final);
ogs_fsm_init(&nf_instance->sm, &e);
ogs_fsm_tran(&nf_instance->sm, state, &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);
@ -46,50 +62,49 @@ void bsf_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance)
e.sbi.data = nf_instance;
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_assert(s);
ogs_assert(e);
bsf_sm_debug(e);
ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
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);
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);
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);
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);
if (NF_INSTANCE_IS_NRF(nf_instance)) {
OGS_FSM_TRAN(s, &bsf_nf_state_will_register);
if (NF_INSTANCE_TYPE_IS_NRF(nf_instance)) {
OGS_FSM_TRAN(s, &ogs_sbi_nf_state_will_register);
} else {
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_assert(s);
ogs_assert(e);
bsf_sm_debug(e);
ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data;
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);
}
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_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(e);
bsf_sm_debug(e);
ogs_sbi_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));
ogs_assert(NF_INSTANCE_TYPE_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, bsf_nnrf_nfm_build_register));
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(nf_instance));
break;
case OGS_FSM_EXIT_SIG:
ogs_timer_stop(nf_instance->t_registration_interval);
break;
case BSF_EVT_SBI_CLIENT:
case OGS_EVENT_SBI_CLIENT:
message = e->sbi.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 ||
message->res_status == OGS_SBI_HTTP_STATUS_CREATED) {
bsf_nnrf_handle_nf_register(nf_instance, message);
OGS_FSM_TRAN(s, &bsf_nf_state_registered);
ogs_sbi_nnrf_handle_nf_register(nf_instance, message);
OGS_FSM_TRAN(s, &ogs_sbi_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, &bsf_nf_state_exception);
OGS_FSM_TRAN(s, &ogs_sbi_nf_state_exception);
}
break;
@ -165,9 +179,9 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
END
break;
case BSF_EVT_SBI_TIMER:
case OGS_EVENT_SBI_TIMER:
switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client;
ogs_assert(client);
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_app()->time.message.sbi.nf_register_interval);
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
nf_instance, bsf_nnrf_nfm_build_register));
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(nf_instance));
break;
default:
ogs_error("[%s] Unknown timer[%s:%d]",
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;
default:
ogs_error("[%s] Unknown event %s",
ogs_sbi_self()->nf_instance->id, bsf_event_get_name(e));
ogs_error("Unknown event %s", ogs_event_get_name(e));
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_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(e);
bsf_sm_debug(e);
ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
@ -213,7 +225,9 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
switch (e->id) {
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_sbi_self()->nf_instance->id,
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 +
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;
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);
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);
}
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_nnrf_nfm_send_nf_de_register(nf_instance));
ogs_nnrf_nfm_send_nf_de_register(nf_instance));
}
}
break;
case BSF_EVT_SBI_CLIENT:
case OGS_EVENT_SBI_CLIENT:
message = e->sbi.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_sbi_self()->nf_instance->id,
message->res_status);
OGS_FSM_TRAN(s, &bsf_nf_state_exception);
OGS_FSM_TRAN(s, &ogs_sbi_nf_state_exception);
}
break;
@ -289,9 +311,9 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
END
break;
case BSF_EVT_SBI_TIMER:
case OGS_EVENT_SBI_TIMER:
switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case OGS_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));
@ -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));
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_FSM_TRAN(s, &bsf_nf_state_will_register);
OGS_FSM_TRAN(s, &ogs_sbi_nf_state_will_register);
break;
case BSF_TIMER_NF_INSTANCE_VALIDITY:
ogs_assert(!NF_INSTANCE_IS_NRF(nf_instance));
case OGS_TIMER_NF_INSTANCE_VALIDITY:
ogs_assert(!NF_INSTANCE_TYPE_IS_NRF(nf_instance));
ogs_assert(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;
default:
ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
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;
@ -324,18 +346,18 @@ void bsf_nf_state_registered(ogs_fsm_t *s, bsf_event_t *e)
ogs_error("[%s:%s] Unknown event %s",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
bsf_event_get_name(e));
ogs_event_get_name(e));
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_assert(s);
ogs_assert(e);
bsf_sm_debug(e);
ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data;
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) {
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);
}
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",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
bsf_event_get_name(e));
ogs_event_get_name(e));
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_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(e);
bsf_sm_debug(e);
ogs_sbi_sm_debug(e);
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
@ -377,7 +399,7 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
switch (e->id) {
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_app()->time.message.sbi.
nf_register_interval_in_exception);
@ -385,14 +407,14 @@ void bsf_nf_state_exception(ogs_fsm_t *s, bsf_event_t *e)
break;
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);
}
break;
case BSF_EVT_SBI_TIMER:
case OGS_EVENT_SBI_TIMER:
switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case OGS_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
client = nf_instance->client;
ogs_assert(client);
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_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;
default:
ogs_error("[%s:%s] Unknown timer[%s:%d]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
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;
case BSF_EVT_SBI_CLIENT:
case OGS_EVENT_SBI_CLIENT:
message = e->sbi.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",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id ? nf_instance->id : "Undefined",
bsf_event_get_name(e));
ogs_event_get_name(e));
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;
int i = 0;
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
int fqdn_len;
char fqdn[OGS_MAX_FQDN_LEN];
#endif
char *ipstr = NULL;
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->nf_profile_changes_support_ind = true;
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
if (nf_instance->fqdn)
NFProfile->fqdn = ogs_strdup(nf_instance->fqdn);
#endif
}
NFProfile->is_priority = true;
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++) {
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)
@ -163,21 +144,21 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
NFServiceVersion = ogs_calloc(1, sizeof(*NFServiceVersion));
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 =
ogs_strdup(nf_service->versions[i].in_uri);
ogs_strdup(nf_service->version[i].in_uri);
ogs_expect_or_return_val(
NFServiceVersion->api_version_in_uri, NULL);
}
if (nf_service->versions[i].full) {
if (nf_service->version[i].full) {
NFServiceVersion->api_full_version =
ogs_strdup(nf_service->versions[i].full);
ogs_strdup(nf_service->version[i].full);
ogs_expect_or_return_val(
NFServiceVersion->api_full_version, NULL);
}
if (nf_service->versions[i].expiry) {
if (nf_service->version[i].expiry) {
NFServiceVersion->expiry =
ogs_strdup(nf_service->versions[i].expiry);
ogs_strdup(nf_service->version[i].expiry);
ogs_expect_or_return_val(
NFServiceVersion->expiry, NULL);
}
@ -191,22 +172,8 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(void)
NFService->scheme = nf_service->scheme;
NFService->nf_service_status = nf_service->status;
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
if (nf_service->fqdn)
NFService->fqdn = ogs_strdup(nf_service->fqdn);
#endif
}
IpEndPointList = OpenAPI_list_create();
ogs_assert(IpEndPointList);
@ -333,6 +300,284 @@ void ogs_sbi_nnrf_free_nf_profile(OpenAPI_nf_profile_t *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_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);
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_de_register(void);

View File

@ -20,6 +20,245 @@
#include "ogs-sbi.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(
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,
OpenAPI_nf_profile_t *NFProfile,
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)
{
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;
OpenAPI_lnode_t *node;
ogs_sbi_nf_service_t *nf_service = NULL, *next_nf_service = NULL;
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
char fqdn[OGS_MAX_FQDN_LEN+1];
#endif
ogs_sbi_response_t *response = NULL;
OpenAPI_notification_data_t *NotificationData = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_assert(nf_instance);
ogs_assert(NFProfile);
ogs_sbi_message_t message;
ogs_sbi_header_t header;
if (!NFProfile) {
ogs_error("No NFProfile");
if (stream)
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No NFProfile", NULL));
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 (!NFProfile->nf_instance_id) {
ogs_error("No NFProfile.NFInstanceId");
if (stream)
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "NFProfile", "No NFInstanceId"));
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;
}
if (!NFProfile->nf_type) {
ogs_error("No NFProfile.NFType");
if (stream)
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "NFProfile", "No NFType"));
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 (!NFProfile->nf_status) {
ogs_error("No NFProfile.NFStatus");
if (stream)
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "NFProfile", "No NFStatus"));
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;
}
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);
}
if (NF_INSTANCE_ID_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;
}
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 (NotificationData->event ==
OpenAPI_notification_event_type_NF_REGISTERED) {
if (NFProfile->fqdn) {
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
if (ogs_fqdn_parse(
fqdn, NFProfile->fqdn,
ogs_min(strlen(NFProfile->fqdn), OGS_MAX_FQDN_LEN)) > 0) {
OpenAPI_nf_profile_t *NFProfile = NULL;
/* Nothing : succeeded to parse FQDN */
nf_instance->fqdn = ogs_strdup(fqdn);
ogs_assert(nf_instance);
} else {
ogs_error("ogs_fqdn_parse() failed[%s]", NFProfile->fqdn);
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;
}
#else
nf_instance->fqdn = ogs_strdup(NFProfile->fqdn);
#endif
}
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);
if (!NFProfile->nf_instance_id) {
ogs_error("No NFProfile.NFInstanceId");
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NFProfile.NFInstanceId", NULL));
ogs_sbi_header_free(&header);
return false;
}
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 (!NFProfile->nf_type) {
ogs_error("No NFProfile.NFType");
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No NFProfile.NFType", NULL));
ogs_sbi_header_free(&header);
return false;
}
if (NFService->fqdn) {
#if SBI_FQDN_WITH_ONE_OCTET_LENGTH
if (ogs_fqdn_parse(
fqdn, NFService->fqdn,
ogs_min(strlen(NFService->fqdn), OGS_MAX_FQDN_LEN)) > 0) {
if (!NFProfile->nf_status) {
ogs_error("No NFProfile.NFStatus");
ogs_assert(true ==
ogs_sbi_server_send_error(
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_service->fqdn = ogs_strdup(fqdn);
ogs_assert(nf_service);
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]);
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 {
ogs_error("ogs_fqdn_parse() failed[%s]", NFService->fqdn);
return false;
ogs_info("[%s] NF removed", nf_instance->id);
ogs_sbi_nf_fsm_fini((nf_instance));
ogs_sbi_nf_instance_remove(nf_instance);
}
#else
nf_service->fqdn = ogs_strdup(NFService->fqdn);
ogs_assert(nf_service);
#endif
} 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;
}
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;
} 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;
}
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);
}
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 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" {
#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,
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
}
#endif

View File

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

View File

@ -124,8 +124,7 @@ bool ogs_sbi_discover_and_send(
return false;
}
bool ogs_nnrf_nfm_send_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_request_t *(*build)(void))
bool ogs_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
{
ogs_sbi_request_t *request = NULL;
ogs_sbi_client_t *client = NULL;
@ -133,9 +132,8 @@ bool ogs_nnrf_nfm_send_nf_register(
ogs_assert(nf_instance);
client = nf_instance->client;
ogs_assert(client);
ogs_assert(build);
request = (*build)();
request = ogs_nnrf_nfm_build_register();
ogs_expect_or_return_val(request, false);
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_client_cb_f client_cb, void *data);
bool ogs_nnrf_nfm_send_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_request_t *(*build)(void));
bool ogs_nnrf_nfm_send_nf_register(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_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.
*
@ -17,25 +17,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef NSSF_NNRF_HANDLER_H
#define NSSF_NNRF_HANDLER_H
#if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
#error "This header cannot be included directly."
#endif
#include "context.h"
#ifndef OGS_SBI_TIMER_H
#define OGS_SBI_TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
void nssf_nnrf_handle_nf_register(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg);
void nssf_nnrf_handle_nf_status_subscribe(
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg);
bool nssf_nnrf_handle_nf_status_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
void ogs_timer_nf_instance_registration_interval(void *data);
void ogs_timer_nf_instance_heartbeat_interval(void *data);
void ogs_timer_nf_instance_no_heartbeat(void *data);
void ogs_timer_nf_instance_validity(void *data);
void ogs_timer_subscription_validity(void *data);
void ogs_timer_sbi_client_wait_expire(void *data);
#ifdef __cplusplus
}
#endif
#endif /* NSSF_NNRF_HANDLER_H */
#endif /* OGS_SBI_TIMER_H */

View File

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

View File

@ -20,7 +20,7 @@
#ifndef OGS_TUN_H
#define OGS_TUN_H
#include "ogs-core.h"
#include "ogs-proto.h"
#ifdef __cplusplus
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.
*
@ -79,17 +79,17 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(s);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AMF_EVT_SBI_SERVER:
sbi_request = e->sbi.request;
case OGS_EVENT_SBI_SERVER:
sbi_request = e->h.sbi.request;
ogs_assert(sbi_request);
stream = e->sbi.data;
stream = e->h.sbi.data;
ogs_assert(stream);
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)
SWITCH(sbi_message.h.method)
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;
DEFAULT
@ -240,10 +240,10 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_message_free(&sbi_message);
break;
case AMF_EVT_SBI_CLIENT:
case OGS_EVENT_SBI_CLIENT:
ogs_assert(e);
sbi_response = e->sbi.response;
sbi_response = e->h.sbi.response;
ogs_assert(sbi_response);
rv = ogs_sbi_parse_response(&sbi_message, sbi_response);
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])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data;
nf_instance = e->h.sbi.data;
ogs_assert(nf_instance);
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);
break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data;
subscription = e->h.sbi.data;
ogs_assert(subscription);
SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK) {
amf_nnrf_handle_nf_status_subscribe(
ogs_nnrf_handle_nf_status_subscribe(
subscription, &sbi_message);
} else {
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)
SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
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_SDM)
CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(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));
e->amf_ue = amf_ue;
e->sbi.message = &sbi_message;;
e->h.sbi.message = &sbi_message;;
ogs_fsm_dispatch(&amf_ue->sm, e);
} else {
@ -385,7 +385,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(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->sess = sess;
e->sbi.message = &sbi_message;;
e->h.sbi.message = &sbi_message;;
SWITCH(sbi_message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
@ -502,7 +502,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break;
CASE(OGS_SBI_SERVICE_NAME_NNSSF_NSSELECTION)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(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->sess = sess;
e->sbi.message = &sbi_message;;
e->h.sbi.message = &sbi_message;;
amf_nnssf_nsselection_handle_get(sess, &sbi_message);
break;
@ -549,27 +549,27 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_response_free(sbi_response);
break;
case AMF_EVT_SBI_TIMER:
case OGS_EVENT_SBI_TIMER:
ogs_assert(e);
switch(e->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:
nf_instance = e->sbi.data;
switch(e->h.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:
nf_instance = e->h.sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
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]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id, e->timer_id);
nf_instance->id, e->h.timer_id);
break;
case AMF_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data;
case OGS_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->h.sbi.data;
ogs_assert(subscription);
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);
break;
case AMF_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data;
case OGS_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
sbi_object = sbi_xact->sbi_object;
@ -647,11 +647,11 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
default:
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;
case AMF_EVT_NGAP_LO_ACCEPT:
case AMF_EVENT_NGAP_LO_ACCEPT:
sock = e->ngap.sock;
ogs_assert(sock);
addr = e->ngap.addr;
@ -674,7 +674,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break;
case AMF_EVT_NGAP_LO_SCTP_COMM_UP:
case AMF_EVENT_NGAP_LO_SCTP_COMM_UP:
sock = e->ngap.sock;
ogs_assert(sock);
addr = e->ngap.addr;
@ -701,7 +701,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break;
case AMF_EVT_NGAP_LO_CONNREFUSED:
case AMF_EVENT_NGAP_LO_CONNREFUSED:
sock = e->ngap.sock;
ogs_assert(sock);
addr = e->ngap.addr;
@ -720,7 +720,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_free(addr);
break;
case AMF_EVT_NGAP_MESSAGE:
case AMF_EVENT_NGAP_MESSAGE:
sock = e->ngap.sock;
ogs_assert(sock);
addr = e->ngap.addr;
@ -751,11 +751,11 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_pkbuf_free(pkbuf);
break;
case AMF_EVT_NGAP_TIMER:
case AMF_EVENT_NGAP_TIMER:
ran_ue = e->ran_ue;
ogs_assert(ran_ue);
switch (e->timer_id) {
switch (e->h.timer_id) {
case AMF_TIMER_NG_DELAYED_SEND:
gnb = e->gnb;
ogs_assert(gnb);
@ -774,12 +774,12 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
break;
default:
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_5GMM_MESSAGE:
case AMF_EVENT_5GMM_MESSAGE:
ran_ue = e->ran_ue;
ogs_assert(ran_ue);
pkbuf = e->pkbuf;
@ -867,7 +867,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_pkbuf_free(pkbuf);
break;
case AMF_EVT_5GMM_TIMER:
case AMF_EVENT_5GMM_TIMER:
amf_ue = e->amf_ue;
ogs_assert(amf_ue);
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.
*
@ -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_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_final(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.
*
@ -870,8 +870,7 @@ amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
memset(&e, 0, sizeof(e));
e.gnb = gnb;
ogs_fsm_create(&gnb->sm, ngap_state_initial, ngap_state_final);
ogs_fsm_init(&gnb->sm, &e);
ogs_fsm_init(&gnb->sm, ngap_state_initial, ngap_state_final, &e);
ogs_list_add(&self.gnb_list, 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));
e.gnb = gnb;
ogs_fsm_fini(&gnb->sm, &e);
ogs_fsm_delete(&gnb->sm);
ogs_hash_set(self.gnb_addr_hash,
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));
e.amf_ue = amf_ue;
ogs_fsm_create(&amf_ue->sm, gmm_state_initial, gmm_state_final);
ogs_fsm_init(&amf_ue->sm, &e);
ogs_fsm_init(&amf_ue->sm, gmm_state_initial, gmm_state_final, &e);
}
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));
e.amf_ue = amf_ue;
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)
@ -1792,7 +1788,6 @@ void amf_sbi_select_nf(
ogs_sbi_nf_instance_t *nf_instance = NULL;
amf_sess_t *sess = NULL;
ogs_assert(ogs_sbi_self()->nf_state_registered);
ogs_assert(sbi_object);
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.
*
@ -197,22 +197,6 @@ struct ran_ue_s {
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 {
ogs_sbi_object_t sbi;
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.
*
@ -20,90 +20,66 @@
#include "event.h"
#include "context.h"
static OGS_POOL(pool, amf_event_t);
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 *amf_event_new(int id)
{
amf_event_t *e = NULL;
ogs_thread_mutex_lock(&amf_event_alloc_mutex);
ogs_pool_alloc(&pool, &e);
ogs_thread_mutex_unlock(&amf_event_alloc_mutex);
e = ogs_event_size(id, sizeof(amf_event_t));
ogs_assert(e);
memset(e, 0, sizeof(*e));
e->id = id;
e->h.id = id;
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)
{
if (e == NULL)
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 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";
}
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,
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);
if (e->pkbuf)
ogs_pkbuf_free(e->pkbuf);
amf_event_free(e);
ogs_event_free(e);
}
#if HAVE_USRSCTP
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.
*
@ -20,18 +20,12 @@
#ifndef AMF_EVENT_H
#define AMF_EVENT_H
#include "ogs-core.h"
#include "ogs-proto.h"
#ifdef __cplusplus
extern "C" {
#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 NGAP_NGAP_PDU ogs_ngap_message_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 enum {
AMF_EVT_BASE = OGS_FSM_USER_SIG,
AMF_EVENT_BASE = OGS_MAX_NUM_OF_PROTO_EVENT,
AMF_EVT_SBI_SERVER,
AMF_EVT_SBI_CLIENT,
AMF_EVT_SBI_TIMER,
AMF_EVENT_NGAP_MESSAGE,
AMF_EVENT_NGAP_TIMER,
AMF_EVENT_NGAP_LO_ACCEPT,
AMF_EVENT_NGAP_LO_SCTP_COMM_UP,
AMF_EVENT_NGAP_LO_CONNREFUSED,
AMF_EVT_NGAP_MESSAGE,
AMF_EVT_NGAP_TIMER,
AMF_EVT_NGAP_LO_ACCEPT,
AMF_EVT_NGAP_LO_SCTP_COMM_UP,
AMF_EVT_NGAP_LO_CONNREFUSED,
AMF_EVENT_5GMM_MESSAGE,
AMF_EVENT_5GMM_TIMER,
AMF_EVENT_5GSM_MESSAGE,
AMF_EVENT_5GSM_TIMER,
AMF_EVT_5GMM_MESSAGE,
AMF_EVT_5GMM_TIMER,
AMF_EVT_5GSM_MESSAGE,
AMF_EVT_5GSM_TIMER,
AMF_EVT_TOP,
MAX_NUM_OF_AMF_EVENT,
} amf_event_e;
typedef struct amf_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;
ogs_sbi_message_t *message;
} sbi;
struct {
ogs_sock_t *sock;
@ -101,15 +83,11 @@ typedef struct amf_event_s {
ogs_timer_t *timer;
} amf_event_t;
void amf_event_init(void);
void amf_event_final(void);
amf_event_t *amf_event_new(amf_event_e id);
void amf_event_free(amf_event_t *e);
amf_event_t *amf_event_new(int id);
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,
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;
ogs_assert(amf_ue);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
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);
}
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AMF_EVT_5GMM_MESSAGE:
case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message;
ogs_assert(nas_message);
@ -367,8 +367,8 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
}
break;
case AMF_EVT_5GMM_TIMER:
switch (e->timer_id) {
case AMF_EVENT_5GMM_TIMER:
switch (e->h.timer_id) {
case AMF_TIMER_T3513:
if (amf_ue->t3513.retry_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:
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;
case AMF_EVT_SBI_CLIENT:
sbi_response = e->sbi.response;
case OGS_EVENT_SBI_CLIENT:
sbi_response = e->h.sbi.response;
ogs_assert(sbi_response);
sbi_message = e->sbi.message;
sbi_message = e->h.sbi.message;
ogs_assert(sbi_message);
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);
}
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AMF_EVT_5GMM_MESSAGE:
case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->nas.message;
ogs_assert(nas_message);
@ -651,8 +651,8 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
break;
}
break;
case AMF_EVT_5GMM_TIMER:
switch (e->timer_id) {
case AMF_EVENT_5GMM_TIMER:
switch (e->h.timer_id) {
case AMF_TIMER_T3560:
if (amf_ue->t3560.retry_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;
default:
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;
case AMF_EVT_SBI_CLIENT:
sbi_response = e->sbi.response;
case OGS_EVENT_SBI_CLIENT:
sbi_response = e->h.sbi.response;
ogs_assert(sbi_response);
sbi_message = e->sbi.message;
sbi_message = e->h.sbi.message;
ogs_assert(sbi_message);
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;
ogs_assert(amf_ue);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
CLEAR_AMF_UE_TIMER(amf_ue->t3560);
ogs_assert(OGS_OK ==
@ -780,7 +780,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
break;
case OGS_FSM_EXIT_SIG:
break;
case AMF_EVT_5GMM_MESSAGE:
case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->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;
case AMF_EVT_5GMM_TIMER:
switch (e->timer_id) {
case AMF_EVENT_5GMM_TIMER:
switch (e->h.timer_id) {
case AMF_TIMER_T3560:
if (amf_ue->t3560.retry_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;
default:
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;
@ -962,16 +962,16 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(amf_ue);
}
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AMF_EVT_SBI_CLIENT:
sbi_response = e->sbi.response;
case OGS_EVENT_SBI_CLIENT:
sbi_response = e->h.sbi.response;
ogs_assert(sbi_response);
sbi_message = e->sbi.message;
sbi_message = e->h.sbi.message;
ogs_assert(sbi_message);
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
break;
case AMF_EVT_5GMM_MESSAGE:
case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->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;
case AMF_EVT_5GMM_TIMER:
switch (e->timer_id) {
case AMF_EVENT_5GMM_TIMER:
switch (e->h.timer_id) {
case AMF_TIMER_T3550:
if (amf_ue->t3550.retry_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;
default:
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;
@ -1281,7 +1281,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(amf_ue);
}
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
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:
break;
case AMF_EVT_5GMM_MESSAGE:
case AMF_EVENT_5GMM_MESSAGE:
nas_message = e->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.
*
@ -33,7 +33,6 @@ int amf_initialize()
ogs_sbi_context_init();
amf_context_init();
amf_event_init();
rv = ogs_sbi_context_parse_config("amf", "nrf", "scp");
if (rv != OGS_OK) return rv;
@ -76,7 +75,7 @@ static void event_termination(void)
/* Sending NF Instance De-registeration to NRF */
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 */
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
@ -105,8 +104,6 @@ void amf_terminate(void)
amf_context_final();
ogs_sbi_context_final();
ogs_metrics_context_final();
amf_event_final(); /* Destroy event */
}
static void amf_main(void *data)
@ -114,8 +111,7 @@ static void amf_main(void *data)
ogs_fsm_t amf_sm;
int rv;
ogs_fsm_create(&amf_sm, amf_state_initial, amf_state_final);
ogs_fsm_init(&amf_sm, 0);
ogs_fsm_init(&amf_sm, amf_state_initial, amf_state_final, 0);
for ( ;; ) {
ogs_pollset_poll(ogs_app()->pollset,
@ -148,11 +144,10 @@ static void amf_main(void *data)
ogs_assert(e);
ogs_fsm_dispatch(&amf_sm, e);
amf_event_free(e);
ogs_event_free(e);
}
}
done:
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.
@ -43,8 +43,6 @@ libamf_sources = files('''
namf-handler.c
sbi-path.c
nf-sm.c
ngap-sctp.c
ngap-build.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) {
amf_event_t *e = NULL;
e = amf_event_new(AMF_EVT_NGAP_TIMER);
e = amf_event_new(AMF_EVENT_NGAP_TIMER);
ogs_assert(e);
e->timer = ogs_timer_add(
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(esmbuf);
e = amf_event_new(AMF_EVT_5GSM_MESSAGE);
e = amf_event_new(AMF_EVENT_5GSM_MESSAGE);
ogs_assert(e);
e->amf_ue = amf_ue;
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) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf);
amf_event_free(e);
ogs_event_free(e);
}
return rv;
@ -212,7 +212,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
if (h->extended_protocol_discriminator ==
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
int rv;
e = amf_event_new(AMF_EVT_5GMM_MESSAGE);
e = amf_event_new(AMF_EVENT_5GMM_MESSAGE);
if (!e) {
ogs_error("ngap_send_to_nas() failed");
ogs_pkbuf_free(nasbuf);
@ -226,7 +226,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
if (rv != OGS_OK) {
ogs_error("ngap_send_to_nas() failed:%d", (int)rv);
ogs_pkbuf_free(e->pkbuf);
amf_event_free(e);
ogs_event_free(e);
}
return rv;
} 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_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);
} else {
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);
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,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
@ -180,7 +180,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr);
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);
}
break;
@ -193,7 +193,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr);
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);
break;
@ -235,7 +235,7 @@ void ngap_recv_handler(ogs_sock_t *sock)
ogs_assert(addr);
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;
} else {
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;
ogs_assert(gnb);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AMF_EVT_NGAP_MESSAGE:
case AMF_EVENT_NGAP_MESSAGE:
pdu = e->ngap.message;
ogs_assert(pdu);
@ -190,8 +190,8 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
}
break;
case AMF_EVT_NGAP_TIMER:
switch (e->timer_id) {
case AMF_EVENT_NGAP_TIMER:
switch (e->h.timer_id) {
case AMF_TIMER_NG_DELAYED_SEND:
ogs_assert(e->ran_ue);
ogs_assert(e->pkbuf);
@ -201,7 +201,7 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
break;
default:
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;
@ -218,7 +218,7 @@ void ngap_state_exception(ogs_fsm_t *s, amf_event_t *e)
amf_sm_debug(e);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
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.
*
@ -19,41 +19,6 @@
#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(
char *nrf_id,
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.
*
@ -26,8 +26,6 @@
extern "C" {
#endif
ogs_sbi_request_t *amf_nnrf_nfm_build_register(void);
ogs_sbi_request_t *amf_nnrf_disc_build_discover(
char *nrf_id,
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.
*
@ -22,233 +22,6 @@
#include "ngap-path.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(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
{
@ -273,84 +46,10 @@ void amf_nnrf_handle_nf_discover(
return;
}
amf_nnrf_handle_nf_discover_search_result(
ogs_nnrf_handle_nf_discover_search_result(
sbi_object, target_nf_type, discovery_option, SearchResult);
amf_sbi_select_nf(sbi_object, target_nf_type, discovery_option);
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.
*
@ -26,21 +26,8 @@
extern "C" {
#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(
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
}

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_ue_t *amf_ue = NULL;
ran_ue_t *ran_ue = NULL;
ogs_assert(sess);
amf_ue = sess->amf_ue;
ogs_assert(amf_ue);
@ -356,7 +358,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!n2smbuf) {
ogs_error("[%s:%d] No N2 SM Content",
amf_ue->supi, sess->psi);
ogs_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error));
@ -380,7 +382,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!n2smbuf) {
ogs_error("[%s:%d] No N2 SM Content",
amf_ue->supi, sess->psi);
ogs_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error));
@ -402,7 +404,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
default:
ogs_error("Not implemented [%d]",
SmContextUpdatedData->n2_sm_info_type);
ogs_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol,
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) {
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);
@ -644,7 +646,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL) {
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
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);
@ -701,8 +703,6 @@ int amf_nsmf_pdusession_handle_update_sm_context(
}
}
} else {
amf_ue_t *amf_ue = NULL;
OpenAPI_sm_context_update_error_t *SmContextUpdateError = NULL;
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
ogs_pkbuf_t *n1smbuf = NULL;
@ -719,7 +719,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!SmContextUpdateError) {
ogs_error("[%d:%d] No SmContextUpdateError [%d]",
sess->psi, sess->pti, recvmsg->res_status);
ogs_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
@ -728,7 +728,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!SmContextUpdateError->error) {
ogs_error("[%d:%d] No Error [%d]",
sess->psi, sess->pti, recvmsg->res_status);
ogs_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
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;
if (!n2SmInfo || !n2SmInfo->content_id) {
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_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
@ -773,7 +773,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
if (!n2smbuf) {
ogs_error("[%d:%d] No N2 SM Content [%s]",
sess->psi, sess->pti, n2SmInfo->content_id);
ogs_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
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_assert(OGS_OK ==
ogs_expect(OGS_OK ==
ngap_send_error_indication2(amf_ue,
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.
*
@ -30,17 +30,17 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
ogs_assert(request);
ogs_assert(data);
e = amf_event_new(AMF_EVT_SBI_SERVER);
e = amf_event_new(OGS_EVENT_SBI_SERVER);
ogs_assert(e);
e->sbi.request = request;
e->sbi.data = data;
e->h.sbi.request = request;
e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_request_free(request);
amf_event_free(e);
ogs_event_free(e);
return OGS_ERROR;
}
@ -61,16 +61,16 @@ static int client_cb(int status, ogs_sbi_response_t *response, void *data)
ogs_assert(response);
e = amf_event_new(AMF_EVT_SBI_CLIENT);
e = amf_event_new(OGS_EVENT_SBI_CLIENT);
ogs_assert(e);
e->sbi.response = response;
e->sbi.data = data;
e->h.sbi.response = response;
e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_response_free(response);
amf_event_free(e);
ogs_event_free(e);
return OGS_ERROR;
}
@ -82,6 +82,14 @@ int amf_sbi_open(void)
ogs_sbi_nf_instance_t *nf_instance = 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 */
nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance);
@ -123,16 +131,9 @@ int amf_sbi_open(void)
/* NFRegister is sent and the response is received
* 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)
return OGS_ERROR;
@ -332,7 +333,7 @@ static int client_discover_cb(
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);
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.
*

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.
*
@ -20,36 +20,33 @@
#include "context.h"
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 */
[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 */
[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 */
[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 */
[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
* SECURITY MODE COMMAND sent */
[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 */
[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] =
{ .duration = ogs_time_from_sec(30) },
{ .have = true, .duration = ogs_time_from_sec(30) },
};
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)
{
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];
}
const char *amf_timer_get_name(amf_timer_e id)
const char *amf_timer_get_name(int timer_id)
{
switch (id) {
case AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
return "AMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL";
case AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
return "AMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL";
case AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
return "AMF_TIMER_NF_INSTANCE_NO_HEARTBEAT";
case AMF_TIMER_NF_INSTANCE_VALIDITY:
return "AMF_TIMER_NF_INSTANCE_VALIDITY";
case AMF_TIMER_SUBSCRIPTION_VALIDITY:
return "AMF_TIMER_SUBSCRIPTION_VALIDITY";
case AMF_TIMER_SBI_CLIENT_WAIT:
return "AMF_TIMER_SBI_CLIENT_WAIT";
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;
case AMF_TIMER_NG_DELAYED_SEND:
return "AMF_TIMER_NG_DELAYED_SEND";
case AMF_TIMER_T3513:
@ -93,9 +94,10 @@ const char *amf_timer_get_name(amf_timer_e id)
case AMF_TIMER_NG_HOLDING:
return "AMF_TIMER_NG_HOLDING";
default:
break;
break;
}
ogs_error("Unknown Timer[%d]", timer_id);
return "UNKNOWN_TIMER";
}
@ -105,90 +107,16 @@ void amf_timer_ng_delayed_send(void *data)
amf_event_t *e = data;
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);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
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(
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;
ogs_assert(amf_ue);
e = amf_event_new(AMF_EVT_5GMM_TIMER);
e = amf_event_new(AMF_EVENT_5GMM_TIMER);
ogs_assert(e);
e->timer_id = timer_id;
e->h.timer_id = timer_id;
e->amf_ue = amf_ue;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
amf_event_free(e);
ogs_error("ogs_queue_push() failed:%d in %s",
(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);
ran_ue = data;
e = amf_event_new(AMF_EVT_NGAP_TIMER);
e = amf_event_new(AMF_EVENT_NGAP_TIMER);
ogs_assert(e);
e->timer_id = AMF_TIMER_NG_HOLDING;
e->h.timer_id = AMF_TIMER_NG_HOLDING;
e->ran_ue = ran_ue;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
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.
*
@ -20,7 +20,7 @@
#ifndef AMF_TIMER_H
#define AMF_TIMER_H
#include "ogs-core.h"
#include "ogs-proto.h"
#ifdef __cplusplus
extern "C" {
@ -28,14 +28,7 @@ extern "C" {
/* forward declaration */
typedef enum {
AMF_TIMER_BASE = 0,
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_BASE = OGS_MAX_NUM_OF_PROTO_TIMER,
AMF_TIMER_NG_DELAYED_SEND,
AMF_TIMER_NG_HOLDING,
@ -52,20 +45,14 @@ typedef enum {
} amf_timer_e;
typedef struct amf_timer_cfg_s {
bool have;
int max_count;
ogs_time_t duration;
} amf_timer_cfg_t;
amf_timer_cfg_t *amf_timer_cfg(amf_timer_e id);
const char *amf_timer_get_name(amf_timer_e 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);
const char *amf_timer_get_name(int timer_id);
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.
*
@ -53,17 +53,17 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ogs_assert(s);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AUSF_EVT_SBI_SERVER:
request = e->sbi.request;
case OGS_EVENT_SBI_SERVER:
request = e->h.sbi.request;
ogs_assert(request);
stream = e->sbi.data;
stream = e->h.sbi.data;
ogs_assert(stream);
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)
SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
ausf_nnrf_handle_nf_status_notify(stream, &message);
ogs_nnrf_handle_nf_status_notify(stream, &message);
break;
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));
e->ausf_ue = ausf_ue;
e->sbi.message = &message;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&ausf_ue->sm, e);
if (OGS_FSM_CHECK(&ausf_ue->sm, ausf_ue_state_exception)) {
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);
break;
case AUSF_EVT_SBI_CLIENT:
case OGS_EVENT_SBI_CLIENT:
ogs_assert(e);
response = e->sbi.response;
response = e->h.sbi.response;
ogs_assert(response);
rv = ogs_sbi_parse_response(&message, response);
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])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data;
nf_instance = e->h.sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &message;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&nf_instance->sm, e);
break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data;
subscription = e->h.sbi.data;
ogs_assert(subscription);
SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
message.res_status == OGS_SBI_HTTP_STATUS_OK) {
ausf_nnrf_handle_nf_status_subscribe(
ogs_nnrf_handle_nf_status_subscribe(
subscription, &message);
} else {
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)
SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
SWITCH(message.h.method)
@ -276,7 +276,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
break;
CASE(OGS_SBI_SERVICE_NAME_NUDM_UEAU)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(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;
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);
@ -301,7 +301,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
}
e->ausf_ue = ausf_ue;
e->sbi.message = &message;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&ausf_ue->sm, e);
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);
break;
case AUSF_EVT_SBI_TIMER:
case OGS_EVENT_SBI_TIMER:
ogs_assert(e);
switch(e->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:
nf_instance = e->sbi.data;
switch(e->h.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:
nf_instance = e->h.sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
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]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id, e->timer_id);
nf_instance->id, e->h.timer_id);
break;
case AUSF_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data;
case OGS_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->h.sbi.data;
ogs_assert(subscription);
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);
break;
case AUSF_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data;
case OGS_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
stream = sbi_xact->assoc_stream;
@ -370,7 +370,7 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e)
break;
default:
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;

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.
*
@ -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_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_final(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.
*
@ -141,8 +141,7 @@ ausf_ue_t *ausf_ue_add(char *suci)
memset(&e, 0, sizeof(e));
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, &e);
ogs_fsm_init(&ausf_ue->sm, ausf_ue_state_initial, ausf_ue_state_final, &e);
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));
e.ausf_ue = ausf_ue;
ogs_fsm_fini(&ausf_ue->sm, &e);
ogs_fsm_delete(&ausf_ue->sm);
/* Free SBI object memory */
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.
*
@ -25,7 +25,6 @@
#include "ogs-sbi.h"
#include "ausf-sm.h"
#include "timer.h"
#ifdef __cplusplus
extern "C" {
@ -63,22 +62,6 @@ struct ausf_ue_s {
uint8_t hxres_star[OGS_MAX_RES_LEN];
uint8_t kausf[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);

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.
*
@ -18,60 +18,42 @@
*/
#include "event.h"
#include "context.h"
static OGS_POOL(pool, ausf_event_t);
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 *ausf_event_new(int id)
{
ausf_event_t *e = NULL;
ogs_pool_alloc(&pool, &e);
e = ogs_event_size(id, sizeof(ausf_event_t));
ogs_assert(e);
memset(e, 0, sizeof(*e));
e->id = id;
e->h.id = id;
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)
{
if (e == NULL)
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 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";
}

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.
*
@ -20,53 +20,21 @@
#ifndef AUSF_EVENT_H
#define AUSF_EVENT_H
#include "ogs-core.h"
#include "ogs-proto.h"
#ifdef __cplusplus
extern "C" {
#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 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 {
int id;
int timer_id;
struct {
ogs_sbi_request_t *request;
ogs_sbi_response_t *response;
void *data;
ogs_sbi_message_t *message;
} sbi;
ogs_event_t h;
ausf_ue_t *ausf_ue;
ogs_timer_t *timer;
} ausf_event_t;
void ausf_event_init(void);
void ausf_event_final(void);
ausf_event_t *ausf_event_new(ausf_event_e id);
void ausf_event_free(ausf_event_t *e);
ausf_event_t *ausf_event_new(int id);
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.
*
@ -30,7 +30,6 @@ int ausf_initialize()
ogs_sbi_context_init();
ausf_context_init();
ausf_event_init();
rv = ogs_sbi_context_parse_config("ausf", "nrf", "scp");
if (rv != OGS_OK) return rv;
@ -61,7 +60,7 @@ static void event_termination(void)
/* Sending NF Instance De-registeration to NRF */
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 */
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
@ -87,8 +86,6 @@ void ausf_terminate(void)
ausf_context_final();
ogs_sbi_context_final();
ausf_event_final(); /* Destroy event */
}
static void ausf_main(void *data)
@ -96,8 +93,7 @@ static void ausf_main(void *data)
ogs_fsm_t ausf_sm;
int rv;
ogs_fsm_create(&ausf_sm, ausf_state_initial, ausf_state_final);
ogs_fsm_init(&ausf_sm, 0);
ogs_fsm_init(&ausf_sm, ausf_state_initial, ausf_state_final, 0);
for ( ;; ) {
ogs_pollset_poll(ogs_app()->pollset,
@ -130,11 +126,10 @@ static void ausf_main(void *data)
ogs_assert(e);
ogs_fsm_dispatch(&ausf_sm, e);
ausf_event_free(e);
ogs_event_free(e);
}
}
done:
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.
@ -18,12 +18,8 @@
libausf_sources = files('''
context.c
event.c
timer.c
nnrf-build.c
nnrf-handler.c
nf-sm.c
nausf-handler.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.
*
@ -20,243 +20,14 @@
#include "sbi-path.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(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
{
ogs_sbi_object_t *sbi_object = NULL;
OpenAPI_nf_type_e target_nf_type = 0;
ogs_sbi_discovery_option_t *discovery_option = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
OpenAPI_search_result_t *SearchResult = NULL;
OpenAPI_lnode_t *node = NULL;
bool handled;
ogs_assert(recvmsg);
ogs_assert(xact);
@ -273,64 +44,8 @@ void ausf_nnrf_handle_nf_discover(
return;
}
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);
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_nnrf_handle_nf_discover_search_result(
sbi_object, target_nf_type, discovery_option, SearchResult);
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.
*
@ -26,14 +26,6 @@
extern "C" {
#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(
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.
*
@ -27,17 +27,17 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
ogs_assert(request);
ogs_assert(data);
e = ausf_event_new(AUSF_EVT_SBI_SERVER);
e = ausf_event_new(OGS_EVENT_SBI_SERVER);
ogs_assert(e);
e->sbi.request = request;
e->sbi.data = data;
e->h.sbi.request = request;
e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_request_free(request);
ausf_event_free(e);
ogs_event_free(e);
return OGS_ERROR;
}
@ -58,16 +58,16 @@ static int client_cb(int status, ogs_sbi_response_t *response, void *data)
ogs_assert(response);
e = ausf_event_new(AUSF_EVT_SBI_CLIENT);
e = ausf_event_new(OGS_EVENT_SBI_CLIENT);
ogs_assert(e);
e->sbi.response = response;
e->sbi.data = data;
e->h.sbi.response = response;
e->h.sbi.data = data;
rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_sbi_response_free(response);
ausf_event_free(e);
ogs_event_free(e);
return OGS_ERROR;
}
@ -79,6 +79,10 @@ int ausf_sbi_open(void)
ogs_sbi_nf_instance_t *nf_instance = 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 */
nf_instance = ogs_sbi_self()->nf_instance;
ogs_assert(nf_instance);
@ -98,28 +102,20 @@ int ausf_sbi_open(void)
}
/* Initialize NRF NF Instance */
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) {
if (NF_INSTANCE_IS_NRF(nf_instance)) {
ogs_sbi_client_t *client = NULL;
nf_instance = ogs_sbi_self()->nrf_instance;
if (nf_instance) {
ogs_sbi_client_t *client = NULL;
/* Client callback is only used when NF sends to NRF */
client = nf_instance->client;
ogs_assert(client);
client->cb = client_cb;
/* Client callback is only used when NF sends to NRF */
client = nf_instance->client;
ogs_assert(client);
client->cb = client_cb;
/* NFRegister is sent and the response is received
* by the above client callback. */
ausf_nf_fsm_init(nf_instance);
}
/* NFRegister is sent and the response is received
* by the above client callback. */
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)
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.
*
@ -20,7 +20,6 @@
#ifndef AUSF_SBI_PATH_H
#define AUSF_SBI_PATH_H
#include "nnrf-build.h"
#include "nudm-build.h"
#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.
*
@ -66,17 +66,17 @@ void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e)
ausf_ue = e->ausf_ue;
ogs_assert(ausf_ue);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case AUSF_EVT_SBI_SERVER:
message = e->sbi.message;
case OGS_EVENT_SBI_SERVER:
message = e->h.sbi.message;
ogs_assert(message);
stream = e->sbi.data;
stream = e->h.sbi.data;
ogs_assert(stream);
SWITCH(message->h.method)
@ -109,13 +109,13 @@ void ausf_ue_state_operational(ogs_fsm_t *s, ausf_event_t *e)
break;
case AUSF_EVT_SBI_CLIENT:
message = e->sbi.message;
case OGS_EVENT_SBI_CLIENT:
message = e->h.sbi.message;
ogs_assert(message);
ausf_ue = e->ausf_ue;
ogs_assert(ausf_ue);
stream = e->sbi.data;
stream = e->h.sbi.data;
ogs_assert(stream);
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;
ogs_assert(ausf_ue);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
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.
*
@ -56,17 +56,17 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
ogs_assert(s);
switch (e->id) {
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case BSF_EVT_SBI_SERVER:
request = e->sbi.request;
case OGS_EVENT_SBI_SERVER:
request = e->h.sbi.request;
ogs_assert(request);
stream = e->sbi.data;
stream = e->h.sbi.data;
ogs_assert(stream);
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)
SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
bsf_nnrf_handle_nf_status_notify(stream, &message);
ogs_nnrf_handle_nf_status_notify(stream, &message);
break;
DEFAULT
@ -195,10 +195,10 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
ogs_sbi_message_free(&message);
break;
case BSF_EVT_SBI_CLIENT:
case OGS_EVENT_SBI_CLIENT:
ogs_assert(e);
response = e->sbi.response;
response = e->h.sbi.response;
ogs_assert(response);
rv = ogs_sbi_parse_response(&message, response);
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])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data;
nf_instance = e->h.sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &message;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&nf_instance->sm, e);
break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data;
subscription = e->h.sbi.data;
ogs_assert(subscription);
SWITCH(message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
message.res_status == OGS_SBI_HTTP_STATUS_OK) {
bsf_nnrf_handle_nf_status_subscribe(
ogs_nnrf_handle_nf_status_subscribe(
subscription, &message);
} else {
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)
SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data;
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
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);
break;
case BSF_EVT_SBI_TIMER:
case OGS_EVENT_SBI_TIMER:
ogs_assert(e);
switch(e->timer_id) {
case BSF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case BSF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
case BSF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
case BSF_TIMER_NF_INSTANCE_VALIDITY:
nf_instance = e->sbi.data;
switch(e->h.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:
nf_instance = e->h.sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
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]",
OpenAPI_nf_type_ToString(nf_instance->nf_type),
nf_instance->id, e->timer_id);
nf_instance->id, e->h.timer_id);
break;
case BSF_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data;
case OGS_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->h.sbi.data;
ogs_assert(subscription);
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);
break;
case BSF_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data;
case OGS_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
stream = sbi_xact->assoc_stream;
@ -358,7 +358,7 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e)
default:
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;

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.
*
@ -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_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) \
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.
*

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.
*
@ -23,7 +23,6 @@
#include "ogs-sbi.h"
#include "ogs-app.h"
#include "timer.h"
#include "bsf-sm.h"
#ifdef __cplusplus
@ -42,22 +41,6 @@ typedef struct bsf_context_s {
ogs_list_t sess_list;
} 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 {

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.
*
@ -18,60 +18,42 @@
*/
#include "event.h"
#include "context.h"
static OGS_POOL(pool, bsf_event_t);
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 *bsf_event_new(int id)
{
bsf_event_t *e = NULL;
ogs_pool_alloc(&pool, &e);
e = ogs_event_size(id, sizeof(bsf_event_t));
ogs_assert(e);
memset(e, 0, sizeof(*e));
e->id = id;
e->h.id = id;
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)
{
if (e == NULL)
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 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";
}

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.
*
@ -20,51 +20,20 @@
#ifndef BSF_EVENT_H
#define BSF_EVENT_H
#include "ogs-core.h"
#include "ogs-proto.h"
#ifdef __cplusplus
extern "C" {
#endif
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 {
int id;
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;
ogs_event_t h;
bsf_sess_t *sess;
} bsf_event_t;
void bsf_event_init(void);
void bsf_event_final(void);
bsf_event_t *bsf_event_new(bsf_event_e id);
void bsf_event_free(bsf_event_t *e);
bsf_event_t *bsf_event_new(int id);
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.
*
@ -32,7 +32,6 @@ int bsf_initialize()
ogs_sbi_context_init();
bsf_context_init();
bsf_event_init();
rv = ogs_sbi_context_parse_config("bsf", "nrf", "scp");
if (rv != OGS_OK) return rv;
@ -63,7 +62,7 @@ static void event_termination(void)
/* Sending NF Instance De-registeration to NRF */
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 */
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
@ -90,8 +89,6 @@ void bsf_terminate(void)
bsf_context_final();
ogs_sbi_context_final();
bsf_event_final(); /* Destroy event */
}
static void bsf_main(void *data)
@ -99,8 +96,7 @@ static void bsf_main(void *data)
ogs_fsm_t bsf_sm;
int rv;
ogs_fsm_create(&bsf_sm, bsf_state_initial, bsf_state_final);
ogs_fsm_init(&bsf_sm, 0);
ogs_fsm_init(&bsf_sm, bsf_state_initial, bsf_state_final, 0);
for ( ;; ) {
ogs_pollset_poll(ogs_app()->pollset,
@ -133,11 +129,10 @@ static void bsf_main(void *data)
ogs_assert(e);
ogs_fsm_dispatch(&bsf_sm, e);
bsf_event_free(e);
ogs_event_free(e);
}
}
done:
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.
@ -18,12 +18,8 @@
libbsf_sources = files('''
context.c
event.c
timer.c
nnrf-build.c
nnrf-handler.c
nf-sm.c
nbsf-handler.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 SendPcfBinding;
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(recvmsg);
@ -103,22 +99,10 @@ bool bsf_nbsf_management_handle_pcf_binding(
bsf_sess_set_ipv6prefix(sess, RecvPcfBinding->ipv6_prefix);
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)
ogs_free(sess->pcf_fqdn);
sess->pcf_fqdn = ogs_strdup(RecvPcfBinding->pcf_fqdn);
ogs_assert(sess->pcf_fqdn);
#endif
}
PcfIpEndPointList = RecvPcfBinding->pcf_ip_end_points;
@ -232,18 +216,8 @@ bool bsf_nbsf_management_handle_pcf_binding(
PcfIpEndPointList = OpenAPI_list_create();
ogs_assert(PcfIpEndPointList);
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
if (sess->pcf_fqdn && strlen(sess->pcf_fqdn))
SendPcfBinding.pcf_fqdn = ogs_strdup(sess->pcf_fqdn);
#endif
}
for (i = 0; i < sess->num_of_pcf_ip; i++) {
OpenAPI_ip_end_point_t *PcfIpEndPoint = NULL;

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