forked from acouzens/open5gs
Merge branch 'main' of https://github.com/open5gs/open5gs into main
This commit is contained in:
commit
0c6258d108
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -178,6 +178,13 @@ logger:
|
|||
# sinit_max_attempts : 4
|
||||
# sinit_max_init_timeo : 8000
|
||||
#
|
||||
# <Metrics Server>
|
||||
#
|
||||
# o Metrics Server(http://<any address>:9090)
|
||||
# metrics:
|
||||
# addr: 0.0.0.0
|
||||
# port: 9090
|
||||
#
|
||||
# <GUAMI>
|
||||
#
|
||||
# o Multiple GUAMI
|
||||
|
@ -263,6 +270,9 @@ amf:
|
|||
port: 7777
|
||||
ngap:
|
||||
- addr: 127.0.0.5
|
||||
metrics:
|
||||
addr: 127.0.0.5
|
||||
port: 9090
|
||||
guami:
|
||||
- plmn_id:
|
||||
mcc: 999
|
||||
|
@ -391,17 +401,3 @@ usrsctp:
|
|||
# handover:
|
||||
# duration: 500
|
||||
time:
|
||||
|
||||
#
|
||||
# metrics:
|
||||
#
|
||||
# <Metrics Server>
|
||||
#
|
||||
# o Metrics Server(http://<any address>:9090)
|
||||
# metrics:
|
||||
# addr: 0.0.0.0
|
||||
# port: 9090
|
||||
#
|
||||
metrics:
|
||||
addr: 127.0.0.5
|
||||
port: 9090
|
||||
|
|
|
@ -41,6 +41,7 @@ hss:
|
|||
# prefer_ipv4: true
|
||||
#
|
||||
parameter:
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
#
|
||||
# max:
|
||||
|
|
|
@ -175,6 +175,12 @@ logger:
|
|||
# mnc: 02
|
||||
# lac: 43693
|
||||
#
|
||||
# <Metrics Server>
|
||||
#
|
||||
# o Metrics Server(http://<any address>:9090)
|
||||
# metrics:
|
||||
# addr: 0.0.0.0
|
||||
# port: 9090
|
||||
#
|
||||
# <GUMMEI>
|
||||
#
|
||||
|
@ -248,6 +254,9 @@ mme:
|
|||
- addr: 127.0.0.2
|
||||
gtpc:
|
||||
- addr: 127.0.0.2
|
||||
metrics:
|
||||
addr: 127.0.0.2
|
||||
port: 9090
|
||||
gummei:
|
||||
plmn_id:
|
||||
mcc: 999
|
||||
|
@ -421,17 +430,3 @@ usrsctp:
|
|||
# handover:
|
||||
# duration: 500
|
||||
time:
|
||||
|
||||
#
|
||||
# metrics:
|
||||
#
|
||||
# <Metrics Server>
|
||||
#
|
||||
# o Metrics Server(http://<any address>:9090)
|
||||
# metrics:
|
||||
# addr: 0.0.0.0
|
||||
# port: 9090
|
||||
#
|
||||
metrics:
|
||||
addr: 127.0.0.2
|
||||
port: 9090
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#
|
||||
# o Set OGS_LOG_TRACE to all domain level
|
||||
# level: trace
|
||||
# domain: core,pfcp,fd,pfcp,gtp,smf,event,tlv,mem,sock
|
||||
# domain: core,fd,pfcp,gtp,smf,event,tlv,mem,sock
|
||||
#
|
||||
logger:
|
||||
file: @localstatedir@/log/open5gs/smf.log
|
||||
|
@ -179,6 +179,13 @@ logger:
|
|||
# option:
|
||||
# so_bindtodevice: vrf-blue
|
||||
#
|
||||
# <Metrics Server>
|
||||
#
|
||||
# o Metrics Server(http://<any address>:9090)
|
||||
# metrics:
|
||||
# addr: 0.0.0.0
|
||||
# port: 9090
|
||||
#
|
||||
# <Subnet for UE Pool>
|
||||
#
|
||||
# o IPv4 Pool
|
||||
|
@ -423,6 +430,9 @@ smf:
|
|||
gtpu:
|
||||
- addr: 127.0.0.4
|
||||
- addr: ::1
|
||||
metrics:
|
||||
addr: 127.0.0.4
|
||||
port: 9090
|
||||
subnet:
|
||||
- addr: 10.45.0.1/16
|
||||
- addr: 2001:db8:cafe::1/48
|
||||
|
@ -599,17 +609,3 @@ max:
|
|||
# handover:
|
||||
# duration: 500
|
||||
time:
|
||||
|
||||
#
|
||||
# metrics:
|
||||
#
|
||||
# <Metrics Server>
|
||||
#
|
||||
# o Metrics Server(http://<any address>:9090)
|
||||
# metrics:
|
||||
# addr: 0.0.0.0
|
||||
# port: 9090
|
||||
#
|
||||
metrics:
|
||||
addr: 127.0.0.4
|
||||
port: 9090
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
|||
# no_sgwu: true
|
||||
# no_pcrf: true
|
||||
# no_hss: true
|
||||
# use_mongodb_change_stream: true
|
||||
|
||||
mme:
|
||||
freeDiameter:
|
||||
|
|
|
@ -430,6 +430,21 @@ $ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
|
|||
$ sudo ip6tables -t nat -A POSTROUTING -s 2001:db8:cafe::/48 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
Optionally, you may consider the settings below for security purposes.
|
||||
|
||||
```bash
|
||||
### Prevent UE's from connecting to the host on which UPF is running
|
||||
$ sudo iptables -I INPUT -s 10.45.0.0/16 -j DROP
|
||||
$ sudo ip6tables -I INPUT -s 2001:db8:cafe::/48 -j DROP
|
||||
|
||||
### If your core network runs over multiple hosts, you probably want to block
|
||||
### UE originating traffic from accessing other network functions.
|
||||
### Replace x.x.x.x/y with the VNFs IP/subnet
|
||||
$ sudo iptables -I FORWARD -s 10.45.0.0/16 -d x.x.x.x/y -j DROP
|
||||
```
|
||||
|
||||
**Note:** The above assumes you do not have any existing rules in the filter and nat tables. If a program such as docker has already set up rules, you may need to add the Open5GS related rules differently.
|
||||
{: .notice--danger}
|
||||
|
||||
## 5. Turn on your eNB/gNB and UE
|
||||
---
|
||||
|
|
|
@ -468,6 +468,19 @@ $ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
|
|||
$ sudo ip6tables -t nat -A POSTROUTING -s 2001:db8:cafe::/48 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
Optionally, you may consider the settings below for security purposes.
|
||||
|
||||
```bash
|
||||
### Prevent UE's from connecting to the host on which UPF is running
|
||||
$ sudo iptables -I INPUT -s 10.45.0.0/16 -j DROP
|
||||
$ sudo ip6tables -I INPUT -s 2001:db8:cafe::/48 -j DROP
|
||||
|
||||
### If your core network runs over multiple hosts, you probably want to block
|
||||
### UE originating traffic from accessing other network functions.
|
||||
### Replace x.x.x.x/y with the VNFs IP/subnet
|
||||
$ sudo iptables -I FORWARD -s 10.45.0.0/16 -d x.x.x.x/y -j DROP
|
||||
```
|
||||
|
||||
**Note:** The above assumes you do not have any existing rules in the filter and nat tables. If a program such as docker has already set up rules, you may need to add the Open5GS related rules differently.
|
||||
{: .notice--danger}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ $ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
|
|||
$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||
```
|
||||
|
||||
Enable IP forwarding & Masquerading
|
||||
|
|
|
@ -69,6 +69,7 @@ $ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
|
|||
$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||
```
|
||||
|
||||
Enable IP forwarding & Masquerading
|
||||
|
|
|
@ -89,6 +89,7 @@ $ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
|
|||
$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||
```
|
||||
|
||||
Enable IP forwarding
|
||||
|
|
|
@ -350,6 +350,10 @@ int ogs_app_context_parse_config(void)
|
|||
} else if (!strcmp(parameter_key, "no_pfcp_rr_select")) {
|
||||
self.parameter.no_pfcp_rr_select =
|
||||
ogs_yaml_iter_bool(¶meter_iter);
|
||||
} else if (!strcmp(parameter_key,
|
||||
"use_mongodb_change_stream")) {
|
||||
self.use_mongodb_change_stream =
|
||||
ogs_yaml_iter_bool(¶meter_iter);
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", parameter_key);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ typedef struct ogs_app_context_s {
|
|||
void *document;
|
||||
|
||||
const char *db_uri;
|
||||
int use_mongodb_change_stream;
|
||||
|
||||
struct {
|
||||
const char *file;
|
||||
const char *level;
|
||||
|
|
|
@ -125,7 +125,7 @@ ogs_time_t ogs_time_now(void)
|
|||
rc = ogs_gettimeofday(&tv);
|
||||
ogs_assert(rc == 0);
|
||||
|
||||
return tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec;
|
||||
return ogs_time_from_sec(tv.tv_sec) + tv.tv_usec;
|
||||
}
|
||||
|
||||
/* The following code is stolen from APR library */
|
||||
|
@ -188,13 +188,13 @@ uint32_t ogs_time_ntp32_now(void)
|
|||
rc = ogs_gettimeofday(&tv);
|
||||
ogs_assert(rc == 0);
|
||||
|
||||
return ogs_time_to_ntp32(tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec);
|
||||
return ogs_time_to_ntp32(ogs_time_from_sec(tv.tv_sec) + tv.tv_usec);
|
||||
}
|
||||
ogs_time_t ogs_time_from_ntp32(uint32_t ntp_timestamp)
|
||||
{
|
||||
if (ntp_timestamp < OGS_1970_1900_SEC_DIFF)
|
||||
return 0;
|
||||
return (ntp_timestamp - OGS_1970_1900_SEC_DIFF) * OGS_USEC_PER_SEC;
|
||||
return ogs_time_from_sec(ntp_timestamp - OGS_1970_1900_SEC_DIFF);
|
||||
}
|
||||
uint32_t ogs_time_to_ntp32(ogs_time_t time)
|
||||
{
|
||||
|
@ -242,7 +242,7 @@ ogs_time_t ogs_get_monotonic_time(void)
|
|||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return ((ts.tv_sec * 1000000UL) + (ts.tv_nsec / 1000UL));
|
||||
return ogs_time_from_sec(ts.tv_sec) + ts.tv_nsec / 1000UL;
|
||||
#elif defined(__APPLE__)
|
||||
static mach_timebase_info_data_t info = {0};
|
||||
static double ratio = 0.0;
|
||||
|
@ -268,7 +268,7 @@ ogs_time_t ogs_get_monotonic_time(void)
|
|||
struct timeval tv;
|
||||
|
||||
ogs_gettimeofday(&tv);
|
||||
return (tv.tv_sec * 1000000UL) + tv.tv_usec;
|
||||
return ogs_time_from_sec(tv.tv_sec) + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,11 @@ ogs_tlv_t *ogs_tlv_parse_block(uint32_t length, void *data, uint8_t mode)
|
|||
ogs_assert(pos);
|
||||
}
|
||||
|
||||
ogs_assert(length == (pos - blk));
|
||||
if (length != (pos - blk)) {
|
||||
ogs_fatal("ogs_tlv_parse_block() failed[LEN:%d,MODE:%d]", length, mode);
|
||||
ogs_log_hexdump(OGS_LOG_FATAL, data, length);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ static void get_system_time(uint64_t *uuid_time)
|
|||
|
||||
/* ### fix this call to be more portable? */
|
||||
ogs_gettimeofday(&tv);
|
||||
*uuid_time = tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec;
|
||||
*uuid_time = ogs_time_from_sec(tv.tv_sec) + tv.tv_usec;
|
||||
|
||||
/* Offset between UUID formatted times and Unix formatted times.
|
||||
UUID UTC base time is October 15, 1582.
|
||||
|
|
|
@ -19,11 +19,14 @@ libdbi_sources = files('''
|
|||
ogs-dbi.h
|
||||
|
||||
ogs-mongoc.h
|
||||
timer.h
|
||||
|
||||
ogs-mongoc.c
|
||||
subscription.c
|
||||
session.c
|
||||
ims.c
|
||||
path.c
|
||||
timer.c
|
||||
'''.split())
|
||||
|
||||
libmongoc_dep = dependency('libmongoc-1.0')
|
||||
|
@ -35,10 +38,10 @@ libdbi = library('ogsdbi',
|
|||
version : libogslib_version,
|
||||
c_args : '-DOGS_DBI_COMPILATION',
|
||||
include_directories : [libdbi_inc, libinc],
|
||||
dependencies : [libcrypt_dep, libmongoc_dep],
|
||||
dependencies : [libcrypt_dep, libapp_dep, libmongoc_dep],
|
||||
install : true)
|
||||
|
||||
libdbi_dep = declare_dependency(
|
||||
link_with : libdbi,
|
||||
include_directories : [libdbi_inc, libinc],
|
||||
dependencies : [libcrypt_dep, libmongoc_dep])
|
||||
dependencies : [libcrypt_dep, libapp_dep, libmongoc_dep])
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define OGS_DBI_H
|
||||
|
||||
#include "crypt/ogs-crypt.h"
|
||||
#include "app/ogs-app.h"
|
||||
|
||||
#define OGS_DBI_INSIDE
|
||||
|
||||
|
@ -28,6 +29,8 @@
|
|||
#include "dbi/subscription.h"
|
||||
#include "dbi/session.h"
|
||||
#include "dbi/ims.h"
|
||||
#include "dbi/path.h"
|
||||
#include "dbi/timer.h"
|
||||
|
||||
#undef OGS_DBI_INSIDE
|
||||
|
||||
|
|
|
@ -182,5 +182,62 @@ void ogs_dbi_final()
|
|||
mongoc_collection_destroy(self.collection.subscriber);
|
||||
}
|
||||
|
||||
if (self.stream) {
|
||||
mongoc_change_stream_destroy(self.stream);
|
||||
}
|
||||
|
||||
ogs_mongoc_final();
|
||||
}
|
||||
|
||||
int ogs_dbi_collection_watch_init(void)
|
||||
{
|
||||
bson_t empty = BSON_INITIALIZER;
|
||||
const bson_t *err_doc;
|
||||
bson_error_t error;
|
||||
bson_t *options = BCON_NEW("fullDocument", "updateLookup");
|
||||
|
||||
ogs_mongoc()->stream = mongoc_collection_watch(self.collection.subscriber,
|
||||
&empty, options);
|
||||
|
||||
if (mongoc_change_stream_error_document(ogs_mongoc()->stream, &error,
|
||||
&err_doc)) {
|
||||
if (!bson_empty (err_doc)) {
|
||||
ogs_error("Change Stream Error. Enable replica sets to "
|
||||
"enable database updates to be sent to MME.");
|
||||
} else {
|
||||
ogs_error("Client Error: %s\n", error.message);
|
||||
}
|
||||
return OGS_ERROR;
|
||||
} else {
|
||||
ogs_info("Change Streams are Enabled.");
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int ogs_dbi_poll_change_stream(void)
|
||||
{
|
||||
int rv;
|
||||
|
||||
const bson_t *document;
|
||||
const bson_t *err_document;
|
||||
bson_error_t error;
|
||||
|
||||
while (mongoc_change_stream_next(ogs_mongoc()->stream, &document)) {
|
||||
rv = ogs_dbi_process_change_stream(document);
|
||||
if (rv != OGS_OK) return rv;
|
||||
}
|
||||
|
||||
if (mongoc_change_stream_error_document(ogs_mongoc()->stream, &error,
|
||||
&err_document)) {
|
||||
if (!bson_empty (err_document)) {
|
||||
ogs_debug("Server Error: %s\n",
|
||||
bson_as_relaxed_extended_json(err_document, NULL));
|
||||
} else {
|
||||
ogs_debug("Client Error: %s\n", error.message);
|
||||
}
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ typedef struct ogs_mongoc_s {
|
|||
void *client;
|
||||
void *database;
|
||||
|
||||
mongoc_change_stream_t *stream;
|
||||
|
||||
char *masked_db_uri;
|
||||
|
||||
struct {
|
||||
|
@ -51,6 +53,9 @@ ogs_mongoc_t *ogs_mongoc(void);
|
|||
int ogs_dbi_init(const char *db_uri);
|
||||
void ogs_dbi_final(void);
|
||||
|
||||
int ogs_dbi_collection_watch_init(void);
|
||||
int ogs_dbi_poll_change_stream(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 "ogs-dbi.h"
|
||||
|
||||
int ogs_dbi_process_change_stream(const bson_t *document)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ogs_event_t *e = NULL;
|
||||
|
||||
e = ogs_event_new(OGS_EVENT_DBI_MESSAGE);
|
||||
ogs_assert(e);
|
||||
e->dbi.document = bson_copy(document);
|
||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||
bson_destroy((bson_t*)e->dbi.document);
|
||||
ogs_event_free(e);
|
||||
} else {
|
||||
ogs_pollset_notify(ogs_app()->pollset);
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef OGS_DBI_PATH_H
|
||||
#define OGS_DBI_PATH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ogs_dbi_process_change_stream(const bson_t *document);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_DBI_PATH_H */
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "ogs-dbi.h"
|
||||
|
||||
static void timer_send_event(int timer_id, void *data)
|
||||
{
|
||||
int rv;
|
||||
ogs_event_t *e = NULL;
|
||||
|
||||
e = ogs_event_new(OGS_EVENT_DBI_POLL_TIMER);
|
||||
ogs_assert(e);
|
||||
e->timer_id = timer_id;
|
||||
|
||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||
ogs_event_free(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ogs_timer_dbi_poll_change_stream(void *data)
|
||||
{
|
||||
timer_send_event(OGS_TIMER_DBI_POLL_CHANGE_STREAM, data);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 OGS_DBI_TIMER_H
|
||||
#define OGS_DBI_TIMER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ogs_timer_dbi_poll_change_stream(void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_DBI_TIMER_H */
|
|
@ -39,7 +39,7 @@ void ogs_metrics_context_open(ogs_metrics_context_t *ctx);
|
|||
void ogs_metrics_context_close(ogs_metrics_context_t *ctx);
|
||||
void ogs_metrics_context_final(void);
|
||||
ogs_metrics_context_t *ogs_metrics_self(void);
|
||||
int ogs_metrics_context_parse_config(void);
|
||||
int ogs_metrics_context_parse_config(const char *local);
|
||||
|
||||
typedef struct ogs_metrics_spec_s ogs_metrics_spec_t;
|
||||
ogs_metrics_spec_t *ogs_metrics_spec_new(
|
||||
|
|
|
@ -104,7 +104,7 @@ ogs_metrics_context_t *ogs_metrics_self(void)
|
|||
return &self;
|
||||
}
|
||||
|
||||
int ogs_metrics_context_parse_config(void)
|
||||
int ogs_metrics_context_parse_config(const char *local)
|
||||
{
|
||||
int family = AF_UNSPEC;
|
||||
const char *hostname = NULL;
|
||||
|
@ -121,17 +121,26 @@ int ogs_metrics_context_parse_config(void)
|
|||
while (ogs_yaml_iter_next(&root_iter)) {
|
||||
const char *root_key = ogs_yaml_iter_key(&root_iter);
|
||||
ogs_assert(root_key);
|
||||
if (!strcmp(root_key, "metrics")) {
|
||||
if (local && !strcmp(root_key, local)) {
|
||||
ogs_yaml_iter_t local_iter;
|
||||
ogs_yaml_iter_recurse(&root_iter, &local_iter);
|
||||
while (ogs_yaml_iter_next(&local_iter)) {
|
||||
const char *local_key = ogs_yaml_iter_key(&local_iter);
|
||||
if (!strcmp(local_key, "addr")) {
|
||||
if ((v = ogs_yaml_iter_value(&local_iter)))
|
||||
hostname = v;
|
||||
} else if (!strcmp(local_key, "port")) {
|
||||
if ((v = ogs_yaml_iter_value(&local_iter)))
|
||||
port = atoi(v);
|
||||
ogs_assert(local_key);
|
||||
if (!strcmp(local_key, "metrics")) {
|
||||
ogs_yaml_iter_t metrics_iter;
|
||||
ogs_yaml_iter_recurse(&local_iter, &metrics_iter);
|
||||
while (ogs_yaml_iter_next(&metrics_iter)) {
|
||||
const char *metrics_key = ogs_yaml_iter_key(&metrics_iter);
|
||||
ogs_assert(metrics_key);
|
||||
if (!strcmp(metrics_key, "addr")) {
|
||||
if ((v = ogs_yaml_iter_value(&metrics_iter)))
|
||||
hostname = v;
|
||||
} else if (!strcmp(metrics_key, "port")) {
|
||||
if ((v = ogs_yaml_iter_value(&metrics_iter)))
|
||||
port = atoi(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ ogs_metrics_context_t *ogs_metrics_self(void)
|
|||
return &self;
|
||||
}
|
||||
|
||||
int ogs_metrics_context_parse_config(void)
|
||||
int ogs_metrics_context_parse_config(const char *local)
|
||||
{
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ const char *ogs_event_get_name(ogs_event_t *e)
|
|||
case OGS_EVENT_SBI_TIMER:
|
||||
return OGS_EVENT_NAME_SBI_TIMER;
|
||||
|
||||
case OGS_EVENT_DBI_POLL_TIMER:
|
||||
return "OGS_EVENT_DBI_POLL_TIMER";
|
||||
case OGS_EVENT_DBI_MESSAGE:
|
||||
return "OGS_EVENT_DBI_MESSAGE";
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ typedef enum {
|
|||
OGS_EVENT_SBI_CLIENT,
|
||||
OGS_EVENT_SBI_TIMER,
|
||||
|
||||
OGS_EVENT_DBI_POLL_TIMER,
|
||||
OGS_EVENT_DBI_MESSAGE,
|
||||
|
||||
OGS_MAX_NUM_OF_PROTO_EVENT,
|
||||
|
||||
} ogs_event_e;
|
||||
|
@ -47,6 +50,8 @@ 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 _bson_t bson_t;
|
||||
|
||||
typedef struct ogs_event_s {
|
||||
int id;
|
||||
int timer_id;
|
||||
|
@ -59,6 +64,10 @@ typedef struct ogs_event_s {
|
|||
|
||||
ogs_sbi_message_t *message;
|
||||
} sbi;
|
||||
|
||||
struct {
|
||||
const bson_t *document;
|
||||
} dbi;
|
||||
} ogs_event_t;
|
||||
|
||||
void *ogs_event_size(int id, size_t size);
|
||||
|
|
|
@ -47,6 +47,8 @@ const char *ogs_timer_get_name(int timer_id)
|
|||
return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY;
|
||||
case OGS_TIMER_SBI_CLIENT_WAIT:
|
||||
return OGS_TIMER_NAME_SBI_CLIENT_WAIT;
|
||||
case OGS_TIMER_DBI_POLL_CHANGE_STREAM:
|
||||
return "OGS_TIMER_DBI_POLL_CHANGE_STREAM";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ typedef enum {
|
|||
OGS_TIMER_SUBSCRIPTION_VALIDITY,
|
||||
OGS_TIMER_SBI_CLIENT_WAIT,
|
||||
|
||||
OGS_TIMER_DBI_POLL_CHANGE_STREAM,
|
||||
|
||||
OGS_MAX_NUM_OF_PROTO_TIMER,
|
||||
|
||||
} ogs_timer_e;
|
||||
|
|
|
@ -81,6 +81,7 @@ extern "C" {
|
|||
#define OGS_MAX_PCO_LEN 251
|
||||
#define OGS_MAX_FQDN_LEN 256
|
||||
|
||||
#define OGS_MAX_NUM_OF_SERVED_GUAMI 8
|
||||
#define OGS_MAX_NUM_OF_SERVED_TAI 16
|
||||
#define OGS_MAX_NUM_OF_ALGORITHM 8
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef struct connection_s {
|
|||
|
||||
char *memory;
|
||||
size_t size;
|
||||
bool memory_overflow;
|
||||
|
||||
char *location;
|
||||
|
||||
|
@ -533,6 +534,8 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
|||
|
||||
res = resource->data.result;
|
||||
if (res == CURLE_OK) {
|
||||
ogs_log_level_e level = OGS_LOG_DEBUG;
|
||||
|
||||
response = ogs_sbi_response_new();
|
||||
ogs_assert(response);
|
||||
|
||||
|
@ -546,7 +549,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
|||
response->h.uri = ogs_strdup(url);
|
||||
ogs_assert(response->h.uri);
|
||||
|
||||
ogs_debug("[%d:%s] %s",
|
||||
if (content_type)
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
OGS_SBI_CONTENT_TYPE, content_type);
|
||||
if (conn->location)
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
OGS_SBI_LOCATION, conn->location);
|
||||
|
||||
if (conn->memory_overflow == true)
|
||||
level = OGS_LOG_ERROR;
|
||||
|
||||
ogs_log_message(level, 0, "[%d:%s] %s",
|
||||
response->status, response->h.method, response->h.uri);
|
||||
|
||||
if (conn->memory) {
|
||||
|
@ -557,16 +570,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
|||
ogs_assert(response->http.content_length);
|
||||
}
|
||||
|
||||
ogs_debug("RECEIVED[%d]", (int)response->http.content_length);
|
||||
ogs_log_message(level, 0, "RECEIVED[%d]",
|
||||
(int)response->http.content_length);
|
||||
if (response->http.content_length && response->http.content)
|
||||
ogs_debug("%s", response->http.content);
|
||||
ogs_log_message(level, 0, "%s", response->http.content);
|
||||
|
||||
if (conn->memory_overflow == true) {
|
||||
ogs_sbi_response_free(response);
|
||||
connection_remove(conn);
|
||||
break;
|
||||
}
|
||||
|
||||
if (content_type)
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
OGS_SBI_CONTENT_TYPE, content_type);
|
||||
if (conn->location)
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
OGS_SBI_LOCATION, conn->location);
|
||||
} else
|
||||
ogs_warn("[%d] %s", res, conn->error);
|
||||
|
||||
|
@ -727,8 +741,12 @@ static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data)
|
|||
realsize = size * nmemb;
|
||||
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
ogs_fatal("not enough memory (realloc returned NULL)");
|
||||
ogs_assert_if_reached();
|
||||
conn->memory_overflow = true;
|
||||
|
||||
ogs_error("Overflow : conn->size[%d], realsize[%d]",
|
||||
(int)conn->size, (int)realsize);
|
||||
ogs_log_hexdump(OGS_LOG_ERROR, contents, realsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1189,6 +1189,11 @@ ogs_sbi_nf_info_t *ogs_sbi_nf_info_add(
|
|||
return nf_info;
|
||||
}
|
||||
|
||||
static void amf_info_free(ogs_sbi_amf_info_t *amf_info)
|
||||
{
|
||||
/* Nothing */
|
||||
}
|
||||
|
||||
static void smf_info_free(ogs_sbi_smf_info_t *smf_info)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -1214,6 +1219,9 @@ void ogs_sbi_nf_info_remove(ogs_list_t *list, ogs_sbi_nf_info_t *nf_info)
|
|||
ogs_list_remove(list, nf_info);
|
||||
|
||||
switch(nf_info->nf_type) {
|
||||
case OpenAPI_nf_type_AMF:
|
||||
amf_info_free(&nf_info->amf);
|
||||
break;
|
||||
case OpenAPI_nf_type_SMF:
|
||||
smf_info_free(&nf_info->smf);
|
||||
break;
|
||||
|
|
|
@ -255,12 +255,37 @@ typedef struct ogs_sbi_smf_info_s {
|
|||
} nr_tai_range[OGS_MAX_NUM_OF_TAI];
|
||||
} ogs_sbi_smf_info_t;
|
||||
|
||||
typedef struct ogs_sbi_amf_info_s {
|
||||
int amf_set_id;
|
||||
int amf_region_id;
|
||||
|
||||
int num_of_guami;
|
||||
ogs_guami_t guami[OGS_MAX_NUM_OF_SERVED_GUAMI];
|
||||
|
||||
int num_of_nr_tai;
|
||||
ogs_5gs_tai_t nr_tai[OGS_MAX_NUM_OF_TAI];
|
||||
|
||||
int num_of_nr_tai_range;
|
||||
struct {
|
||||
ogs_plmn_id_t plmn_id;
|
||||
/*
|
||||
* TS29.510 6.1.6.2.28 Type: TacRange
|
||||
*
|
||||
* Either the start and end attributes, or
|
||||
* the pattern attribute, shall be present.
|
||||
*/
|
||||
int num_of_tac_range;
|
||||
ogs_uint24_t start[OGS_MAX_NUM_OF_TAI], end[OGS_MAX_NUM_OF_TAI];
|
||||
} nr_tai_range[OGS_MAX_NUM_OF_TAI];
|
||||
} ogs_sbi_amf_info_t;
|
||||
|
||||
typedef struct ogs_sbi_nf_info_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
OpenAPI_nf_type_e nf_type;
|
||||
union {
|
||||
ogs_sbi_smf_info_t smf;
|
||||
ogs_sbi_amf_info_t amf;
|
||||
};
|
||||
} ogs_sbi_nf_info_t;
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef struct ogs_sbi_stream_s {
|
|||
|
||||
int32_t stream_id;
|
||||
ogs_sbi_request_t *request;
|
||||
bool memory_overflow;
|
||||
|
||||
ogs_sbi_session_t *session;
|
||||
} ogs_sbi_stream_t;
|
||||
|
@ -791,12 +792,23 @@ static int on_frame_recv(nghttp2_session *session,
|
|||
case NGHTTP2_DATA:
|
||||
/* HEADERS or DATA frame with +END_STREAM flag */
|
||||
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
||||
ogs_log_level_e level = OGS_LOG_DEBUG;
|
||||
|
||||
ogs_debug("[%s] %s", request->h.method, request->h.uri);
|
||||
if (stream->memory_overflow == true)
|
||||
level = OGS_LOG_ERROR;
|
||||
|
||||
ogs_log_message(level, 0,
|
||||
"[%s] %s", request->h.method, request->h.uri);
|
||||
|
||||
if (request->http.content_length && request->http.content) {
|
||||
ogs_debug("RECEIVED: %d", (int)request->http.content_length);
|
||||
ogs_debug("%s", request->http.content);
|
||||
ogs_log_message(level, 0,
|
||||
"RECEIVED: %d", (int)request->http.content_length);
|
||||
ogs_log_message(level, 0, "%s", request->http.content);
|
||||
}
|
||||
|
||||
if (stream->memory_overflow == true) {
|
||||
ogs_error("[DROP] Overflow");
|
||||
break;
|
||||
}
|
||||
|
||||
if (server->cb(request, stream) != OGS_OK) {
|
||||
|
@ -967,23 +979,30 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||
ogs_assert(len);
|
||||
|
||||
if (request->http.content == NULL) {
|
||||
request->http.content_length = len;
|
||||
request->http.content =
|
||||
(char*)ogs_malloc(request->http.content_length + 1);
|
||||
ogs_assert(request->http.content);
|
||||
ogs_assert(request->http.content_length == 0);
|
||||
ogs_assert(offset == 0);
|
||||
|
||||
request->http.content = (char*)ogs_malloc(len + 1);
|
||||
} else {
|
||||
offset = request->http.content_length;
|
||||
if ((request->http.content_length + len) > OGS_HUGE_LEN) {
|
||||
ogs_error("Overflow : Content-Length[%d], len[%d]",
|
||||
(int)request->http.content_length, (int)len);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
request->http.content_length += len;
|
||||
request->http.content = (char *)ogs_realloc(
|
||||
request->http.content, request->http.content_length + 1);
|
||||
ogs_assert(request->http.content);
|
||||
ogs_assert(request->http.content_length != 0);
|
||||
|
||||
request->http.content = (char*)ogs_realloc(
|
||||
request->http.content, request->http.content_length + len + 1);
|
||||
}
|
||||
|
||||
if (!request->http.content) {
|
||||
stream->memory_overflow = true;
|
||||
|
||||
ogs_error("Overflow : Content-Length[%d], len[%d]",
|
||||
(int)request->http.content_length, (int)len);
|
||||
ogs_log_hexdump(OGS_LOG_ERROR, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset = request->http.content_length;
|
||||
request->http.content_length += len;
|
||||
|
||||
memcpy(request->http.content + offset, data, len);
|
||||
request->http.content[request->http.content_length] = '\0';
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@ static OpenAPI_nf_service_t *build_nf_service(
|
|||
ogs_sbi_nf_service_t *nf_service);
|
||||
static void free_nf_service(OpenAPI_nf_service_t *NFService);
|
||||
static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info);
|
||||
static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info);
|
||||
static void free_smf_info(OpenAPI_smf_info_t *SmfInfo);
|
||||
static void free_amf_info(OpenAPI_amf_info_t *AmfInfo);
|
||||
|
||||
ogs_sbi_request_t *ogs_nnrf_nfm_build_register(void)
|
||||
{
|
||||
|
@ -79,13 +81,15 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
|
|||
OpenAPI_list_t *AllowedNfTypeList = NULL;
|
||||
OpenAPI_list_t *NFServiceList = NULL;
|
||||
OpenAPI_map_t *NFServiceMap = NULL;
|
||||
OpenAPI_list_t *SmfInfoList = NULL;
|
||||
OpenAPI_map_t *SmfInfoMap = NULL;
|
||||
OpenAPI_list_t *InfoList = NULL;
|
||||
OpenAPI_map_t *InfoMap = NULL;
|
||||
OpenAPI_smf_info_t *SmfInfo = NULL;
|
||||
int SmfInfoMapKey;
|
||||
int InfoMapKey;
|
||||
|
||||
OpenAPI_lnode_t *node = NULL;
|
||||
|
||||
OpenAPI_amf_info_t *AmfInfo = NULL;
|
||||
|
||||
int i = 0;
|
||||
char *ipstr = NULL;
|
||||
|
||||
|
@ -222,10 +226,10 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
|
|||
} else
|
||||
OpenAPI_list_free(NFServiceList);
|
||||
|
||||
SmfInfoList = OpenAPI_list_create();
|
||||
ogs_assert(SmfInfoList);
|
||||
InfoList = OpenAPI_list_create();
|
||||
ogs_assert(InfoList);
|
||||
|
||||
SmfInfoMapKey = 0;
|
||||
InfoMapKey = 0;
|
||||
|
||||
ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
|
||||
if (nf_info->nf_type == OpenAPI_nf_type_SMF) {
|
||||
|
@ -238,11 +242,21 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
|
|||
SmfInfo = build_smf_info(nf_info);
|
||||
ogs_expect_or_return_val(SmfInfo, NULL);
|
||||
|
||||
SmfInfoMap = OpenAPI_map_create(
|
||||
ogs_msprintf("%d", ++SmfInfoMapKey), SmfInfo);
|
||||
ogs_assert(SmfInfoMap);
|
||||
InfoMap = OpenAPI_map_create(
|
||||
ogs_msprintf("%d", ++InfoMapKey), SmfInfo);
|
||||
ogs_assert(InfoMap);
|
||||
|
||||
OpenAPI_list_add(SmfInfoList, SmfInfoMap);
|
||||
OpenAPI_list_add(InfoList, InfoMap);
|
||||
|
||||
} else if (nf_info->nf_type == OpenAPI_nf_type_AMF) {
|
||||
AmfInfo = build_amf_info(nf_info);
|
||||
ogs_expect_or_return_val(AmfInfo, NULL);
|
||||
|
||||
InfoMap = OpenAPI_map_create(
|
||||
ogs_msprintf("%d", ++InfoMapKey), AmfInfo);
|
||||
ogs_assert(InfoMap);
|
||||
|
||||
OpenAPI_list_add(InfoList, InfoMap);
|
||||
|
||||
} else {
|
||||
ogs_fatal("Not implemented NF-type[%s]",
|
||||
|
@ -250,23 +264,37 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
|
|||
ogs_assert_if_reached();
|
||||
}
|
||||
}
|
||||
|
||||
if (SmfInfoList->count == 1) {
|
||||
NFProfile->smf_info = SmfInfo;
|
||||
|
||||
OpenAPI_list_for_each(SmfInfoList, node) {
|
||||
SmfInfoMap = node->data;
|
||||
if (SmfInfoMap) {
|
||||
if (SmfInfoMap->key)
|
||||
ogs_free(SmfInfoMap->key);
|
||||
ogs_free(SmfInfoMap);
|
||||
if (InfoList->count == 1) {
|
||||
if (nf_instance->nf_type == OpenAPI_nf_type_SMF) {
|
||||
NFProfile->smf_info = SmfInfo;
|
||||
} else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) {
|
||||
NFProfile->amf_info = AmfInfo;
|
||||
} else {
|
||||
ogs_fatal("Not implemented NF-type[%s]",
|
||||
OpenAPI_nf_type_ToString(nf_instance->nf_type));
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
OpenAPI_list_for_each(InfoList, node) {
|
||||
InfoMap = node->data;
|
||||
if (InfoMap) {
|
||||
if (InfoMap->key)
|
||||
ogs_free(InfoMap->key);
|
||||
ogs_free(InfoMap);
|
||||
}
|
||||
}
|
||||
OpenAPI_list_free(SmfInfoList);
|
||||
} else if (SmfInfoList->count > 1) {
|
||||
NFProfile->smf_info_list = SmfInfoList;
|
||||
OpenAPI_list_free(InfoList);
|
||||
} else if (InfoList->count > 1) {
|
||||
if (nf_instance->nf_type == OpenAPI_nf_type_SMF) {
|
||||
NFProfile->smf_info_list = InfoList;
|
||||
} else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) {
|
||||
NFProfile->amf_info_list = InfoList;
|
||||
} else {
|
||||
ogs_fatal("Not implemented NF-type[%s]",
|
||||
OpenAPI_nf_type_ToString(nf_instance->nf_type));
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
} else
|
||||
OpenAPI_list_free(SmfInfoList);
|
||||
OpenAPI_list_free(InfoList);
|
||||
|
||||
return NFProfile;
|
||||
}
|
||||
|
@ -277,6 +305,8 @@ void ogs_nnrf_nfm_free_nf_profile(OpenAPI_nf_profile_t *NFProfile)
|
|||
OpenAPI_nf_service_t *NFService = NULL;
|
||||
OpenAPI_map_t *SmfInfoMap = NULL;
|
||||
OpenAPI_smf_info_t *SmfInfo = NULL;
|
||||
OpenAPI_map_t *AmfInfoMap = NULL;
|
||||
OpenAPI_amf_info_t *AmfInfo = NULL;
|
||||
OpenAPI_lnode_t *node = NULL;
|
||||
|
||||
ogs_assert(NFProfile);
|
||||
|
@ -327,6 +357,22 @@ void ogs_nnrf_nfm_free_nf_profile(OpenAPI_nf_profile_t *NFProfile)
|
|||
if (NFProfile->smf_info)
|
||||
free_smf_info(NFProfile->smf_info);
|
||||
|
||||
OpenAPI_list_for_each(NFProfile->amf_info_list, node) {
|
||||
AmfInfoMap = node->data;
|
||||
if (AmfInfoMap) {
|
||||
AmfInfo = AmfInfoMap->value;
|
||||
if (AmfInfo)
|
||||
free_amf_info(AmfInfo);
|
||||
if (AmfInfoMap->key)
|
||||
ogs_free(AmfInfoMap->key);
|
||||
ogs_free(AmfInfoMap);
|
||||
}
|
||||
}
|
||||
OpenAPI_list_free(NFProfile->amf_info_list);
|
||||
|
||||
if (NFProfile->amf_info)
|
||||
free_amf_info(NFProfile->amf_info);
|
||||
|
||||
ogs_free(NFProfile);
|
||||
}
|
||||
|
||||
|
@ -622,6 +668,124 @@ static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info)
|
|||
return SmfInfo;
|
||||
}
|
||||
|
||||
static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info)
|
||||
{
|
||||
int i, j;
|
||||
OpenAPI_amf_info_t *AmfInfo = NULL;
|
||||
|
||||
OpenAPI_list_t *guamiAmfInfoList = NULL;
|
||||
OpenAPI_guami_t *guamiAmfInfoItem = 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;
|
||||
|
||||
ogs_assert(nf_info);
|
||||
|
||||
AmfInfo = ogs_calloc(1, sizeof(*AmfInfo));
|
||||
ogs_expect_or_return_val(AmfInfo, NULL);
|
||||
|
||||
AmfInfo->amf_set_id = ogs_msprintf("%03x", nf_info->amf.amf_set_id);
|
||||
AmfInfo->amf_region_id = ogs_msprintf("%02x", nf_info->amf.amf_region_id);
|
||||
|
||||
guamiAmfInfoList = OpenAPI_list_create();
|
||||
ogs_assert(guamiAmfInfoList);
|
||||
|
||||
for (i = 0; i < nf_info->amf.num_of_guami; i++) {
|
||||
|
||||
guamiAmfInfoItem = ogs_calloc(1, sizeof(*guamiAmfInfoItem));
|
||||
ogs_expect_or_return_val(guamiAmfInfoItem, NULL);
|
||||
|
||||
guamiAmfInfoItem->plmn_id =
|
||||
ogs_sbi_build_plmn_id_nid(&nf_info->amf.guami[i].plmn_id);
|
||||
ogs_expect_or_return_val(guamiAmfInfoItem->plmn_id, NULL);
|
||||
guamiAmfInfoItem->amf_id =
|
||||
ogs_amf_id_to_string(&nf_info->amf.guami[i].amf_id);
|
||||
ogs_expect_or_return_val(guamiAmfInfoItem->amf_id, NULL);
|
||||
|
||||
OpenAPI_list_add(guamiAmfInfoList, guamiAmfInfoItem);
|
||||
}
|
||||
|
||||
if (guamiAmfInfoList->count)
|
||||
AmfInfo->guami_list = guamiAmfInfoList;
|
||||
else
|
||||
OpenAPI_list_free(guamiAmfInfoList);
|
||||
|
||||
TaiList = OpenAPI_list_create();
|
||||
ogs_assert(TaiList);
|
||||
|
||||
for (i = 0; i < nf_info->amf.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->amf.nr_tai[i].plmn_id);
|
||||
ogs_expect_or_return_val(TaiItem->plmn_id, NULL);
|
||||
TaiItem->tac =
|
||||
ogs_uint24_to_0string(nf_info->amf.nr_tai[i].tac);
|
||||
ogs_expect_or_return_val(TaiItem->tac, NULL);
|
||||
|
||||
OpenAPI_list_add(TaiList, TaiItem);
|
||||
}
|
||||
|
||||
if (TaiList->count)
|
||||
AmfInfo->tai_list = TaiList;
|
||||
else
|
||||
OpenAPI_list_free(TaiList);
|
||||
|
||||
TaiRangeList = OpenAPI_list_create();
|
||||
ogs_assert(TaiRangeList);
|
||||
|
||||
for (i = 0; i < nf_info->amf.num_of_nr_tai_range; i++) {
|
||||
TacRangeList = OpenAPI_list_create();
|
||||
ogs_assert(TacRangeList);
|
||||
|
||||
for (j = 0;
|
||||
j < nf_info->amf.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->amf.nr_tai_range[i].start[j]);
|
||||
ogs_expect_or_return_val(TacRangeItem->start, NULL);
|
||||
TacRangeItem->end =
|
||||
ogs_uint24_to_0string(
|
||||
nf_info->amf.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->amf.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)
|
||||
AmfInfo->tai_range_list = TaiRangeList;
|
||||
else
|
||||
OpenAPI_list_free(TaiRangeList);
|
||||
|
||||
return AmfInfo;
|
||||
}
|
||||
|
||||
static void free_smf_info(OpenAPI_smf_info_t *SmfInfo)
|
||||
{
|
||||
OpenAPI_list_t *sNssaiSmfInfoList = NULL;
|
||||
|
@ -705,6 +869,84 @@ static void free_smf_info(OpenAPI_smf_info_t *SmfInfo)
|
|||
ogs_free(SmfInfo);
|
||||
}
|
||||
|
||||
static void free_amf_info(OpenAPI_amf_info_t *AmfInfo)
|
||||
{
|
||||
OpenAPI_list_t *guamiAmfInfoList = NULL;
|
||||
OpenAPI_guami_t *guamiAmfInfoItem = 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;
|
||||
|
||||
ogs_assert(AmfInfo);
|
||||
|
||||
ogs_free(AmfInfo->amf_set_id);
|
||||
ogs_free(AmfInfo->amf_region_id);
|
||||
|
||||
guamiAmfInfoList = AmfInfo->guami_list;
|
||||
OpenAPI_list_for_each(guamiAmfInfoList, node) {
|
||||
guamiAmfInfoItem = node->data;
|
||||
if (guamiAmfInfoItem) {
|
||||
if (guamiAmfInfoItem->plmn_id) {
|
||||
if (guamiAmfInfoItem->plmn_id->mcc)
|
||||
ogs_free(guamiAmfInfoItem->plmn_id->mcc);
|
||||
if (guamiAmfInfoItem->plmn_id->mnc)
|
||||
ogs_free(guamiAmfInfoItem->plmn_id->mnc);
|
||||
ogs_free(guamiAmfInfoItem->plmn_id);
|
||||
}
|
||||
if (guamiAmfInfoItem->amf_id)
|
||||
ogs_free(guamiAmfInfoItem->amf_id);
|
||||
}
|
||||
ogs_free(guamiAmfInfoItem);
|
||||
}
|
||||
|
||||
OpenAPI_list_free(guamiAmfInfoList);
|
||||
|
||||
TaiList = AmfInfo->tai_list;
|
||||
OpenAPI_list_for_each(TaiList, node) {
|
||||
TaiItem = node->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 = AmfInfo->tai_range_list;
|
||||
OpenAPI_list_for_each(TaiRangeList, node) {
|
||||
TaiRangeItem = node->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, node2) {
|
||||
TacRangeItem = node2->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(AmfInfo);
|
||||
}
|
||||
|
||||
ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void)
|
||||
{
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
|
|
|
@ -330,7 +330,7 @@ int amf_context_parse_config(void)
|
|||
const char *region = NULL, *set = NULL;
|
||||
const char *pointer = NULL;
|
||||
ogs_assert(self.num_of_served_guami <
|
||||
MAX_NUM_OF_SERVED_GUAMI);
|
||||
OGS_MAX_NUM_OF_SERVED_GUAMI);
|
||||
|
||||
if (ogs_yaml_iter_type(&guami_array) ==
|
||||
YAML_MAPPING_NODE) {
|
||||
|
@ -825,6 +825,8 @@ int amf_context_parse_config(void)
|
|||
/* handle config in sbi library */
|
||||
} else if (!strcmp(amf_key, "discovery")) {
|
||||
/* handle config in sbi library */
|
||||
} else if (!strcmp(amf_key, "metrics")) {
|
||||
/* handle config in metrics library */
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", amf_key);
|
||||
}
|
||||
|
@ -837,6 +839,97 @@ int amf_context_parse_config(void)
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
int amf_context_nf_info(void)
|
||||
{
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
ogs_sbi_nf_info_t *nf_info = NULL;
|
||||
|
||||
int served_i, next_new_i, info_i;
|
||||
bool next_found;
|
||||
served_i = 0;
|
||||
next_new_i = 0;
|
||||
next_found = false;
|
||||
do {
|
||||
nf_instance = ogs_sbi_self()->nf_instance;
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
nf_info = ogs_sbi_nf_info_add(
|
||||
&nf_instance->nf_info_list, OpenAPI_nf_type_AMF);
|
||||
ogs_assert(nf_info);
|
||||
nf_info->amf.amf_set_id = self.served_guami[next_new_i].amf_id.set2;
|
||||
nf_info->amf.amf_region_id = self.served_guami[next_new_i].amf_id.region;
|
||||
next_found = false;
|
||||
info_i = 0;
|
||||
for (served_i = next_new_i; served_i <
|
||||
self.num_of_served_guami; served_i++) {
|
||||
if (self.served_guami[served_i].amf_id.set2 ==
|
||||
nf_info->amf.amf_set_id &&
|
||||
self.served_guami[served_i].amf_id.region ==
|
||||
nf_info->amf.amf_region_id) {
|
||||
nf_info->amf.guami[info_i] = self.served_guami[served_i];
|
||||
nf_info->amf.num_of_guami++;
|
||||
info_i++;
|
||||
} else {
|
||||
if (!next_found) {
|
||||
int handled_i;
|
||||
for (handled_i = 0; handled_i < served_i; handled_i++) {
|
||||
if (self.served_guami[handled_i].amf_id.set2 ==
|
||||
self.served_guami[served_i].amf_id.set2 &&
|
||||
self.served_guami[handled_i].amf_id.region ==
|
||||
self.served_guami[served_i].amf_id.region) {
|
||||
break;
|
||||
}
|
||||
next_found = true;
|
||||
next_new_i = served_i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nf_info->amf.num_of_nr_tai = 0;
|
||||
int i = 0, j = 0, info_tai_i = 0;
|
||||
for (i = 0; i < self.num_of_served_tai; i++) {
|
||||
if (self.served_tai[i].list2.num) {
|
||||
for (j = 0; j < self.served_tai[i].list2.num; j++) {
|
||||
for (served_i = 0; served_i < info_i; served_i++) {
|
||||
if (ogs_plmn_id_hexdump
|
||||
(&self.served_tai[i].list2.tai[j].plmn_id) ==
|
||||
ogs_plmn_id_hexdump
|
||||
(&nf_info->amf.guami[served_i].plmn_id)) {
|
||||
nf_info->amf.nr_tai[info_tai_i].plmn_id =
|
||||
self.served_tai[i].list2.tai[j].plmn_id;
|
||||
nf_info->amf.nr_tai[info_tai_i].tac =
|
||||
self.served_tai[i].list2.tai[j].tac;
|
||||
nf_info->amf.num_of_nr_tai++;
|
||||
info_tai_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = 0; self.served_tai[i].list0.tai[j].num; j++) {
|
||||
int k = 0;
|
||||
for (k = 0; k < self.served_tai[i].list0.tai[j].num; k++) {
|
||||
for (served_i = 0; served_i < info_i; served_i++) {
|
||||
if (ogs_plmn_id_hexdump
|
||||
(&self.served_tai[i].list0.tai[j].plmn_id) ==
|
||||
ogs_plmn_id_hexdump
|
||||
(&nf_info->amf.guami[served_i].plmn_id)) {
|
||||
nf_info->amf.nr_tai[info_tai_i].plmn_id =
|
||||
self.served_tai[i].list0.tai[j].plmn_id;
|
||||
nf_info->amf.nr_tai[info_tai_i].tac =
|
||||
self.served_tai[i].list0.tai[j].tac[k];
|
||||
nf_info->amf.num_of_nr_tai++;
|
||||
info_tai_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (next_found);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
|
||||
{
|
||||
amf_gnb_t *gnb = NULL;
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
extern int __amf_log_domain;
|
||||
extern int __gmm_log_domain;
|
||||
|
||||
|
@ -50,7 +48,7 @@ typedef uint32_t amf_m_tmsi_t;
|
|||
typedef struct amf_context_s {
|
||||
/* Served GUAMI */
|
||||
uint8_t num_of_served_guami;
|
||||
ogs_guami_t served_guami[MAX_NUM_OF_SERVED_GUAMI];
|
||||
ogs_guami_t served_guami[OGS_MAX_NUM_OF_SERVED_GUAMI];
|
||||
|
||||
/* Served TAI */
|
||||
uint8_t num_of_served_tai;
|
||||
|
@ -613,6 +611,7 @@ void amf_context_final(void);
|
|||
amf_context_t *amf_self(void);
|
||||
|
||||
int amf_context_parse_config(void);
|
||||
int amf_context_nf_info(void);
|
||||
|
||||
amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr);
|
||||
void amf_gnb_remove(amf_gnb_t *gnb);
|
||||
|
|
|
@ -37,12 +37,15 @@ int amf_initialize()
|
|||
rv = ogs_sbi_context_parse_config("amf", "nrf", "scp");
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = ogs_metrics_context_parse_config();
|
||||
rv = ogs_metrics_context_parse_config("amf");
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = amf_context_parse_config();
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = amf_context_nf_info();
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = amf_m_tmsi_pool_generate();
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
extern int __ausf_log_domain;
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#include "ogs-dbi.h"
|
||||
#include "hss-context.h"
|
||||
#include "hss-event.h"
|
||||
#include "hss-s6a-path.h"
|
||||
|
||||
|
||||
typedef struct hss_impi_s hss_impi_t;
|
||||
|
||||
|
@ -680,7 +683,7 @@ void hss_cx_associate_identity(char *user_name, char *public_identity)
|
|||
{
|
||||
hss_impi_t *impi = NULL;
|
||||
hss_impu_t *impu = NULL;
|
||||
|
||||
|
||||
ogs_assert(user_name);
|
||||
ogs_assert(public_identity);
|
||||
|
||||
|
@ -1171,3 +1174,134 @@ char *hss_cx_download_user_data(
|
|||
|
||||
return user_data;
|
||||
}
|
||||
|
||||
int hss_db_poll_change_stream(void)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ogs_thread_mutex_lock(&self.db_lock);
|
||||
|
||||
rv = ogs_dbi_poll_change_stream();
|
||||
|
||||
ogs_thread_mutex_unlock(&self.db_lock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int hss_handle_change_event(const bson_t *document)
|
||||
{
|
||||
bson_iter_t iter, child1_iter, child2_iter, child3_iter;
|
||||
|
||||
char *utf8 = NULL;
|
||||
uint32_t length = 0;
|
||||
|
||||
bool send_clr_flag = false;
|
||||
bool send_idr_flag = false;
|
||||
uint32_t subdatamask = 0;
|
||||
|
||||
char *imsi_bcd;
|
||||
|
||||
char *as_json = bson_as_relaxed_extended_json(document, NULL);
|
||||
ogs_debug("Got document: %s\n", as_json);
|
||||
if (!bson_iter_init_find(&iter, document, "fullDocument")) {
|
||||
ogs_error("No 'imsi' field in this document.");
|
||||
return OGS_ERROR;
|
||||
} else {
|
||||
bson_iter_recurse(&iter, &child1_iter);
|
||||
while (bson_iter_next(&child1_iter)) {
|
||||
const char *key = bson_iter_key(&child1_iter);
|
||||
if (!strcmp(key, "imsi") &&
|
||||
BSON_ITER_HOLDS_UTF8(&child1_iter)) {
|
||||
utf8 = (char *)bson_iter_utf8(&child1_iter, &length);
|
||||
imsi_bcd = ogs_strndup(utf8,
|
||||
ogs_min(length, OGS_MAX_IMSI_BCD_LEN) + 1);
|
||||
ogs_assert(imsi_bcd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!imsi_bcd) {
|
||||
ogs_error("No 'imsi' field in this document.");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
if (bson_iter_init_find(&iter, document, "updateDescription")) {
|
||||
bson_iter_recurse(&iter, &child1_iter);
|
||||
while (bson_iter_next(&child1_iter)) {
|
||||
const char *key = bson_iter_key(&child1_iter);
|
||||
if (!strcmp(key, "updatedFields") &&
|
||||
BSON_ITER_HOLDS_DOCUMENT(&child1_iter)) {
|
||||
bson_iter_recurse(&child1_iter, &child2_iter);
|
||||
while (bson_iter_next(&child2_iter)) {
|
||||
const char *child2_key = bson_iter_key(&child2_iter);
|
||||
if (!strcmp(child2_key,
|
||||
"request_cancel_location") &&
|
||||
BSON_ITER_HOLDS_BOOL(&child2_iter)) {
|
||||
send_clr_flag = (char *)bson_iter_bool(&child2_iter);
|
||||
} else if (!strncmp(child2_key, "msisdn",
|
||||
strlen("msisdn"))) {
|
||||
int msisdn_count = 0;
|
||||
bson_iter_recurse(&child2_iter, &child3_iter);
|
||||
while (bson_iter_next(&child3_iter)) {
|
||||
if (BSON_ITER_HOLDS_UTF8(&child3_iter)) {
|
||||
msisdn_count++;
|
||||
}
|
||||
}
|
||||
if (msisdn_count) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask |
|
||||
OGS_HSS_SUBDATA_MSISDN);
|
||||
} else {
|
||||
send_clr_flag = true;
|
||||
}
|
||||
} else if (!strncmp(child2_key,
|
||||
"access_restriction_data",
|
||||
strlen("access_restriction_data"))) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask | OGS_HSS_SUBDATA_ARD);
|
||||
} else if (!strncmp(child2_key,
|
||||
"subscriber_status",
|
||||
strlen("subscriber_status"))) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask |
|
||||
OGS_HSS_SUBDATA_SUB_STATUS);
|
||||
} else if (!strncmp(child2_key,
|
||||
"network_access_mode",
|
||||
strlen("network_access_mode"))) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask | OGS_HSS_SUBDATA_NAM);
|
||||
} else if (!strncmp(child2_key, "ambr", strlen("ambr"))) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask | OGS_HSS_SUBDATA_UEAMBR);
|
||||
} else if (!strncmp(child2_key,
|
||||
"subscribed_rau_tau_timer",
|
||||
strlen("subscribed_rau_tau_timer"))) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask |
|
||||
OGS_HSS_SUBDATA_RAU_TAU_TIMER);
|
||||
} else if (!strncmp(child2_key, "slice", strlen("slice"))) {
|
||||
send_idr_flag = true;
|
||||
subdatamask = (subdatamask | OGS_HSS_SUBDATA_SLICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ogs_debug("No 'updateDescription' field in this document");
|
||||
}
|
||||
|
||||
bson_free (as_json);
|
||||
|
||||
if (send_clr_flag) {
|
||||
ogs_info("[%s] Cancel Location Requested", imsi_bcd);
|
||||
hss_s6a_send_clr(imsi_bcd, NULL, NULL,
|
||||
OGS_DIAM_S6A_CT_SUBSCRIPTION_WITHDRAWL);
|
||||
} else if (send_idr_flag) {
|
||||
ogs_info("[%s] Subscription-Data Changed", imsi_bcd);
|
||||
hss_s6a_send_idr(imsi_bcd, 0, subdatamask);
|
||||
}
|
||||
|
||||
ogs_free(imsi_bcd);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,9 @@ char *hss_cx_download_user_data(
|
|||
char *user_name, char *visited_network_identifier,
|
||||
ogs_ims_data_t *ims_data);
|
||||
|
||||
int hss_db_poll_change_stream(void);
|
||||
int hss_handle_change_event(const bson_t *document);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "hss-event.h"
|
||||
#include "ogs-app.h"
|
||||
|
||||
void hss_event_term(void)
|
||||
{
|
||||
ogs_queue_term(ogs_app()->queue);
|
||||
ogs_pollset_notify(ogs_app()->pollset);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 HSS_EVENT_H
|
||||
#define HSS_EVENT_H
|
||||
|
||||
#include "ogs-core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void hss_event_term(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HSS_EVENT_H */
|
|
@ -39,4 +39,3 @@ void hss_swx_final(void);
|
|||
#endif
|
||||
|
||||
#endif /* HSS_FD_PATH_H */
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
|
||||
#include "hss-context.h"
|
||||
#include "hss-fd-path.h"
|
||||
#include "hss-sm.h"
|
||||
|
||||
|
||||
static ogs_thread_t *thread;
|
||||
static void hss_main(void *data);
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
|
@ -41,6 +46,9 @@ int hss_initialize(void)
|
|||
rv = hss_fd_init();
|
||||
if (rv != OGS_OK) return OGS_ERROR;
|
||||
|
||||
thread = ogs_thread_create(hss_main, NULL);
|
||||
if (!thread) return OGS_ERROR;
|
||||
|
||||
initialized = 1;
|
||||
|
||||
return OGS_OK;
|
||||
|
@ -50,6 +58,9 @@ void hss_terminate(void)
|
|||
{
|
||||
if (!initialized) return;
|
||||
|
||||
hss_event_term();
|
||||
ogs_thread_destroy(thread);
|
||||
|
||||
hss_fd_final();
|
||||
|
||||
ogs_dbi_final();
|
||||
|
@ -57,3 +68,49 @@ void hss_terminate(void)
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
static void hss_main(void *data)
|
||||
{
|
||||
ogs_fsm_t hss_sm;
|
||||
int rv;
|
||||
|
||||
ogs_fsm_init(&hss_sm, hss_state_initial, hss_state_final, 0);
|
||||
|
||||
for ( ;; ) {
|
||||
ogs_pollset_poll(ogs_app()->pollset,
|
||||
ogs_timer_mgr_next(ogs_app()->timer_mgr));
|
||||
|
||||
/*
|
||||
* After ogs_pollset_poll(), ogs_timer_mgr_expire() must be called.
|
||||
*
|
||||
* The reason is why ogs_timer_mgr_next() can get the corrent value
|
||||
* when ogs_timer_stop() is called internally in ogs_timer_mgr_expire().
|
||||
*
|
||||
* You should not use event-queue before ogs_timer_mgr_expire().
|
||||
* In this case, ogs_timer_mgr_expire() does not work
|
||||
* because 'if rv == OGS_DONE' statement is exiting and
|
||||
* not calling ogs_timer_mgr_expire().
|
||||
*/
|
||||
ogs_timer_mgr_expire(ogs_app()->timer_mgr);
|
||||
|
||||
for ( ;; ) {
|
||||
ogs_event_t *e = NULL;
|
||||
|
||||
rv = ogs_queue_trypop(ogs_app()->queue, (void**)&e);
|
||||
ogs_assert(rv != OGS_ERROR);
|
||||
|
||||
if (rv == OGS_DONE)
|
||||
goto done;
|
||||
|
||||
if (rv == OGS_RETRY)
|
||||
break;
|
||||
|
||||
ogs_assert(e);
|
||||
ogs_fsm_dispatch(&hss_sm, e);
|
||||
ogs_event_free(e);
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
ogs_fsm_fini(&hss_sm, 0);
|
||||
}
|
||||
|
|
|
@ -719,7 +719,7 @@ static int hss_s6a_avp_add_subscription_data(
|
|||
ret = fd_msg_avp_add(apn_configuration_profile,
|
||||
MSG_BRW_LAST_CHILD, apn_configuration);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
|
||||
}
|
||||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD,
|
||||
apn_configuration_profile);
|
||||
|
@ -825,7 +825,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(mme_host);
|
||||
ogs_assert(mme_realm);
|
||||
|
||||
/* If UE is not purged at MME, determine if the MME sending the ULR
|
||||
/* If UE is not purged at MME, determine if the MME sending the ULR
|
||||
* is different from the one that was last used. if so, send CLR.
|
||||
*/
|
||||
if (subscription_data.mme_host != NULL &&
|
||||
|
@ -1269,6 +1269,7 @@ void hss_s6a_send_clr(char *imsi_bcd, char *mme_host, char *mme_realm,
|
|||
ogs_assert(pthread_mutex_lock(&ogs_diam_logger_self()->stats_lock) == 0);
|
||||
ogs_diam_logger_self()->stats.nb_sent++;
|
||||
ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0);
|
||||
|
||||
}
|
||||
|
||||
/* HSS received Cancel Location Answer from MME */
|
||||
|
@ -1286,7 +1287,7 @@ static void hss_s6a_cla_cb(void *data, struct msg **msg)
|
|||
ret = fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new);
|
||||
ogs_expect_or_return(ret == 0);
|
||||
ogs_expect_or_return(new == 0);
|
||||
|
||||
|
||||
ret = fd_sess_state_retrieve(hss_s6a_reg, session, &sess_data);
|
||||
ogs_expect_or_return(ret == 0);
|
||||
ogs_expect_or_return(sess_data);
|
||||
|
@ -1326,8 +1327,8 @@ int hss_s6a_send_idr(char *imsi_bcd, uint32_t idr_flags, uint32_t subdatamask)
|
|||
|
||||
if (subscription_data.purge_flag) {
|
||||
ogs_error(" [%s] UE Purged at MME. Cannot send IDR.", imsi_bcd);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
/* Create the random value to store with the session */
|
||||
sess_data = ogs_calloc(1, sizeof(*sess_data));
|
||||
|
@ -1405,7 +1406,7 @@ int hss_s6a_send_idr(char *imsi_bcd, uint32_t idr_flags, uint32_t subdatamask)
|
|||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
|
||||
/* Set the Subscription Data */
|
||||
ret = fd_msg_avp_new(ogs_diam_s6a_subscription_data, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -1415,11 +1416,11 @@ int hss_s6a_send_idr(char *imsi_bcd, uint32_t idr_flags, uint32_t subdatamask)
|
|||
if (ret != OGS_OK) {
|
||||
ogs_error(" [%s] Could not build Subscription-Data.",
|
||||
imsi_bcd);
|
||||
return OGS_ERROR;
|
||||
return OGS_ERROR;
|
||||
}
|
||||
}
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
/* Set Vendor-Specific-Application-Id AVP */
|
||||
ret = ogs_diam_message_vendor_specific_appid_set(
|
||||
|
@ -1464,7 +1465,7 @@ static void hss_s6a_ida_cb(void *data, struct msg **msg)
|
|||
ret = fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new);
|
||||
ogs_expect_or_return(ret == 0);
|
||||
ogs_expect_or_return(new == 0);
|
||||
|
||||
|
||||
ret = fd_sess_state_retrieve(hss_s6a_reg, session, &sess_data);
|
||||
ogs_expect_or_return(ret == 0);
|
||||
ogs_expect_or_return(sess_data);
|
||||
|
@ -1527,7 +1528,7 @@ int hss_s6a_init(void)
|
|||
void hss_s6a_final(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
ret = fd_sess_handler_destroy(&hss_s6a_reg, NULL);
|
||||
ogs_assert(ret == OGS_OK);
|
||||
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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 "hss-sm.h"
|
||||
#include "hss-context.h"
|
||||
#include "hss-event.h"
|
||||
|
||||
#define DB_POLLING_TIME ogs_time_from_msec(100)
|
||||
|
||||
static ogs_timer_t *t_db_polling = NULL;
|
||||
|
||||
void hss_state_initial(ogs_fsm_t *s, ogs_event_t *e)
|
||||
{
|
||||
hss_sm_debug(e);
|
||||
|
||||
ogs_assert(s);
|
||||
|
||||
if (ogs_app()->use_mongodb_change_stream) {
|
||||
ogs_dbi_collection_watch_init();
|
||||
|
||||
t_db_polling = ogs_timer_add(ogs_app()->timer_mgr,
|
||||
ogs_timer_dbi_poll_change_stream, 0);
|
||||
ogs_assert(t_db_polling);
|
||||
ogs_timer_start(t_db_polling, DB_POLLING_TIME);
|
||||
|
||||
OGS_FSM_TRAN(s, &hss_state_operational);
|
||||
}
|
||||
}
|
||||
|
||||
void hss_state_final(ogs_fsm_t *s, ogs_event_t *e)
|
||||
{
|
||||
hss_sm_debug(e);
|
||||
|
||||
if (t_db_polling)
|
||||
ogs_timer_delete(t_db_polling);
|
||||
|
||||
ogs_assert(s);
|
||||
}
|
||||
|
||||
void hss_state_operational(ogs_fsm_t *s, ogs_event_t *e)
|
||||
{
|
||||
hss_sm_debug(e);
|
||||
|
||||
ogs_assert(s);
|
||||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
break;
|
||||
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
if (t_db_polling) {
|
||||
ogs_timer_stop(t_db_polling);
|
||||
}
|
||||
break;
|
||||
|
||||
case OGS_EVENT_DBI_POLL_TIMER:
|
||||
ogs_assert(e);
|
||||
|
||||
switch(e->timer_id) {
|
||||
case OGS_TIMER_DBI_POLL_CHANGE_STREAM:
|
||||
hss_db_poll_change_stream();
|
||||
ogs_timer_start(t_db_polling, DB_POLLING_TIME);
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown timer[%s:%d]",
|
||||
ogs_timer_get_name(e->timer_id), e->timer_id);
|
||||
}
|
||||
break;
|
||||
|
||||
case OGS_EVENT_DBI_MESSAGE:
|
||||
ogs_assert(e);
|
||||
|
||||
ogs_assert(e->dbi.document);
|
||||
hss_handle_change_event(e->dbi.document);
|
||||
|
||||
bson_destroy((bson_t*)e->dbi.document);
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("No handler for event %s", ogs_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef HSS_SM_H
|
||||
#define HSS_SM_H
|
||||
|
||||
#include "hss-event.h"
|
||||
#include "ogs-proto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void hss_state_initial(ogs_fsm_t *s, ogs_event_t *e);
|
||||
void hss_state_final(ogs_fsm_t *s, ogs_event_t *e);
|
||||
void hss_state_operational(ogs_fsm_t *s, ogs_event_t *e);
|
||||
void hss_state_exception(ogs_fsm_t *s, ogs_event_t *e);
|
||||
|
||||
#define hss_sm_debug(__pe) \
|
||||
ogs_debug("%s(): %s", __func__, ogs_event_get_name(__pe))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HSS_SM_H */
|
|
@ -19,9 +19,13 @@ libhss_sources = files('''
|
|||
hss-context.h
|
||||
hss-fd-path.h
|
||||
hss-s6a-path.h
|
||||
hss-event.h
|
||||
hss-sm.h
|
||||
|
||||
hss-init.c
|
||||
hss-context.c
|
||||
hss-event.c
|
||||
hss-sm.c
|
||||
|
||||
hss-s6a-path.c
|
||||
hss-cx-path.c
|
||||
|
|
|
@ -1277,6 +1277,8 @@ int mme_context_parse_config()
|
|||
YAML_SEQUENCE_NODE);
|
||||
} else if (!strcmp(mme_key, "mme_name")) {
|
||||
self.mme_name = ogs_yaml_iter_value(&mme_iter);
|
||||
} else if (!strcmp(mme_key, "metrics")) {
|
||||
/* handle config in metrics library */
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", mme_key);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ int mme_initialize()
|
|||
rv = ogs_gtp_context_parse_config("mme", "sgwc");
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = ogs_metrics_context_parse_config();
|
||||
rv = ogs_metrics_context_parse_config("mme");
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = mme_context_parse_config();
|
||||
|
|
|
@ -220,7 +220,7 @@ void mme_s11_handle_create_session_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
||||
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
||||
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
||||
ogs_assert(OGS_OK == nas_eps_send_attach_reject(mme_ue,
|
||||
|
@ -240,7 +240,7 @@ void mme_s11_handle_create_session_response(
|
|||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE &&
|
||||
cause_value !=
|
||||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
||||
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
||||
ogs_assert(OGS_OK == nas_eps_send_attach_reject(mme_ue,
|
||||
|
@ -467,7 +467,7 @@ void mme_s11_handle_modify_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||
return;
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ void mme_s11_handle_delete_session_response(
|
|||
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
||||
ogs_error("GTP Failed [CAUSE:%d] - Ignored", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d] - Ignored", cause_value);
|
||||
}
|
||||
|
||||
/********************
|
||||
|
@ -1143,7 +1143,7 @@ void mme_s11_handle_release_access_bearers_response(
|
|||
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
||||
ogs_error("GTP Failed [CAUSE:%d, ACTION:%d]", cause_value, action);
|
||||
ogs_error("GTP Cause [Value:%d, ACTION:%d]", cause_value, action);
|
||||
}
|
||||
|
||||
/********************
|
||||
|
@ -1455,7 +1455,7 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||
return;
|
||||
}
|
||||
|
@ -1571,7 +1571,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||
return;
|
||||
}
|
||||
|
@ -1639,7 +1639,7 @@ void mme_s11_handle_bearer_resource_failure_indication(
|
|||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
ogs_warn("GTP Failed [CAUSE:%d] - Ignored", cause_value);
|
||||
ogs_warn("GTP Cause [Value:%d] - Ignored", cause_value);
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
}
|
||||
|
|
|
@ -102,13 +102,27 @@ uint8_t mme_s6a_handle_ula(
|
|||
break;
|
||||
}
|
||||
|
||||
mme_ue->session[i].name = ogs_strdup(slice_data->session[i].name);
|
||||
ogs_assert(mme_ue->session[i].name);
|
||||
if (slice_data->session[i].name) {
|
||||
mme_ue->session[i].name = ogs_strdup(slice_data->session[i].name);
|
||||
ogs_assert(mme_ue->session[i].name);
|
||||
}
|
||||
|
||||
mme_ue->session[i].context_identifier =
|
||||
slice_data->session[i].context_identifier;
|
||||
|
||||
mme_ue->session[i].session_type = slice_data->session[i].session_type;
|
||||
if (slice_data->session[i].session_type == OGS_PDU_SESSION_TYPE_IPV4 ||
|
||||
slice_data->session[i].session_type == OGS_PDU_SESSION_TYPE_IPV6 ||
|
||||
slice_data->session[i].session_type ==
|
||||
OGS_PDU_SESSION_TYPE_IPV4V6) {
|
||||
mme_ue->session[i].session_type =
|
||||
slice_data->session[i].session_type;
|
||||
} else {
|
||||
ogs_error("Invalid PDN_TYPE[%d]",
|
||||
slice_data->session[i].session_type);
|
||||
if (mme_ue->session[i].name)
|
||||
ogs_free(mme_ue->session[i].name);
|
||||
break;
|
||||
}
|
||||
memcpy(&mme_ue->session[i].paa, &slice_data->session[i].paa,
|
||||
sizeof(mme_ue->session[i].paa));
|
||||
|
||||
|
@ -127,6 +141,11 @@ uint8_t mme_s6a_handle_ula(
|
|||
slice_data->session[i].charging_characteristics_presence;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
ogs_error("No Session");
|
||||
return OGS_NAS_EMM_CAUSE_SEVERE_NETWORK_FAILURE;
|
||||
}
|
||||
|
||||
mme_ue->num_of_session = i;
|
||||
mme_ue->context_identifier = slice_data->context_identifier;
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
extern int __nssf_log_domain;
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
extern int __pcf_log_domain;
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
|
|
|
@ -169,12 +169,16 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
|
|||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
ogs_info("PFCP associated");
|
||||
ogs_info("PFCP associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_start(node->t_no_heartbeat,
|
||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
ogs_info("PFCP de-associated");
|
||||
ogs_info("PFCP de-associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_stop(node->t_no_heartbeat);
|
||||
break;
|
||||
case SGWC_EVT_SXA_MESSAGE:
|
||||
|
@ -206,12 +210,16 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
|
|||
&message->pfcp_heartbeat_response));
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
||||
ogs_warn("PFCP[REQ] has already been associated");
|
||||
ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_cp_handle_association_setup_request(node, xact,
|
||||
&message->pfcp_association_setup_request);
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
||||
ogs_warn("PFCP[RSP] has already been associated");
|
||||
ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_cp_handle_association_setup_response(node, xact,
|
||||
&message->pfcp_association_setup_response);
|
||||
break;
|
||||
|
|
|
@ -766,7 +766,7 @@ void sgwc_s11_handle_create_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_bearer_modification_request(
|
||||
bearer, NULL, NULL,
|
||||
|
@ -919,7 +919,7 @@ void sgwc_s11_handle_update_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
|
@ -929,7 +929,7 @@ void sgwc_s11_handle_update_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
|
@ -1022,7 +1022,7 @@ void sgwc_s11_handle_delete_bearer_response(
|
|||
cause_value = cause->value;
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
|
@ -1062,13 +1062,13 @@ void sgwc_s11_handle_delete_bearer_response(
|
|||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
}
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
|
@ -1172,7 +1172,7 @@ void sgwc_s11_handle_downlink_data_notification_ack(
|
|||
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
||||
ogs_warn("GTP Failed [CAUSE:%d] - PFCP_CAUSE[%d]",
|
||||
ogs_warn("GTP Cause [Value:%d] - PFCP_CAUSE[%d]",
|
||||
cause_value, pfcp_cause_from_gtp(cause_value));
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
|
|
|
@ -79,9 +79,6 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_gtp_xact_t *s11_xact = NULL;
|
||||
ogs_gtp_node_t *pgw = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(gtpbuf);
|
||||
ogs_assert(message);
|
||||
rsp = &message->create_session_response;
|
||||
|
@ -99,10 +96,32 @@ void sgwc_s5c_handle_create_session_response(
|
|||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
*
|
||||
* - Session could be deleted before a message is received from SMF.
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence == 0) {
|
||||
ogs_error("No GTP TEID");
|
||||
|
@ -150,7 +169,7 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
|
@ -167,7 +186,7 @@ void sgwc_s5c_handle_create_session_response(
|
|||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE &&
|
||||
cause_value !=
|
||||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
|
@ -280,9 +299,6 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
ogs_gtp_xact_t *s11_xact = NULL;
|
||||
ogs_gtp2_modify_bearer_response_t *rsp = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(message);
|
||||
rsp = &message->modify_bearer_response;
|
||||
ogs_assert(rsp);
|
||||
|
@ -300,10 +316,37 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
*
|
||||
* - Session could be deleted before a message is received from SMF.
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
else
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
|
@ -331,7 +374,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
|
@ -385,9 +428,6 @@ void sgwc_s5c_handle_delete_session_response(
|
|||
ogs_gtp_xact_t *s11_xact = NULL;
|
||||
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(message);
|
||||
rsp = &message->delete_session_response;
|
||||
ogs_assert(rsp);
|
||||
|
@ -404,10 +444,32 @@ void sgwc_s5c_handle_delete_session_response(
|
|||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
*
|
||||
* - Session could be deleted before a message is received from SMF.
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
|
@ -430,7 +492,7 @@ void sgwc_s5c_handle_delete_session_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
|
@ -835,9 +897,6 @@ void sgwc_s5c_handle_bearer_resource_failure_indication(
|
|||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(message);
|
||||
ind = &message->bearer_resource_failure_indication;
|
||||
ogs_assert(ind);
|
||||
|
@ -851,6 +910,19 @@ void sgwc_s5c_handle_bearer_resource_failure_indication(
|
|||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
*
|
||||
* - Session could be deleted before a message is received from SMF.
|
||||
************************/
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
********************/
|
||||
|
|
|
@ -1325,12 +1325,21 @@ void sgwc_sxa_handle_session_report_request(
|
|||
|
||||
ogs_debug("Session Report Request");
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(pfcp_xact);
|
||||
ogs_assert(pfcp_req);
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
*
|
||||
* - Session could be deleted before a message is received from SMF.
|
||||
************************/
|
||||
if (!sess) {
|
||||
ogs_error("No Context");
|
||||
cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (pfcp_req->report_type.presence == 0) {
|
||||
ogs_error("No Report Type");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
|
|
@ -165,12 +165,16 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
|
|||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
ogs_info("PFCP associated");
|
||||
ogs_info("PFCP associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_start(node->t_no_heartbeat,
|
||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
ogs_info("PFCP de-associated");
|
||||
ogs_info("PFCP de-associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_stop(node->t_no_heartbeat);
|
||||
break;
|
||||
case SGWU_EVT_SXA_MESSAGE:
|
||||
|
@ -194,12 +198,16 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
|
|||
&message->pfcp_heartbeat_response));
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
||||
ogs_warn("PFCP[REQ] has already been associated");
|
||||
ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_up_handle_association_setup_request(node, xact,
|
||||
&message->pfcp_association_setup_request);
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
||||
ogs_warn("PFCP[RSP] has already been associated");
|
||||
ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_up_handle_association_setup_response(node, xact,
|
||||
&message->pfcp_association_setup_response);
|
||||
break;
|
||||
|
|
|
@ -835,6 +835,8 @@ int smf_context_parse_config(void)
|
|||
/* handle config in sbi library */
|
||||
} else if (!strcmp(smf_key, "discovery")) {
|
||||
/* handle config in sbi library */
|
||||
} else if (!strcmp(smf_key, "metrics")) {
|
||||
/* handle config in metrics library */
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", smf_key);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ int smf_initialize()
|
|||
rv = ogs_sbi_context_parse_config("smf", "nrf", "scp");
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = ogs_metrics_context_parse_config();
|
||||
rv = ogs_metrics_context_parse_config("smf");
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
rv = smf_context_parse_config();
|
||||
|
|
|
@ -1063,7 +1063,7 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
|
|||
return OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_warn("PFCP Cause[%d] : Not Accepted", rsp->cause.u8);
|
||||
ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
|
||||
return rsp->cause.u8;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,12 +171,16 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
|||
|
||||
switch (e->h.id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
ogs_info("PFCP associated");
|
||||
ogs_info("PFCP associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_start(node->t_no_heartbeat,
|
||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
ogs_info("PFCP de-associated");
|
||||
ogs_info("PFCP de-associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_stop(node->t_no_heartbeat);
|
||||
break;
|
||||
case SMF_EVT_N4_MESSAGE:
|
||||
|
@ -210,12 +214,16 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
|||
&message->pfcp_heartbeat_response));
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
||||
ogs_warn("PFCP[REQ] has already been associated");
|
||||
ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_cp_handle_association_setup_request(node, xact,
|
||||
&message->pfcp_association_setup_request);
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
||||
ogs_warn("PFCP[RSP] has already been associated");
|
||||
ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_cp_handle_association_setup_response(node, xact,
|
||||
&message->pfcp_association_setup_response);
|
||||
break;
|
||||
|
|
|
@ -708,7 +708,7 @@ void smf_s5c_handle_create_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_one_bearer_modification_request(
|
||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||
|
@ -721,7 +721,7 @@ void smf_s5c_handle_create_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_one_bearer_modification_request(
|
||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||
|
@ -837,7 +837,7 @@ void smf_s5c_handle_update_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -845,7 +845,7 @@ void smf_s5c_handle_update_bearer_response(
|
|||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -925,7 +925,7 @@ bool smf_s5c_handle_delete_bearer_response(
|
|||
cause_value = cause->value;
|
||||
if (cause->value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
|
@ -965,13 +965,13 @@ bool smf_s5c_handle_delete_bearer_response(
|
|||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
}
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
extern int __udm_log_domain;
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
extern int __udr_log_domain;
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
|
|
|
@ -547,7 +547,8 @@ static void upf_sess_urr_acc_validity_time_setup(upf_sess_t *sess, ogs_pfcp_urr_
|
|||
if (!urr_acc->t_validity_time)
|
||||
urr_acc->t_validity_time = ogs_timer_add(ogs_app()->timer_mgr,
|
||||
upf_sess_urr_acc_timers_cb, urr);
|
||||
ogs_timer_start(urr_acc->t_validity_time, urr->quota_validity_time * OGS_USEC_PER_SEC);
|
||||
ogs_timer_start(urr_acc->t_validity_time,
|
||||
ogs_time_from_sec(urr->quota_validity_time));
|
||||
}
|
||||
static void upf_sess_urr_acc_time_quota_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
|
||||
{
|
||||
|
@ -558,7 +559,7 @@ static void upf_sess_urr_acc_time_quota_setup(upf_sess_t *sess, ogs_pfcp_urr_t *
|
|||
if (!urr_acc->t_time_quota)
|
||||
urr_acc->t_time_quota = ogs_timer_add(ogs_app()->timer_mgr,
|
||||
upf_sess_urr_acc_timers_cb, urr);
|
||||
ogs_timer_start(urr_acc->t_time_quota, urr->time_quota * OGS_USEC_PER_SEC);
|
||||
ogs_timer_start(urr_acc->t_time_quota, ogs_time_from_sec(urr->time_quota));
|
||||
}
|
||||
static void upf_sess_urr_acc_time_threshold_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
|
||||
{
|
||||
|
@ -569,7 +570,8 @@ static void upf_sess_urr_acc_time_threshold_setup(upf_sess_t *sess, ogs_pfcp_urr
|
|||
if (!urr_acc->t_time_threshold)
|
||||
urr_acc->t_time_threshold = ogs_timer_add(ogs_app()->timer_mgr,
|
||||
upf_sess_urr_acc_timers_cb, urr);
|
||||
ogs_timer_start(urr_acc->t_time_threshold, urr->time_threshold * OGS_USEC_PER_SEC);
|
||||
ogs_timer_start(urr_acc->t_time_threshold,
|
||||
ogs_time_from_sec(urr->time_threshold));
|
||||
}
|
||||
|
||||
void upf_sess_urr_acc_timers_setup(upf_sess_t *sess, ogs_pfcp_urr_t *urr)
|
||||
|
|
|
@ -170,12 +170,16 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
|
|||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
ogs_info("PFCP associated");
|
||||
ogs_info("PFCP associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_start(node->t_no_heartbeat,
|
||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||
break;
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
ogs_info("PFCP de-associated");
|
||||
ogs_info("PFCP de-associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_timer_stop(node->t_no_heartbeat);
|
||||
break;
|
||||
case UPF_EVT_N4_MESSAGE:
|
||||
|
@ -199,12 +203,16 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
|
|||
&message->pfcp_heartbeat_response));
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
||||
ogs_warn("PFCP[REQ] has already been associated");
|
||||
ogs_warn("PFCP[REQ] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_up_handle_association_setup_request(node, xact,
|
||||
&message->pfcp_association_setup_request);
|
||||
break;
|
||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
||||
ogs_warn("PFCP[RSP] has already been associated");
|
||||
ogs_warn("PFCP[RSP] has already been associated [%s]:%d",
|
||||
OGS_ADDR(&node->addr, buf),
|
||||
OGS_PORT(&node->addr));
|
||||
ogs_pfcp_up_handle_association_setup_response(node, xact,
|
||||
&message->pfcp_association_setup_response);
|
||||
break;
|
||||
|
|
|
@ -36,8 +36,6 @@ extern "C" {
|
|||
#define TEST_PING_IPV4 "10.45.0.1"
|
||||
#define TEST_PING_IPV6 "2001:db8:cafe::1"
|
||||
|
||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
||||
|
||||
#define TEST_MSISDN "491725670014"
|
||||
#define TEST_ADDITIONAL_MSISDN "491725670015"
|
||||
|
||||
|
|
Loading…
Reference in New Issue