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_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
||||||
# no_sgwu: true
|
# no_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
||||||
# no_sgwu: true
|
# no_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -178,6 +178,13 @@ logger:
|
||||||
# sinit_max_attempts : 4
|
# sinit_max_attempts : 4
|
||||||
# sinit_max_init_timeo : 8000
|
# sinit_max_init_timeo : 8000
|
||||||
#
|
#
|
||||||
|
# <Metrics Server>
|
||||||
|
#
|
||||||
|
# o Metrics Server(http://<any address>:9090)
|
||||||
|
# metrics:
|
||||||
|
# addr: 0.0.0.0
|
||||||
|
# port: 9090
|
||||||
|
#
|
||||||
# <GUAMI>
|
# <GUAMI>
|
||||||
#
|
#
|
||||||
# o Multiple GUAMI
|
# o Multiple GUAMI
|
||||||
|
@ -263,6 +270,9 @@ amf:
|
||||||
port: 7777
|
port: 7777
|
||||||
ngap:
|
ngap:
|
||||||
- addr: 127.0.0.5
|
- addr: 127.0.0.5
|
||||||
|
metrics:
|
||||||
|
addr: 127.0.0.5
|
||||||
|
port: 9090
|
||||||
guami:
|
guami:
|
||||||
- plmn_id:
|
- plmn_id:
|
||||||
mcc: 999
|
mcc: 999
|
||||||
|
@ -391,17 +401,3 @@ usrsctp:
|
||||||
# handover:
|
# handover:
|
||||||
# duration: 500
|
# duration: 500
|
||||||
time:
|
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
|
# prefer_ipv4: true
|
||||||
#
|
#
|
||||||
parameter:
|
parameter:
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
#
|
#
|
||||||
# max:
|
# max:
|
||||||
|
|
|
@ -175,6 +175,12 @@ logger:
|
||||||
# mnc: 02
|
# mnc: 02
|
||||||
# lac: 43693
|
# lac: 43693
|
||||||
#
|
#
|
||||||
|
# <Metrics Server>
|
||||||
|
#
|
||||||
|
# o Metrics Server(http://<any address>:9090)
|
||||||
|
# metrics:
|
||||||
|
# addr: 0.0.0.0
|
||||||
|
# port: 9090
|
||||||
#
|
#
|
||||||
# <GUMMEI>
|
# <GUMMEI>
|
||||||
#
|
#
|
||||||
|
@ -248,6 +254,9 @@ mme:
|
||||||
- addr: 127.0.0.2
|
- addr: 127.0.0.2
|
||||||
gtpc:
|
gtpc:
|
||||||
- addr: 127.0.0.2
|
- addr: 127.0.0.2
|
||||||
|
metrics:
|
||||||
|
addr: 127.0.0.2
|
||||||
|
port: 9090
|
||||||
gummei:
|
gummei:
|
||||||
plmn_id:
|
plmn_id:
|
||||||
mcc: 999
|
mcc: 999
|
||||||
|
@ -421,17 +430,3 @@ usrsctp:
|
||||||
# handover:
|
# handover:
|
||||||
# duration: 500
|
# duration: 500
|
||||||
time:
|
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
|
# o Set OGS_LOG_TRACE to all domain level
|
||||||
# level: trace
|
# level: trace
|
||||||
# domain: core,pfcp,fd,pfcp,gtp,smf,event,tlv,mem,sock
|
# domain: core,fd,pfcp,gtp,smf,event,tlv,mem,sock
|
||||||
#
|
#
|
||||||
logger:
|
logger:
|
||||||
file: @localstatedir@/log/open5gs/smf.log
|
file: @localstatedir@/log/open5gs/smf.log
|
||||||
|
@ -179,6 +179,13 @@ logger:
|
||||||
# option:
|
# option:
|
||||||
# so_bindtodevice: vrf-blue
|
# 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>
|
# <Subnet for UE Pool>
|
||||||
#
|
#
|
||||||
# o IPv4 Pool
|
# o IPv4 Pool
|
||||||
|
@ -423,6 +430,9 @@ smf:
|
||||||
gtpu:
|
gtpu:
|
||||||
- addr: 127.0.0.4
|
- addr: 127.0.0.4
|
||||||
- addr: ::1
|
- addr: ::1
|
||||||
|
metrics:
|
||||||
|
addr: 127.0.0.4
|
||||||
|
port: 9090
|
||||||
subnet:
|
subnet:
|
||||||
- addr: 10.45.0.1/16
|
- addr: 10.45.0.1/16
|
||||||
- addr: 2001:db8:cafe::1/48
|
- addr: 2001:db8:cafe::1/48
|
||||||
|
@ -599,17 +609,3 @@ max:
|
||||||
# handover:
|
# handover:
|
||||||
# duration: 500
|
# duration: 500
|
||||||
time:
|
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_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
||||||
# no_sgwu: true
|
# no_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
||||||
# no_sgwu: true
|
# no_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
||||||
# no_sgwu: true
|
# no_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
freeDiameter:
|
||||||
|
|
|
@ -19,6 +19,7 @@ parameter:
|
||||||
# no_sgwu: true
|
# no_sgwu: true
|
||||||
# no_pcrf: true
|
# no_pcrf: true
|
||||||
# no_hss: true
|
# no_hss: true
|
||||||
|
# use_mongodb_change_stream: true
|
||||||
|
|
||||||
mme:
|
mme:
|
||||||
freeDiameter:
|
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
|
$ 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
|
## 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
|
$ 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.
|
**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}
|
{: .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.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.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.0.20 netmask 255.255.255.255
|
||||||
|
$ sudo ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable IP forwarding & Masquerading
|
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.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.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.0.20 netmask 255.255.255.255
|
||||||
|
$ sudo ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable IP forwarding & Masquerading
|
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.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.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.0.20 netmask 255.255.255.255
|
||||||
|
$ sudo ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable IP forwarding
|
Enable IP forwarding
|
||||||
|
|
|
@ -350,6 +350,10 @@ int ogs_app_context_parse_config(void)
|
||||||
} else if (!strcmp(parameter_key, "no_pfcp_rr_select")) {
|
} else if (!strcmp(parameter_key, "no_pfcp_rr_select")) {
|
||||||
self.parameter.no_pfcp_rr_select =
|
self.parameter.no_pfcp_rr_select =
|
||||||
ogs_yaml_iter_bool(¶meter_iter);
|
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
|
} else
|
||||||
ogs_warn("unknown key `%s`", parameter_key);
|
ogs_warn("unknown key `%s`", parameter_key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ typedef struct ogs_app_context_s {
|
||||||
void *document;
|
void *document;
|
||||||
|
|
||||||
const char *db_uri;
|
const char *db_uri;
|
||||||
|
int use_mongodb_change_stream;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *file;
|
const char *file;
|
||||||
const char *level;
|
const char *level;
|
||||||
|
|
|
@ -125,7 +125,7 @@ ogs_time_t ogs_time_now(void)
|
||||||
rc = ogs_gettimeofday(&tv);
|
rc = ogs_gettimeofday(&tv);
|
||||||
ogs_assert(rc == 0);
|
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 */
|
/* The following code is stolen from APR library */
|
||||||
|
@ -188,13 +188,13 @@ uint32_t ogs_time_ntp32_now(void)
|
||||||
rc = ogs_gettimeofday(&tv);
|
rc = ogs_gettimeofday(&tv);
|
||||||
ogs_assert(rc == 0);
|
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)
|
ogs_time_t ogs_time_from_ntp32(uint32_t ntp_timestamp)
|
||||||
{
|
{
|
||||||
if (ntp_timestamp < OGS_1970_1900_SEC_DIFF)
|
if (ntp_timestamp < OGS_1970_1900_SEC_DIFF)
|
||||||
return 0;
|
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)
|
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)
|
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &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__)
|
#elif defined(__APPLE__)
|
||||||
static mach_timebase_info_data_t info = {0};
|
static mach_timebase_info_data_t info = {0};
|
||||||
static double ratio = 0.0;
|
static double ratio = 0.0;
|
||||||
|
@ -268,7 +268,7 @@ ogs_time_t ogs_get_monotonic_time(void)
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
ogs_gettimeofday(&tv);
|
ogs_gettimeofday(&tv);
|
||||||
return (tv.tv_sec * 1000000UL) + tv.tv_usec;
|
return ogs_time_from_sec(tv.tv_sec) + tv.tv_usec;
|
||||||
#endif
|
#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(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;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ static void get_system_time(uint64_t *uuid_time)
|
||||||
|
|
||||||
/* ### fix this call to be more portable? */
|
/* ### fix this call to be more portable? */
|
||||||
ogs_gettimeofday(&tv);
|
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.
|
/* Offset between UUID formatted times and Unix formatted times.
|
||||||
UUID UTC base time is October 15, 1582.
|
UUID UTC base time is October 15, 1582.
|
||||||
|
|
|
@ -19,11 +19,14 @@ libdbi_sources = files('''
|
||||||
ogs-dbi.h
|
ogs-dbi.h
|
||||||
|
|
||||||
ogs-mongoc.h
|
ogs-mongoc.h
|
||||||
|
timer.h
|
||||||
|
|
||||||
ogs-mongoc.c
|
ogs-mongoc.c
|
||||||
subscription.c
|
subscription.c
|
||||||
session.c
|
session.c
|
||||||
ims.c
|
ims.c
|
||||||
|
path.c
|
||||||
|
timer.c
|
||||||
'''.split())
|
'''.split())
|
||||||
|
|
||||||
libmongoc_dep = dependency('libmongoc-1.0')
|
libmongoc_dep = dependency('libmongoc-1.0')
|
||||||
|
@ -35,10 +38,10 @@ libdbi = library('ogsdbi',
|
||||||
version : libogslib_version,
|
version : libogslib_version,
|
||||||
c_args : '-DOGS_DBI_COMPILATION',
|
c_args : '-DOGS_DBI_COMPILATION',
|
||||||
include_directories : [libdbi_inc, libinc],
|
include_directories : [libdbi_inc, libinc],
|
||||||
dependencies : [libcrypt_dep, libmongoc_dep],
|
dependencies : [libcrypt_dep, libapp_dep, libmongoc_dep],
|
||||||
install : true)
|
install : true)
|
||||||
|
|
||||||
libdbi_dep = declare_dependency(
|
libdbi_dep = declare_dependency(
|
||||||
link_with : libdbi,
|
link_with : libdbi,
|
||||||
include_directories : [libdbi_inc, libinc],
|
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
|
#define OGS_DBI_H
|
||||||
|
|
||||||
#include "crypt/ogs-crypt.h"
|
#include "crypt/ogs-crypt.h"
|
||||||
|
#include "app/ogs-app.h"
|
||||||
|
|
||||||
#define OGS_DBI_INSIDE
|
#define OGS_DBI_INSIDE
|
||||||
|
|
||||||
|
@ -28,6 +29,8 @@
|
||||||
#include "dbi/subscription.h"
|
#include "dbi/subscription.h"
|
||||||
#include "dbi/session.h"
|
#include "dbi/session.h"
|
||||||
#include "dbi/ims.h"
|
#include "dbi/ims.h"
|
||||||
|
#include "dbi/path.h"
|
||||||
|
#include "dbi/timer.h"
|
||||||
|
|
||||||
#undef OGS_DBI_INSIDE
|
#undef OGS_DBI_INSIDE
|
||||||
|
|
||||||
|
|
|
@ -182,5 +182,62 @@ void ogs_dbi_final()
|
||||||
mongoc_collection_destroy(self.collection.subscriber);
|
mongoc_collection_destroy(self.collection.subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.stream) {
|
||||||
|
mongoc_change_stream_destroy(self.stream);
|
||||||
|
}
|
||||||
|
|
||||||
ogs_mongoc_final();
|
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 *client;
|
||||||
void *database;
|
void *database;
|
||||||
|
|
||||||
|
mongoc_change_stream_t *stream;
|
||||||
|
|
||||||
char *masked_db_uri;
|
char *masked_db_uri;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -51,6 +53,9 @@ ogs_mongoc_t *ogs_mongoc(void);
|
||||||
int ogs_dbi_init(const char *db_uri);
|
int ogs_dbi_init(const char *db_uri);
|
||||||
void ogs_dbi_final(void);
|
void ogs_dbi_final(void);
|
||||||
|
|
||||||
|
int ogs_dbi_collection_watch_init(void);
|
||||||
|
int ogs_dbi_poll_change_stream(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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_close(ogs_metrics_context_t *ctx);
|
||||||
void ogs_metrics_context_final(void);
|
void ogs_metrics_context_final(void);
|
||||||
ogs_metrics_context_t *ogs_metrics_self(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;
|
typedef struct ogs_metrics_spec_s ogs_metrics_spec_t;
|
||||||
ogs_metrics_spec_t *ogs_metrics_spec_new(
|
ogs_metrics_spec_t *ogs_metrics_spec_new(
|
||||||
|
|
|
@ -104,7 +104,7 @@ ogs_metrics_context_t *ogs_metrics_self(void)
|
||||||
return &self;
|
return &self;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ogs_metrics_context_parse_config(void)
|
int ogs_metrics_context_parse_config(const char *local)
|
||||||
{
|
{
|
||||||
int family = AF_UNSPEC;
|
int family = AF_UNSPEC;
|
||||||
const char *hostname = NULL;
|
const char *hostname = NULL;
|
||||||
|
@ -121,17 +121,26 @@ int ogs_metrics_context_parse_config(void)
|
||||||
while (ogs_yaml_iter_next(&root_iter)) {
|
while (ogs_yaml_iter_next(&root_iter)) {
|
||||||
const char *root_key = ogs_yaml_iter_key(&root_iter);
|
const char *root_key = ogs_yaml_iter_key(&root_iter);
|
||||||
ogs_assert(root_key);
|
ogs_assert(root_key);
|
||||||
if (!strcmp(root_key, "metrics")) {
|
if (local && !strcmp(root_key, local)) {
|
||||||
ogs_yaml_iter_t local_iter;
|
ogs_yaml_iter_t local_iter;
|
||||||
ogs_yaml_iter_recurse(&root_iter, &local_iter);
|
ogs_yaml_iter_recurse(&root_iter, &local_iter);
|
||||||
while (ogs_yaml_iter_next(&local_iter)) {
|
while (ogs_yaml_iter_next(&local_iter)) {
|
||||||
const char *local_key = ogs_yaml_iter_key(&local_iter);
|
const char *local_key = ogs_yaml_iter_key(&local_iter);
|
||||||
if (!strcmp(local_key, "addr")) {
|
ogs_assert(local_key);
|
||||||
if ((v = ogs_yaml_iter_value(&local_iter)))
|
if (!strcmp(local_key, "metrics")) {
|
||||||
hostname = v;
|
ogs_yaml_iter_t metrics_iter;
|
||||||
} else if (!strcmp(local_key, "port")) {
|
ogs_yaml_iter_recurse(&local_iter, &metrics_iter);
|
||||||
if ((v = ogs_yaml_iter_value(&local_iter)))
|
while (ogs_yaml_iter_next(&metrics_iter)) {
|
||||||
port = atoi(v);
|
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;
|
return &self;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ogs_metrics_context_parse_config(void)
|
int ogs_metrics_context_parse_config(const char *local)
|
||||||
{
|
{
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,11 @@ const char *ogs_event_get_name(ogs_event_t *e)
|
||||||
case OGS_EVENT_SBI_TIMER:
|
case OGS_EVENT_SBI_TIMER:
|
||||||
return OGS_EVENT_NAME_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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ typedef enum {
|
||||||
OGS_EVENT_SBI_CLIENT,
|
OGS_EVENT_SBI_CLIENT,
|
||||||
OGS_EVENT_SBI_TIMER,
|
OGS_EVENT_SBI_TIMER,
|
||||||
|
|
||||||
|
OGS_EVENT_DBI_POLL_TIMER,
|
||||||
|
OGS_EVENT_DBI_MESSAGE,
|
||||||
|
|
||||||
OGS_MAX_NUM_OF_PROTO_EVENT,
|
OGS_MAX_NUM_OF_PROTO_EVENT,
|
||||||
|
|
||||||
} ogs_event_e;
|
} 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_response_s ogs_sbi_response_t;
|
||||||
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
|
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
|
||||||
|
|
||||||
|
typedef struct _bson_t bson_t;
|
||||||
|
|
||||||
typedef struct ogs_event_s {
|
typedef struct ogs_event_s {
|
||||||
int id;
|
int id;
|
||||||
int timer_id;
|
int timer_id;
|
||||||
|
@ -59,6 +64,10 @@ typedef struct ogs_event_s {
|
||||||
|
|
||||||
ogs_sbi_message_t *message;
|
ogs_sbi_message_t *message;
|
||||||
} sbi;
|
} sbi;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const bson_t *document;
|
||||||
|
} dbi;
|
||||||
} ogs_event_t;
|
} ogs_event_t;
|
||||||
|
|
||||||
void *ogs_event_size(int id, size_t size);
|
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;
|
return OGS_TIMER_NAME_SUBSCRIPTION_VALIDITY;
|
||||||
case OGS_TIMER_SBI_CLIENT_WAIT:
|
case OGS_TIMER_SBI_CLIENT_WAIT:
|
||||||
return OGS_TIMER_NAME_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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ typedef enum {
|
||||||
OGS_TIMER_SUBSCRIPTION_VALIDITY,
|
OGS_TIMER_SUBSCRIPTION_VALIDITY,
|
||||||
OGS_TIMER_SBI_CLIENT_WAIT,
|
OGS_TIMER_SBI_CLIENT_WAIT,
|
||||||
|
|
||||||
|
OGS_TIMER_DBI_POLL_CHANGE_STREAM,
|
||||||
|
|
||||||
OGS_MAX_NUM_OF_PROTO_TIMER,
|
OGS_MAX_NUM_OF_PROTO_TIMER,
|
||||||
|
|
||||||
} ogs_timer_e;
|
} ogs_timer_e;
|
||||||
|
|
|
@ -81,6 +81,7 @@ extern "C" {
|
||||||
#define OGS_MAX_PCO_LEN 251
|
#define OGS_MAX_PCO_LEN 251
|
||||||
#define OGS_MAX_FQDN_LEN 256
|
#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_SERVED_TAI 16
|
||||||
#define OGS_MAX_NUM_OF_ALGORITHM 8
|
#define OGS_MAX_NUM_OF_ALGORITHM 8
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ typedef struct connection_s {
|
||||||
|
|
||||||
char *memory;
|
char *memory;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
bool memory_overflow;
|
||||||
|
|
||||||
char *location;
|
char *location;
|
||||||
|
|
||||||
|
@ -533,6 +534,8 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
|
|
||||||
res = resource->data.result;
|
res = resource->data.result;
|
||||||
if (res == CURLE_OK) {
|
if (res == CURLE_OK) {
|
||||||
|
ogs_log_level_e level = OGS_LOG_DEBUG;
|
||||||
|
|
||||||
response = ogs_sbi_response_new();
|
response = ogs_sbi_response_new();
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
|
@ -546,7 +549,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
response->h.uri = ogs_strdup(url);
|
response->h.uri = ogs_strdup(url);
|
||||||
ogs_assert(response->h.uri);
|
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);
|
response->status, response->h.method, response->h.uri);
|
||||||
|
|
||||||
if (conn->memory) {
|
if (conn->memory) {
|
||||||
|
@ -557,16 +570,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
ogs_assert(response->http.content_length);
|
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)
|
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
|
} else
|
||||||
ogs_warn("[%d] %s", res, conn->error);
|
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;
|
realsize = size * nmemb;
|
||||||
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
|
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
|
||||||
if(!ptr) {
|
if(!ptr) {
|
||||||
ogs_fatal("not enough memory (realloc returned NULL)");
|
conn->memory_overflow = true;
|
||||||
ogs_assert_if_reached();
|
|
||||||
|
ogs_error("Overflow : conn->size[%d], realsize[%d]",
|
||||||
|
(int)conn->size, (int)realsize);
|
||||||
|
ogs_log_hexdump(OGS_LOG_ERROR, contents, realsize);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1189,6 +1189,11 @@ ogs_sbi_nf_info_t *ogs_sbi_nf_info_add(
|
||||||
return nf_info;
|
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)
|
static void smf_info_free(ogs_sbi_smf_info_t *smf_info)
|
||||||
{
|
{
|
||||||
int i, j;
|
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);
|
ogs_list_remove(list, nf_info);
|
||||||
|
|
||||||
switch(nf_info->nf_type) {
|
switch(nf_info->nf_type) {
|
||||||
|
case OpenAPI_nf_type_AMF:
|
||||||
|
amf_info_free(&nf_info->amf);
|
||||||
|
break;
|
||||||
case OpenAPI_nf_type_SMF:
|
case OpenAPI_nf_type_SMF:
|
||||||
smf_info_free(&nf_info->smf);
|
smf_info_free(&nf_info->smf);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -255,12 +255,37 @@ typedef struct ogs_sbi_smf_info_s {
|
||||||
} nr_tai_range[OGS_MAX_NUM_OF_TAI];
|
} nr_tai_range[OGS_MAX_NUM_OF_TAI];
|
||||||
} ogs_sbi_smf_info_t;
|
} 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 {
|
typedef struct ogs_sbi_nf_info_s {
|
||||||
ogs_lnode_t lnode;
|
ogs_lnode_t lnode;
|
||||||
|
|
||||||
OpenAPI_nf_type_e nf_type;
|
OpenAPI_nf_type_e nf_type;
|
||||||
union {
|
union {
|
||||||
ogs_sbi_smf_info_t smf;
|
ogs_sbi_smf_info_t smf;
|
||||||
|
ogs_sbi_amf_info_t amf;
|
||||||
};
|
};
|
||||||
} ogs_sbi_nf_info_t;
|
} ogs_sbi_nf_info_t;
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ typedef struct ogs_sbi_stream_s {
|
||||||
|
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
ogs_sbi_request_t *request;
|
ogs_sbi_request_t *request;
|
||||||
|
bool memory_overflow;
|
||||||
|
|
||||||
ogs_sbi_session_t *session;
|
ogs_sbi_session_t *session;
|
||||||
} ogs_sbi_stream_t;
|
} ogs_sbi_stream_t;
|
||||||
|
@ -791,12 +792,23 @@ static int on_frame_recv(nghttp2_session *session,
|
||||||
case NGHTTP2_DATA:
|
case NGHTTP2_DATA:
|
||||||
/* HEADERS or DATA frame with +END_STREAM flag */
|
/* HEADERS or DATA frame with +END_STREAM flag */
|
||||||
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
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) {
|
if (request->http.content_length && request->http.content) {
|
||||||
ogs_debug("RECEIVED: %d", (int)request->http.content_length);
|
ogs_log_message(level, 0,
|
||||||
ogs_debug("%s", request->http.content);
|
"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) {
|
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);
|
ogs_assert(len);
|
||||||
|
|
||||||
if (request->http.content == NULL) {
|
if (request->http.content == NULL) {
|
||||||
request->http.content_length = len;
|
ogs_assert(request->http.content_length == 0);
|
||||||
request->http.content =
|
ogs_assert(offset == 0);
|
||||||
(char*)ogs_malloc(request->http.content_length + 1);
|
|
||||||
ogs_assert(request->http.content);
|
request->http.content = (char*)ogs_malloc(len + 1);
|
||||||
} else {
|
} else {
|
||||||
offset = request->http.content_length;
|
ogs_assert(request->http.content_length != 0);
|
||||||
if ((request->http.content_length + len) > OGS_HUGE_LEN) {
|
|
||||||
ogs_error("Overflow : Content-Length[%d], len[%d]",
|
request->http.content = (char*)ogs_realloc(
|
||||||
(int)request->http.content_length, (int)len);
|
request->http.content, request->http.content_length + len + 1);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
memcpy(request->http.content + offset, data, len);
|
||||||
request->http.content[request->http.content_length] = '\0';
|
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);
|
ogs_sbi_nf_service_t *nf_service);
|
||||||
static void free_nf_service(OpenAPI_nf_service_t *NFService);
|
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_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_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)
|
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 *AllowedNfTypeList = NULL;
|
||||||
OpenAPI_list_t *NFServiceList = NULL;
|
OpenAPI_list_t *NFServiceList = NULL;
|
||||||
OpenAPI_map_t *NFServiceMap = NULL;
|
OpenAPI_map_t *NFServiceMap = NULL;
|
||||||
OpenAPI_list_t *SmfInfoList = NULL;
|
OpenAPI_list_t *InfoList = NULL;
|
||||||
OpenAPI_map_t *SmfInfoMap = NULL;
|
OpenAPI_map_t *InfoMap = NULL;
|
||||||
OpenAPI_smf_info_t *SmfInfo = NULL;
|
OpenAPI_smf_info_t *SmfInfo = NULL;
|
||||||
int SmfInfoMapKey;
|
int InfoMapKey;
|
||||||
|
|
||||||
OpenAPI_lnode_t *node = NULL;
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
|
||||||
|
OpenAPI_amf_info_t *AmfInfo = NULL;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char *ipstr = NULL;
|
char *ipstr = NULL;
|
||||||
|
|
||||||
|
@ -222,10 +226,10 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
|
||||||
} else
|
} else
|
||||||
OpenAPI_list_free(NFServiceList);
|
OpenAPI_list_free(NFServiceList);
|
||||||
|
|
||||||
SmfInfoList = OpenAPI_list_create();
|
InfoList = OpenAPI_list_create();
|
||||||
ogs_assert(SmfInfoList);
|
ogs_assert(InfoList);
|
||||||
|
|
||||||
SmfInfoMapKey = 0;
|
InfoMapKey = 0;
|
||||||
|
|
||||||
ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
|
ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
|
||||||
if (nf_info->nf_type == OpenAPI_nf_type_SMF) {
|
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);
|
SmfInfo = build_smf_info(nf_info);
|
||||||
ogs_expect_or_return_val(SmfInfo, NULL);
|
ogs_expect_or_return_val(SmfInfo, NULL);
|
||||||
|
|
||||||
SmfInfoMap = OpenAPI_map_create(
|
InfoMap = OpenAPI_map_create(
|
||||||
ogs_msprintf("%d", ++SmfInfoMapKey), SmfInfo);
|
ogs_msprintf("%d", ++InfoMapKey), SmfInfo);
|
||||||
ogs_assert(SmfInfoMap);
|
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 {
|
} else {
|
||||||
ogs_fatal("Not implemented NF-type[%s]",
|
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();
|
ogs_assert_if_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (InfoList->count == 1) {
|
||||||
if (SmfInfoList->count == 1) {
|
if (nf_instance->nf_type == OpenAPI_nf_type_SMF) {
|
||||||
NFProfile->smf_info = SmfInfo;
|
NFProfile->smf_info = SmfInfo;
|
||||||
|
} else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) {
|
||||||
OpenAPI_list_for_each(SmfInfoList, node) {
|
NFProfile->amf_info = AmfInfo;
|
||||||
SmfInfoMap = node->data;
|
} else {
|
||||||
if (SmfInfoMap) {
|
ogs_fatal("Not implemented NF-type[%s]",
|
||||||
if (SmfInfoMap->key)
|
OpenAPI_nf_type_ToString(nf_instance->nf_type));
|
||||||
ogs_free(SmfInfoMap->key);
|
ogs_assert_if_reached();
|
||||||
ogs_free(SmfInfoMap);
|
}
|
||||||
|
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);
|
OpenAPI_list_free(InfoList);
|
||||||
} else if (SmfInfoList->count > 1) {
|
} else if (InfoList->count > 1) {
|
||||||
NFProfile->smf_info_list = SmfInfoList;
|
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
|
} else
|
||||||
OpenAPI_list_free(SmfInfoList);
|
OpenAPI_list_free(InfoList);
|
||||||
|
|
||||||
return NFProfile;
|
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_nf_service_t *NFService = NULL;
|
||||||
OpenAPI_map_t *SmfInfoMap = NULL;
|
OpenAPI_map_t *SmfInfoMap = NULL;
|
||||||
OpenAPI_smf_info_t *SmfInfo = NULL;
|
OpenAPI_smf_info_t *SmfInfo = NULL;
|
||||||
|
OpenAPI_map_t *AmfInfoMap = NULL;
|
||||||
|
OpenAPI_amf_info_t *AmfInfo = NULL;
|
||||||
OpenAPI_lnode_t *node = NULL;
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
|
||||||
ogs_assert(NFProfile);
|
ogs_assert(NFProfile);
|
||||||
|
@ -327,6 +357,22 @@ void ogs_nnrf_nfm_free_nf_profile(OpenAPI_nf_profile_t *NFProfile)
|
||||||
if (NFProfile->smf_info)
|
if (NFProfile->smf_info)
|
||||||
free_smf_info(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);
|
ogs_free(NFProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,6 +668,124 @@ static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info)
|
||||||
return SmfInfo;
|
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)
|
static void free_smf_info(OpenAPI_smf_info_t *SmfInfo)
|
||||||
{
|
{
|
||||||
OpenAPI_list_t *sNssaiSmfInfoList = NULL;
|
OpenAPI_list_t *sNssaiSmfInfoList = NULL;
|
||||||
|
@ -705,6 +869,84 @@ static void free_smf_info(OpenAPI_smf_info_t *SmfInfo)
|
||||||
ogs_free(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_request_t *ogs_nnrf_nfm_build_update(void)
|
||||||
{
|
{
|
||||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
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 *region = NULL, *set = NULL;
|
||||||
const char *pointer = NULL;
|
const char *pointer = NULL;
|
||||||
ogs_assert(self.num_of_served_guami <
|
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) ==
|
if (ogs_yaml_iter_type(&guami_array) ==
|
||||||
YAML_MAPPING_NODE) {
|
YAML_MAPPING_NODE) {
|
||||||
|
@ -825,6 +825,8 @@ int amf_context_parse_config(void)
|
||||||
/* handle config in sbi library */
|
/* handle config in sbi library */
|
||||||
} else if (!strcmp(amf_key, "discovery")) {
|
} else if (!strcmp(amf_key, "discovery")) {
|
||||||
/* handle config in sbi library */
|
/* handle config in sbi library */
|
||||||
|
} else if (!strcmp(amf_key, "metrics")) {
|
||||||
|
/* handle config in metrics library */
|
||||||
} else
|
} else
|
||||||
ogs_warn("unknown key `%s`", amf_key);
|
ogs_warn("unknown key `%s`", amf_key);
|
||||||
}
|
}
|
||||||
|
@ -837,6 +839,97 @@ int amf_context_parse_config(void)
|
||||||
return OGS_OK;
|
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 *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
|
||||||
{
|
{
|
||||||
amf_gnb_t *gnb = NULL;
|
amf_gnb_t *gnb = NULL;
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
extern int __amf_log_domain;
|
extern int __amf_log_domain;
|
||||||
extern int __gmm_log_domain;
|
extern int __gmm_log_domain;
|
||||||
|
|
||||||
|
@ -50,7 +48,7 @@ typedef uint32_t amf_m_tmsi_t;
|
||||||
typedef struct amf_context_s {
|
typedef struct amf_context_s {
|
||||||
/* Served GUAMI */
|
/* Served GUAMI */
|
||||||
uint8_t num_of_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 */
|
/* Served TAI */
|
||||||
uint8_t num_of_served_tai;
|
uint8_t num_of_served_tai;
|
||||||
|
@ -613,6 +611,7 @@ void amf_context_final(void);
|
||||||
amf_context_t *amf_self(void);
|
amf_context_t *amf_self(void);
|
||||||
|
|
||||||
int amf_context_parse_config(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);
|
amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr);
|
||||||
void amf_gnb_remove(amf_gnb_t *gnb);
|
void amf_gnb_remove(amf_gnb_t *gnb);
|
||||||
|
|
|
@ -37,12 +37,15 @@ int amf_initialize()
|
||||||
rv = ogs_sbi_context_parse_config("amf", "nrf", "scp");
|
rv = ogs_sbi_context_parse_config("amf", "nrf", "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = ogs_metrics_context_parse_config();
|
rv = ogs_metrics_context_parse_config("amf");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = amf_context_parse_config();
|
rv = amf_context_parse_config();
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
rv = amf_context_nf_info();
|
||||||
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = amf_m_tmsi_pool_generate();
|
rv = amf_m_tmsi_pool_generate();
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
extern int __ausf_log_domain;
|
extern int __ausf_log_domain;
|
||||||
|
|
||||||
#undef OGS_LOG_DOMAIN
|
#undef OGS_LOG_DOMAIN
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
#include "ogs-dbi.h"
|
#include "ogs-dbi.h"
|
||||||
#include "hss-context.h"
|
#include "hss-context.h"
|
||||||
|
#include "hss-event.h"
|
||||||
|
#include "hss-s6a-path.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct hss_impi_s hss_impi_t;
|
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_impi_t *impi = NULL;
|
||||||
hss_impu_t *impu = NULL;
|
hss_impu_t *impu = NULL;
|
||||||
|
|
||||||
ogs_assert(user_name);
|
ogs_assert(user_name);
|
||||||
ogs_assert(public_identity);
|
ogs_assert(public_identity);
|
||||||
|
|
||||||
|
@ -1171,3 +1174,134 @@ char *hss_cx_download_user_data(
|
||||||
|
|
||||||
return 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,
|
char *user_name, char *visited_network_identifier,
|
||||||
ogs_ims_data_t *ims_data);
|
ogs_ims_data_t *ims_data);
|
||||||
|
|
||||||
|
int hss_db_poll_change_stream(void);
|
||||||
|
int hss_handle_change_event(const bson_t *document);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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
|
||||||
|
|
||||||
#endif /* HSS_FD_PATH_H */
|
#endif /* HSS_FD_PATH_H */
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
|
|
||||||
#include "hss-context.h"
|
#include "hss-context.h"
|
||||||
#include "hss-fd-path.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;
|
static int initialized = 0;
|
||||||
|
|
||||||
|
@ -41,6 +46,9 @@ int hss_initialize(void)
|
||||||
rv = hss_fd_init();
|
rv = hss_fd_init();
|
||||||
if (rv != OGS_OK) return OGS_ERROR;
|
if (rv != OGS_OK) return OGS_ERROR;
|
||||||
|
|
||||||
|
thread = ogs_thread_create(hss_main, NULL);
|
||||||
|
if (!thread) return OGS_ERROR;
|
||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
|
@ -50,6 +58,9 @@ void hss_terminate(void)
|
||||||
{
|
{
|
||||||
if (!initialized) return;
|
if (!initialized) return;
|
||||||
|
|
||||||
|
hss_event_term();
|
||||||
|
ogs_thread_destroy(thread);
|
||||||
|
|
||||||
hss_fd_final();
|
hss_fd_final();
|
||||||
|
|
||||||
ogs_dbi_final();
|
ogs_dbi_final();
|
||||||
|
@ -57,3 +68,49 @@ void hss_terminate(void)
|
||||||
|
|
||||||
return;
|
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,
|
ret = fd_msg_avp_add(apn_configuration_profile,
|
||||||
MSG_BRW_LAST_CHILD, apn_configuration);
|
MSG_BRW_LAST_CHILD, apn_configuration);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD,
|
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD,
|
||||||
apn_configuration_profile);
|
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_host);
|
||||||
ogs_assert(mme_realm);
|
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.
|
* is different from the one that was last used. if so, send CLR.
|
||||||
*/
|
*/
|
||||||
if (subscription_data.mme_host != NULL &&
|
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_assert(pthread_mutex_lock(&ogs_diam_logger_self()->stats_lock) == 0);
|
||||||
ogs_diam_logger_self()->stats.nb_sent++;
|
ogs_diam_logger_self()->stats.nb_sent++;
|
||||||
ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0);
|
ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) == 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HSS received Cancel Location Answer from MME */
|
/* 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);
|
ret = fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new);
|
||||||
ogs_expect_or_return(ret == 0);
|
ogs_expect_or_return(ret == 0);
|
||||||
ogs_expect_or_return(new == 0);
|
ogs_expect_or_return(new == 0);
|
||||||
|
|
||||||
ret = fd_sess_state_retrieve(hss_s6a_reg, session, &sess_data);
|
ret = fd_sess_state_retrieve(hss_s6a_reg, session, &sess_data);
|
||||||
ogs_expect_or_return(ret == 0);
|
ogs_expect_or_return(ret == 0);
|
||||||
ogs_expect_or_return(sess_data);
|
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) {
|
if (subscription_data.purge_flag) {
|
||||||
ogs_error(" [%s] UE Purged at MME. Cannot send IDR.", imsi_bcd);
|
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 */
|
/* Create the random value to store with the session */
|
||||||
sess_data = ogs_calloc(1, sizeof(*sess_data));
|
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);
|
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the Subscription Data */
|
/* Set the Subscription Data */
|
||||||
ret = fd_msg_avp_new(ogs_diam_s6a_subscription_data, 0, &avp);
|
ret = fd_msg_avp_new(ogs_diam_s6a_subscription_data, 0, &avp);
|
||||||
ogs_assert(ret == 0);
|
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) {
|
if (ret != OGS_OK) {
|
||||||
ogs_error(" [%s] Could not build Subscription-Data.",
|
ogs_error(" [%s] Could not build Subscription-Data.",
|
||||||
imsi_bcd);
|
imsi_bcd);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
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 */
|
/* Set Vendor-Specific-Application-Id AVP */
|
||||||
ret = ogs_diam_message_vendor_specific_appid_set(
|
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);
|
ret = fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &session, &new);
|
||||||
ogs_expect_or_return(ret == 0);
|
ogs_expect_or_return(ret == 0);
|
||||||
ogs_expect_or_return(new == 0);
|
ogs_expect_or_return(new == 0);
|
||||||
|
|
||||||
ret = fd_sess_state_retrieve(hss_s6a_reg, session, &sess_data);
|
ret = fd_sess_state_retrieve(hss_s6a_reg, session, &sess_data);
|
||||||
ogs_expect_or_return(ret == 0);
|
ogs_expect_or_return(ret == 0);
|
||||||
ogs_expect_or_return(sess_data);
|
ogs_expect_or_return(sess_data);
|
||||||
|
@ -1527,7 +1528,7 @@ int hss_s6a_init(void)
|
||||||
void hss_s6a_final(void)
|
void hss_s6a_final(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = fd_sess_handler_destroy(&hss_s6a_reg, NULL);
|
ret = fd_sess_handler_destroy(&hss_s6a_reg, NULL);
|
||||||
ogs_assert(ret == OGS_OK);
|
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-context.h
|
||||||
hss-fd-path.h
|
hss-fd-path.h
|
||||||
hss-s6a-path.h
|
hss-s6a-path.h
|
||||||
|
hss-event.h
|
||||||
|
hss-sm.h
|
||||||
|
|
||||||
hss-init.c
|
hss-init.c
|
||||||
hss-context.c
|
hss-context.c
|
||||||
|
hss-event.c
|
||||||
|
hss-sm.c
|
||||||
|
|
||||||
hss-s6a-path.c
|
hss-s6a-path.c
|
||||||
hss-cx-path.c
|
hss-cx-path.c
|
||||||
|
|
|
@ -1277,6 +1277,8 @@ int mme_context_parse_config()
|
||||||
YAML_SEQUENCE_NODE);
|
YAML_SEQUENCE_NODE);
|
||||||
} else if (!strcmp(mme_key, "mme_name")) {
|
} else if (!strcmp(mme_key, "mme_name")) {
|
||||||
self.mme_name = ogs_yaml_iter_value(&mme_iter);
|
self.mme_name = ogs_yaml_iter_value(&mme_iter);
|
||||||
|
} else if (!strcmp(mme_key, "metrics")) {
|
||||||
|
/* handle config in metrics library */
|
||||||
} else
|
} else
|
||||||
ogs_warn("unknown key `%s`", mme_key);
|
ogs_warn("unknown key `%s`", mme_key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ int mme_initialize()
|
||||||
rv = ogs_gtp_context_parse_config("mme", "sgwc");
|
rv = ogs_gtp_context_parse_config("mme", "sgwc");
|
||||||
if (rv != OGS_OK) return rv;
|
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;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = mme_context_parse_config();
|
rv = mme_context_parse_config();
|
||||||
|
|
|
@ -220,7 +220,7 @@ void mme_s11_handle_create_session_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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) {
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
||||||
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
||||||
ogs_assert(OGS_OK == nas_eps_send_attach_reject(mme_ue,
|
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 &&
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE &&
|
||||||
cause_value !=
|
cause_value !=
|
||||||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
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) {
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
||||||
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
||||||
ogs_assert(OGS_OK == nas_eps_send_attach_reject(mme_ue,
|
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);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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);
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ void mme_s11_handle_delete_session_response(
|
||||||
|
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
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;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
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);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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);
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1571,7 +1571,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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);
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1639,7 +1639,7 @@ void mme_s11_handle_bearer_resource_failure_indication(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
|
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
ogs_warn("GTP Failed [CAUSE:%d] - Ignored", cause_value);
|
ogs_warn("GTP Cause [Value:%d] - Ignored", cause_value);
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,13 +102,27 @@ uint8_t mme_s6a_handle_ula(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mme_ue->session[i].name = ogs_strdup(slice_data->session[i].name);
|
if (slice_data->session[i].name) {
|
||||||
ogs_assert(mme_ue->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 =
|
mme_ue->session[i].context_identifier =
|
||||||
slice_data->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,
|
memcpy(&mme_ue->session[i].paa, &slice_data->session[i].paa,
|
||||||
sizeof(mme_ue->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;
|
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->num_of_session = i;
|
||||||
mme_ue->context_identifier = slice_data->context_identifier;
|
mme_ue->context_identifier = slice_data->context_identifier;
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
extern int __nssf_log_domain;
|
extern int __nssf_log_domain;
|
||||||
|
|
||||||
#undef OGS_LOG_DOMAIN
|
#undef OGS_LOG_DOMAIN
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
extern int __pcf_log_domain;
|
extern int __pcf_log_domain;
|
||||||
|
|
||||||
#undef OGS_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) {
|
switch (e->id) {
|
||||||
case OGS_FSM_ENTRY_SIG:
|
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_timer_start(node->t_no_heartbeat,
|
||||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||||
break;
|
break;
|
||||||
case OGS_FSM_EXIT_SIG:
|
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);
|
ogs_timer_stop(node->t_no_heartbeat);
|
||||||
break;
|
break;
|
||||||
case SGWC_EVT_SXA_MESSAGE:
|
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));
|
&message->pfcp_heartbeat_response));
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
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,
|
ogs_pfcp_cp_handle_association_setup_request(node, xact,
|
||||||
&message->pfcp_association_setup_request);
|
&message->pfcp_association_setup_request);
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
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,
|
ogs_pfcp_cp_handle_association_setup_response(node, xact,
|
||||||
&message->pfcp_association_setup_response);
|
&message->pfcp_association_setup_response);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -766,7 +766,7 @@ void sgwc_s11_handle_create_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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 ==
|
ogs_assert(OGS_OK ==
|
||||||
sgwc_pfcp_send_bearer_modification_request(
|
sgwc_pfcp_send_bearer_modification_request(
|
||||||
bearer, NULL, NULL,
|
bearer, NULL, NULL,
|
||||||
|
@ -919,7 +919,7 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
|
@ -929,7 +929,7 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
|
@ -1022,7 +1022,7 @@ void sgwc_s11_handle_delete_bearer_response(
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
} else {
|
} else {
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
@ -1062,13 +1062,13 @@ void sgwc_s11_handle_delete_bearer_response(
|
||||||
|
|
||||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
} else {
|
} else {
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
@ -1172,7 +1172,7 @@ void sgwc_s11_handle_downlink_data_notification_ack(
|
||||||
|
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
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));
|
cause_value, pfcp_cause_from_gtp(cause_value));
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
|
|
@ -79,9 +79,6 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
ogs_gtp_xact_t *s11_xact = NULL;
|
ogs_gtp_xact_t *s11_xact = NULL;
|
||||||
ogs_gtp_node_t *pgw = NULL;
|
ogs_gtp_node_t *pgw = NULL;
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
sgwc_ue = sess->sgwc_ue;
|
|
||||||
ogs_assert(sgwc_ue);
|
|
||||||
ogs_assert(gtpbuf);
|
ogs_assert(gtpbuf);
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
rsp = &message->create_session_response;
|
rsp = &message->create_session_response;
|
||||||
|
@ -99,10 +96,32 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
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
|
* 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) {
|
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");
|
ogs_error("No GTP TEID");
|
||||||
|
@ -150,7 +169,7 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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(
|
ogs_gtp_send_error_message(
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
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 &&
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE &&
|
||||||
cause_value !=
|
cause_value !=
|
||||||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
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(
|
ogs_gtp_send_error_message(
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
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_gtp_xact_t *s11_xact = NULL;
|
||||||
ogs_gtp2_modify_bearer_response_t *rsp = NULL;
|
ogs_gtp2_modify_bearer_response_t *rsp = NULL;
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
sgwc_ue = sess->sgwc_ue;
|
|
||||||
ogs_assert(sgwc_ue);
|
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
rsp = &message->modify_bearer_response;
|
rsp = &message->modify_bearer_response;
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
@ -300,10 +316,37 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
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
|
* 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) {
|
if (rsp->cause.presence == 0) {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
@ -331,7 +374,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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)
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp_send_error_message(
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
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_gtp_xact_t *s11_xact = NULL;
|
||||||
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
sgwc_ue = sess->sgwc_ue;
|
|
||||||
ogs_assert(sgwc_ue);
|
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
rsp = &message->delete_session_response;
|
rsp = &message->delete_session_response;
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
@ -404,10 +444,32 @@ void sgwc_s5c_handle_delete_session_response(
|
||||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
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
|
* 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) {
|
if (rsp->cause.presence == 0) {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
@ -430,7 +492,7 @@ void sgwc_s5c_handle_delete_session_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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(
|
ogs_gtp_send_error_message(
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
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;
|
sgwc_ue_t *sgwc_ue = NULL;
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
sgwc_ue = sess->sgwc_ue;
|
|
||||||
ogs_assert(sgwc_ue);
|
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
ind = &message->bearer_resource_failure_indication;
|
ind = &message->bearer_resource_failure_indication;
|
||||||
ogs_assert(ind);
|
ogs_assert(ind);
|
||||||
|
@ -851,6 +910,19 @@ void sgwc_s5c_handle_bearer_resource_failure_indication(
|
||||||
s11_xact = s5c_xact->assoc_xact;
|
s11_xact = s5c_xact->assoc_xact;
|
||||||
ogs_assert(s11_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
|
* Check Cause Value
|
||||||
********************/
|
********************/
|
||||||
|
|
|
@ -1325,12 +1325,21 @@ void sgwc_sxa_handle_session_report_request(
|
||||||
|
|
||||||
ogs_debug("Session Report Request");
|
ogs_debug("Session Report Request");
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
ogs_assert(pfcp_xact);
|
ogs_assert(pfcp_xact);
|
||||||
ogs_assert(pfcp_req);
|
ogs_assert(pfcp_req);
|
||||||
|
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
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) {
|
if (pfcp_req->report_type.presence == 0) {
|
||||||
ogs_error("No Report Type");
|
ogs_error("No Report Type");
|
||||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
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) {
|
switch (e->id) {
|
||||||
case OGS_FSM_ENTRY_SIG:
|
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_timer_start(node->t_no_heartbeat,
|
||||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||||
break;
|
break;
|
||||||
case OGS_FSM_EXIT_SIG:
|
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);
|
ogs_timer_stop(node->t_no_heartbeat);
|
||||||
break;
|
break;
|
||||||
case SGWU_EVT_SXA_MESSAGE:
|
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));
|
&message->pfcp_heartbeat_response));
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
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,
|
ogs_pfcp_up_handle_association_setup_request(node, xact,
|
||||||
&message->pfcp_association_setup_request);
|
&message->pfcp_association_setup_request);
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
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,
|
ogs_pfcp_up_handle_association_setup_response(node, xact,
|
||||||
&message->pfcp_association_setup_response);
|
&message->pfcp_association_setup_response);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -835,6 +835,8 @@ int smf_context_parse_config(void)
|
||||||
/* handle config in sbi library */
|
/* handle config in sbi library */
|
||||||
} else if (!strcmp(smf_key, "discovery")) {
|
} else if (!strcmp(smf_key, "discovery")) {
|
||||||
/* handle config in sbi library */
|
/* handle config in sbi library */
|
||||||
|
} else if (!strcmp(smf_key, "metrics")) {
|
||||||
|
/* handle config in metrics library */
|
||||||
} else
|
} else
|
||||||
ogs_warn("unknown key `%s`", smf_key);
|
ogs_warn("unknown key `%s`", smf_key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ int smf_initialize()
|
||||||
rv = ogs_sbi_context_parse_config("smf", "nrf", "scp");
|
rv = ogs_sbi_context_parse_config("smf", "nrf", "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
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;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = smf_context_parse_config();
|
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;
|
return OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
|
||||||
}
|
}
|
||||||
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
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;
|
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) {
|
switch (e->h.id) {
|
||||||
case OGS_FSM_ENTRY_SIG:
|
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_timer_start(node->t_no_heartbeat,
|
||||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||||
break;
|
break;
|
||||||
case OGS_FSM_EXIT_SIG:
|
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);
|
ogs_timer_stop(node->t_no_heartbeat);
|
||||||
break;
|
break;
|
||||||
case SMF_EVT_N4_MESSAGE:
|
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));
|
&message->pfcp_heartbeat_response));
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
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,
|
ogs_pfcp_cp_handle_association_setup_request(node, xact,
|
||||||
&message->pfcp_association_setup_request);
|
&message->pfcp_association_setup_request);
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
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,
|
ogs_pfcp_cp_handle_association_setup_response(node, xact,
|
||||||
&message->pfcp_association_setup_response);
|
&message->pfcp_association_setup_response);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -708,7 +708,7 @@ void smf_s5c_handle_create_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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 ==
|
ogs_assert(OGS_OK ==
|
||||||
smf_epc_pfcp_send_one_bearer_modification_request(
|
smf_epc_pfcp_send_one_bearer_modification_request(
|
||||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||||
|
@ -721,7 +721,7 @@ void smf_s5c_handle_create_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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 ==
|
ogs_assert(OGS_OK ==
|
||||||
smf_epc_pfcp_send_one_bearer_modification_request(
|
smf_epc_pfcp_send_one_bearer_modification_request(
|
||||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||||
|
@ -837,7 +837,7 @@ void smf_s5c_handle_update_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +845,7 @@ void smf_s5c_handle_update_bearer_response(
|
||||||
ogs_assert(cause);
|
ogs_assert(cause);
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,7 +925,7 @@ bool smf_s5c_handle_delete_bearer_response(
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause->value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause->value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
} else {
|
} else {
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
@ -965,13 +965,13 @@ bool smf_s5c_handle_delete_bearer_response(
|
||||||
|
|
||||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
} else {
|
} else {
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
extern int __udm_log_domain;
|
extern int __udm_log_domain;
|
||||||
|
|
||||||
#undef OGS_LOG_DOMAIN
|
#undef OGS_LOG_DOMAIN
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
extern int __udr_log_domain;
|
extern int __udr_log_domain;
|
||||||
|
|
||||||
#undef OGS_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)
|
if (!urr_acc->t_validity_time)
|
||||||
urr_acc->t_validity_time = ogs_timer_add(ogs_app()->timer_mgr,
|
urr_acc->t_validity_time = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
upf_sess_urr_acc_timers_cb, urr);
|
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)
|
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)
|
if (!urr_acc->t_time_quota)
|
||||||
urr_acc->t_time_quota = ogs_timer_add(ogs_app()->timer_mgr,
|
urr_acc->t_time_quota = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
upf_sess_urr_acc_timers_cb, urr);
|
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)
|
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)
|
if (!urr_acc->t_time_threshold)
|
||||||
urr_acc->t_time_threshold = ogs_timer_add(ogs_app()->timer_mgr,
|
urr_acc->t_time_threshold = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
upf_sess_urr_acc_timers_cb, urr);
|
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)
|
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) {
|
switch (e->id) {
|
||||||
case OGS_FSM_ENTRY_SIG:
|
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_timer_start(node->t_no_heartbeat,
|
||||||
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
ogs_app()->time.message.pfcp.no_heartbeat_duration);
|
||||||
break;
|
break;
|
||||||
case OGS_FSM_EXIT_SIG:
|
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);
|
ogs_timer_stop(node->t_no_heartbeat);
|
||||||
break;
|
break;
|
||||||
case UPF_EVT_N4_MESSAGE:
|
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));
|
&message->pfcp_heartbeat_response));
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE:
|
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,
|
ogs_pfcp_up_handle_association_setup_request(node, xact,
|
||||||
&message->pfcp_association_setup_request);
|
&message->pfcp_association_setup_request);
|
||||||
break;
|
break;
|
||||||
case OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE:
|
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,
|
ogs_pfcp_up_handle_association_setup_response(node, xact,
|
||||||
&message->pfcp_association_setup_response);
|
&message->pfcp_association_setup_response);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -36,8 +36,6 @@ extern "C" {
|
||||||
#define TEST_PING_IPV4 "10.45.0.1"
|
#define TEST_PING_IPV4 "10.45.0.1"
|
||||||
#define TEST_PING_IPV6 "2001:db8:cafe::1"
|
#define TEST_PING_IPV6 "2001:db8:cafe::1"
|
||||||
|
|
||||||
#define MAX_NUM_OF_SERVED_GUAMI 8
|
|
||||||
|
|
||||||
#define TEST_MSISDN "491725670014"
|
#define TEST_MSISDN "491725670014"
|
||||||
#define TEST_ADDITIONAL_MSISDN "491725670015"
|
#define TEST_ADDITIONAL_MSISDN "491725670015"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue