forked from acouzens/open5gs
[SCP] Support of Indirect Communication
This commit is contained in:
parent
1518a4f334
commit
5e18b2bd13
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
@ -194,6 +195,11 @@ nrf:
|
||||||
- ::1
|
- ::1
|
||||||
port: 7777
|
port: 7777
|
||||||
|
|
||||||
|
scp:
|
||||||
|
sbi:
|
||||||
|
- addr: 127.0.1.10
|
||||||
|
port: 7777
|
||||||
|
|
||||||
ausf:
|
ausf:
|
||||||
sbi:
|
sbi:
|
||||||
- addr: 127.0.0.11
|
- addr: 127.0.0.11
|
||||||
|
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
|
|
@ -29,6 +29,7 @@ open5gs_conf = '''
|
||||||
hss.yaml
|
hss.yaml
|
||||||
pcrf.yaml
|
pcrf.yaml
|
||||||
nrf.yaml
|
nrf.yaml
|
||||||
|
scp.yaml
|
||||||
ausf.yaml
|
ausf.yaml
|
||||||
udm.yaml
|
udm.yaml
|
||||||
udr.yaml
|
udr.yaml
|
||||||
|
|
|
@ -0,0 +1,213 @@
|
||||||
|
db_uri: mongodb://localhost/open5gs
|
||||||
|
|
||||||
|
#
|
||||||
|
# logger:
|
||||||
|
#
|
||||||
|
# o Set OGS_LOG_INFO to all domain level
|
||||||
|
# - If `level` is omitted, the default level is OGS_LOG_INFO)
|
||||||
|
# - If `domain` is omitted, the all domain level is set from 'level'
|
||||||
|
# (Nothing is needed)
|
||||||
|
#
|
||||||
|
# o Set OGS_LOG_ERROR to all domain level
|
||||||
|
# - `level` can be set with none, fatal, error, warn, info, debug, trace
|
||||||
|
# level: error
|
||||||
|
#
|
||||||
|
# o Set OGS_LOG_DEBUG to mme/emm domain level
|
||||||
|
# level: debug
|
||||||
|
# domain: mme,emm
|
||||||
|
#
|
||||||
|
# o Set OGS_LOG_TRACE to all domain level
|
||||||
|
# level: trace
|
||||||
|
# domain: core,sbi,scp,event,tlv,mem,sock
|
||||||
|
#
|
||||||
|
logger:
|
||||||
|
file: @localstatedir@/log/open5gs/scp.log
|
||||||
|
|
||||||
|
#
|
||||||
|
# scp:
|
||||||
|
#
|
||||||
|
# <SBI Server>
|
||||||
|
#
|
||||||
|
# o SBI Server(http://<all address available>:80)
|
||||||
|
# sbi:
|
||||||
|
#
|
||||||
|
# o SBI Server(http://<any address>:80)
|
||||||
|
# sbi:
|
||||||
|
# - addr:
|
||||||
|
# - 0.0.0.0
|
||||||
|
# - ::0
|
||||||
|
# port: 7777
|
||||||
|
#
|
||||||
|
# o SBI Server(https://<all address avaiable>:443)
|
||||||
|
# sbi:
|
||||||
|
# - tls:
|
||||||
|
# key: scp.key
|
||||||
|
# pem: scp.pem
|
||||||
|
#
|
||||||
|
# o SBI Server(https://127.0.1.10:443, http://[::1]:80)
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.1.10
|
||||||
|
# tls:
|
||||||
|
# key: scp.key
|
||||||
|
# pem: scp.pem
|
||||||
|
# - addr: ::1
|
||||||
|
#
|
||||||
|
# o SBI Server(http://scp.open5gs.org:80)
|
||||||
|
# sbi:
|
||||||
|
# - name: scp.open5gs.org
|
||||||
|
#
|
||||||
|
# o SBI Server(http://127.0.1.10:7777)
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.1.10
|
||||||
|
# port: 7777
|
||||||
|
#
|
||||||
|
# o SBI Server(http://<eth0 IP address>:80)
|
||||||
|
# sbi:
|
||||||
|
# - dev: eth0
|
||||||
|
#
|
||||||
|
# o Provide custom SBI address to be advertised to NRF
|
||||||
|
# sbi:
|
||||||
|
# - dev: eth0
|
||||||
|
# advertise: open5gs-scp.svc.local
|
||||||
|
#
|
||||||
|
# sbi:
|
||||||
|
# - addr: localhost
|
||||||
|
# advertise:
|
||||||
|
# - 127.0.0.99
|
||||||
|
# - ::1
|
||||||
|
#
|
||||||
|
# o SBI Option (Default)
|
||||||
|
# - tcp_nodelay : true
|
||||||
|
# - so_linger.l_onoff : false
|
||||||
|
#
|
||||||
|
# sbi:
|
||||||
|
# addr: 127.0.1.10
|
||||||
|
# option:
|
||||||
|
# tcp_nodelay: false
|
||||||
|
# so_linger:
|
||||||
|
# l_onoff: true
|
||||||
|
# l_linger: 10
|
||||||
|
#
|
||||||
|
# <Next hop SCP>
|
||||||
|
#
|
||||||
|
# o Next hop SCP Server(https://127.0.1.11:7777)
|
||||||
|
# next_scp:
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.1.11
|
||||||
|
# port: 7777
|
||||||
|
#
|
||||||
|
# <Discovery>
|
||||||
|
#
|
||||||
|
# o NF Discovery and Selection
|
||||||
|
# for indirect communication with Delegated Discovery;
|
||||||
|
#
|
||||||
|
# o delegated:
|
||||||
|
# o auto: (Default)
|
||||||
|
# Use next-hop SCP if next-hop SCP avaiable. Otherwise NRF is used.
|
||||||
|
# => App fails if both next-hop SCP and NRF are unavailable.
|
||||||
|
# o yes: Use next-hop SCP always.
|
||||||
|
# => App fails if no next-hop SCP available.
|
||||||
|
# o no: Don't use next-hop SCP server.
|
||||||
|
# => App fails if no NRF available.
|
||||||
|
#
|
||||||
|
# next_scp:
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.1.11
|
||||||
|
# port: 7777
|
||||||
|
# discovery:
|
||||||
|
# delegated: auto|yes|no
|
||||||
|
#
|
||||||
|
scp:
|
||||||
|
sbi:
|
||||||
|
- addr: 127.0.1.10
|
||||||
|
port: 7777
|
||||||
|
|
||||||
|
#
|
||||||
|
# nrf:
|
||||||
|
#
|
||||||
|
# <SBI Client>>
|
||||||
|
#
|
||||||
|
# o SBI Client(http://127.0.0.10:7777)
|
||||||
|
# sbi:
|
||||||
|
# addr: 127.0.0.10
|
||||||
|
# port: 7777
|
||||||
|
#
|
||||||
|
# o SBI Client(https://127.0.0.10:443, http://nrf.open5gs.org:80)
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.0.10
|
||||||
|
# tls:
|
||||||
|
# key: nrf.key
|
||||||
|
# pem: nrf.pem
|
||||||
|
# - name: nrf.open5gs.org
|
||||||
|
#
|
||||||
|
# o SBI Client(http://[fd69:f21d:873c:fa::1]:80)
|
||||||
|
# If prefer_ipv4 is true, http://127.0.0.10:80 is selected.
|
||||||
|
#
|
||||||
|
# sbi:
|
||||||
|
# addr:
|
||||||
|
# - 127.0.0.10
|
||||||
|
# - fd69:f21d:873c:fa::1
|
||||||
|
#
|
||||||
|
# o SBI Option (Default)
|
||||||
|
# - tcp_nodelay : true
|
||||||
|
# - so_linger.l_onoff : false
|
||||||
|
#
|
||||||
|
# sbi:
|
||||||
|
# addr: 127.0.0.10
|
||||||
|
# option:
|
||||||
|
# tcp_nodelay: false
|
||||||
|
# so_linger:
|
||||||
|
# l_onoff: true
|
||||||
|
# l_linger: 10
|
||||||
|
#
|
||||||
|
nrf:
|
||||||
|
sbi:
|
||||||
|
- addr:
|
||||||
|
- 127.0.0.10
|
||||||
|
- ::1
|
||||||
|
port: 7777
|
||||||
|
|
||||||
|
#
|
||||||
|
# parameter:
|
||||||
|
#
|
||||||
|
# o Disable use of IPv4 addresses (only IPv6)
|
||||||
|
# no_ipv4: true
|
||||||
|
#
|
||||||
|
# o Disable use of IPv6 addresses (only IPv4)
|
||||||
|
# no_ipv6: true
|
||||||
|
#
|
||||||
|
# o Prefer IPv4 instead of IPv6 for estabishing new GTP connections.
|
||||||
|
# prefer_ipv4: true
|
||||||
|
#
|
||||||
|
parameter:
|
||||||
|
|
||||||
|
#
|
||||||
|
# max:
|
||||||
|
#
|
||||||
|
# o Maximum Number of UE per AMF/MME
|
||||||
|
# ue: 1024
|
||||||
|
# o Maximum Number of gNB/eNB per AMF/MME
|
||||||
|
# gnb: 64
|
||||||
|
#
|
||||||
|
max:
|
||||||
|
|
||||||
|
#
|
||||||
|
# time:
|
||||||
|
#
|
||||||
|
# o NF Instance Heartbeat (Default : 0)
|
||||||
|
# NFs will not send heart-beat timer in NFProfile
|
||||||
|
# NRF will send heart-beat timer in NFProfile
|
||||||
|
#
|
||||||
|
# o NF Instance Heartbeat (20 seconds)
|
||||||
|
# NFs will send heart-beat timer (20 seconds) in NFProfile
|
||||||
|
# NRF can change heart-beat timer in NFProfile
|
||||||
|
#
|
||||||
|
# nf_instance:
|
||||||
|
# heartbeat: 20
|
||||||
|
#
|
||||||
|
# o Message Wait Duration (Default : 10,000 ms = 10 seconds)
|
||||||
|
#
|
||||||
|
# o Message Wait Duration (3000 ms)
|
||||||
|
# message:
|
||||||
|
# duration: 3000
|
||||||
|
time:
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
@ -194,6 +195,70 @@ nrf:
|
||||||
- ::1
|
- ::1
|
||||||
port: 7777
|
port: 7777
|
||||||
|
|
||||||
|
#
|
||||||
|
# scp:
|
||||||
|
#
|
||||||
|
# <SBI Client>>
|
||||||
|
#
|
||||||
|
# o SBI Client(http://127.0.0.10:7777)
|
||||||
|
# sbi:
|
||||||
|
# addr: 127.0.0.10
|
||||||
|
# port: 7777
|
||||||
|
#
|
||||||
|
# o SBI Client(https://127.0.0.10:443, http://scp.open5gs.org:80)
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.0.10
|
||||||
|
# tls:
|
||||||
|
# key: scp.key
|
||||||
|
# pem: scp.pem
|
||||||
|
# - name: scp.open5gs.org
|
||||||
|
#
|
||||||
|
# o SBI Client(http://[fd69:f21d:873c:fa::1]:80)
|
||||||
|
# If prefer_ipv4 is true, http://127.0.0.10:80 is selected.
|
||||||
|
#
|
||||||
|
# sbi:
|
||||||
|
# addr:
|
||||||
|
# - 127.0.0.10
|
||||||
|
# - fd69:f21d:873c:fa::1
|
||||||
|
#
|
||||||
|
# o SBI Option (Default)
|
||||||
|
# - tcp_nodelay : true
|
||||||
|
# - so_linger.l_onoff : false
|
||||||
|
#
|
||||||
|
# sbi:
|
||||||
|
# addr: 127.0.0.10
|
||||||
|
# option:
|
||||||
|
# tcp_nodelay: false
|
||||||
|
# so_linger:
|
||||||
|
# l_onoff: true
|
||||||
|
# l_linger: 10
|
||||||
|
#
|
||||||
|
# <Discovery>
|
||||||
|
#
|
||||||
|
# o NF Discovery and Selection
|
||||||
|
# for indirect communication with Delegated Discovery;
|
||||||
|
#
|
||||||
|
# o delegated:
|
||||||
|
# o auto: (Default)
|
||||||
|
# Use SCP if SCP avaiable. Otherwise NRF is used.
|
||||||
|
# => App fails if both NRF and SCP are unavailable.
|
||||||
|
# o yes: Use SCP always.
|
||||||
|
# => App fails if no SCP available.
|
||||||
|
# o no: Don't use SCP server.
|
||||||
|
# => App fails if no NRF available.
|
||||||
|
#
|
||||||
|
# scp:
|
||||||
|
# sbi:
|
||||||
|
# - addr: 127.0.1.10
|
||||||
|
# port: 7777
|
||||||
|
# discovery:
|
||||||
|
# delegated: auto|yes|no
|
||||||
|
#
|
||||||
|
scp:
|
||||||
|
sbi:
|
||||||
|
- addr: 127.0.1.10
|
||||||
|
port: 7777
|
||||||
|
|
||||||
ausf:
|
ausf:
|
||||||
sbi:
|
sbi:
|
||||||
- addr: 127.0.0.11
|
- addr: 127.0.0.11
|
||||||
|
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
|
|
@ -4,6 +4,7 @@ logger:
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
# no_nrf: true
|
# no_nrf: true
|
||||||
|
# no_scp: true
|
||||||
# no_amf: true
|
# no_amf: true
|
||||||
# no_smf: true
|
# no_smf: true
|
||||||
# no_upf: true
|
# no_upf: true
|
||||||
|
@ -199,6 +200,11 @@ nrf:
|
||||||
- ::1
|
- ::1
|
||||||
port: 7777
|
port: 7777
|
||||||
|
|
||||||
|
scp:
|
||||||
|
sbi:
|
||||||
|
- addr: 127.0.1.10
|
||||||
|
port: 7777
|
||||||
|
|
||||||
ausf:
|
ausf:
|
||||||
sbi:
|
sbi:
|
||||||
- addr: 127.0.0.11
|
- addr: 127.0.0.11
|
||||||
|
|
|
@ -94,6 +94,9 @@ void smf_terminate(void);
|
||||||
int amf_initialize(void);
|
int amf_initialize(void);
|
||||||
void amf_terminate(void);
|
void amf_terminate(void);
|
||||||
|
|
||||||
|
int scp_initialize(void);
|
||||||
|
void scp_terminate(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -113,7 +113,7 @@ static void regenerate_all_timer_duration(void)
|
||||||
ogs_max(ogs_time_from_sec(3),
|
ogs_max(ogs_time_from_sec(3),
|
||||||
self.time.message.sbi.client_wait_duration + ogs_time_from_sec(1));
|
self.time.message.sbi.client_wait_duration + ogs_time_from_sec(1));
|
||||||
self.time.message.sbi.nf_register_interval_in_exception =
|
self.time.message.sbi.nf_register_interval_in_exception =
|
||||||
ogs_time_from_msec(300);
|
ogs_time_from_sec(2);
|
||||||
|
|
||||||
#define PFCP_N1_RESPONSE_RETRY_COUNT 3
|
#define PFCP_N1_RESPONSE_RETRY_COUNT 3
|
||||||
self.time.message.pfcp.n1_response_rcount = PFCP_N1_RESPONSE_RETRY_COUNT;
|
self.time.message.pfcp.n1_response_rcount = PFCP_N1_RESPONSE_RETRY_COUNT;
|
||||||
|
@ -316,6 +316,9 @@ int ogs_app_context_parse_config(void)
|
||||||
} else if (!strcmp(parameter_key, "no_nrf")) {
|
} else if (!strcmp(parameter_key, "no_nrf")) {
|
||||||
self.parameter.no_nrf =
|
self.parameter.no_nrf =
|
||||||
ogs_yaml_iter_bool(¶meter_iter);
|
ogs_yaml_iter_bool(¶meter_iter);
|
||||||
|
} else if (!strcmp(parameter_key, "no_scp")) {
|
||||||
|
self.parameter.no_scp =
|
||||||
|
ogs_yaml_iter_bool(¶meter_iter);
|
||||||
} else if (!strcmp(parameter_key, "no_amf")) {
|
} else if (!strcmp(parameter_key, "no_amf")) {
|
||||||
self.parameter.no_amf =
|
self.parameter.no_amf =
|
||||||
ogs_yaml_iter_bool(¶meter_iter);
|
ogs_yaml_iter_bool(¶meter_iter);
|
||||||
|
|
|
@ -64,6 +64,7 @@ typedef struct ogs_app_context_s {
|
||||||
int no_nssf;
|
int no_nssf;
|
||||||
int no_bsf;
|
int no_bsf;
|
||||||
int no_udr;
|
int no_udr;
|
||||||
|
int no_scp;
|
||||||
int no_nrf;
|
int no_nrf;
|
||||||
|
|
||||||
/* Network */
|
/* Network */
|
||||||
|
|
252
lib/sbi/client.c
252
lib/sbi/client.c
|
@ -176,6 +176,26 @@ ogs_sbi_client_t *ogs_sbi_client_find(ogs_sockaddr_t *addr)
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ogs_sbi_client_stop(ogs_sbi_client_t *client)
|
||||||
|
{
|
||||||
|
connection_t *conn = NULL;
|
||||||
|
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
ogs_list_for_each(&client->connection_list, conn) {
|
||||||
|
ogs_assert(conn->client_cb);
|
||||||
|
conn->client_cb(OGS_DONE, NULL, conn->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ogs_sbi_client_stop_all(void)
|
||||||
|
{
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
ogs_list_for_each(&ogs_sbi_self()->client_list, client)
|
||||||
|
ogs_sbi_client_stop(client);
|
||||||
|
}
|
||||||
|
|
||||||
#define mycase(code) \
|
#define mycase(code) \
|
||||||
case code: s = OGS_STRINGIFY(code)
|
case code: s = OGS_STRINGIFY(code)
|
||||||
|
|
||||||
|
@ -246,6 +266,8 @@ static char *add_params_to_uri(CURL *easy, char *uri, ogs_hash_t *params)
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _connection_remove(connection_t *conn);
|
||||||
|
|
||||||
static connection_t *connection_add(
|
static connection_t *connection_add(
|
||||||
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
ogs_sbi_request_t *request, void *data)
|
ogs_sbi_request_t *request, void *data)
|
||||||
|
@ -269,19 +291,31 @@ static connection_t *connection_add(
|
||||||
conn->data = data;
|
conn->data = data;
|
||||||
|
|
||||||
conn->method = ogs_strdup(request->h.method);
|
conn->method = ogs_strdup(request->h.method);
|
||||||
ogs_expect_or_return_val(conn->method, NULL);
|
if (!conn->method) {
|
||||||
|
ogs_error("conn->method is NULL");
|
||||||
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
conn->num_of_header = ogs_hash_count(request->http.headers);
|
conn->num_of_header = ogs_hash_count(request->http.headers);
|
||||||
if (conn->num_of_header) {
|
if (conn->num_of_header) {
|
||||||
conn->headers = ogs_calloc(conn->num_of_header, sizeof(char *));
|
conn->headers = ogs_calloc(conn->num_of_header, sizeof(char *));
|
||||||
ogs_expect_or_return_val(conn->headers, NULL);
|
if (!conn->headers) {
|
||||||
|
ogs_error("conn->headers is NULL");
|
||||||
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
for (hi = ogs_hash_first(request->http.headers), i = 0;
|
for (hi = ogs_hash_first(request->http.headers), i = 0;
|
||||||
hi && i < conn->num_of_header; hi = ogs_hash_next(hi), i++) {
|
hi && i < conn->num_of_header; hi = ogs_hash_next(hi), i++) {
|
||||||
const char *key = ogs_hash_this_key(hi);
|
const char *key = ogs_hash_this_key(hi);
|
||||||
char *val = ogs_hash_this_val(hi);
|
char *val = ogs_hash_this_val(hi);
|
||||||
|
|
||||||
conn->headers[i] = ogs_msprintf("%s: %s", key, val);
|
conn->headers[i] = ogs_msprintf("%s: %s", key, val);
|
||||||
ogs_expect_or_return_val(conn->headers[i], NULL);
|
if (!conn->headers[i]) {
|
||||||
|
ogs_error("conn->headers[i=%d] is NULL", i);
|
||||||
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
conn->header_list = curl_slist_append(
|
conn->header_list = curl_slist_append(
|
||||||
conn->header_list, conn->headers[i]);
|
conn->header_list, conn->headers[i]);
|
||||||
}
|
}
|
||||||
|
@ -289,9 +323,11 @@ static connection_t *connection_add(
|
||||||
|
|
||||||
conn->timer = ogs_timer_add(
|
conn->timer = ogs_timer_add(
|
||||||
ogs_app()->timer_mgr, connection_timer_expired, conn);
|
ogs_app()->timer_mgr, connection_timer_expired, conn);
|
||||||
ogs_expect_or_return_val(conn->timer, NULL);
|
if (!conn->timer) {
|
||||||
|
ogs_error("conn->timer is NULL");
|
||||||
ogs_list_add(&client->connection_list, conn);
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* If http response is not received within deadline,
|
/* If http response is not received within deadline,
|
||||||
* Open5GS will discard this request. */
|
* Open5GS will discard this request. */
|
||||||
|
@ -299,7 +335,23 @@ static connection_t *connection_add(
|
||||||
ogs_app()->time.message.sbi.connection_deadline);
|
ogs_app()->time.message.sbi.connection_deadline);
|
||||||
|
|
||||||
conn->easy = curl_easy_init();
|
conn->easy = curl_easy_init();
|
||||||
ogs_assert(conn->easy);
|
if (!conn->easy) {
|
||||||
|
ogs_error("conn->easy is NULL");
|
||||||
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ogs_hash_count(request->http.params)) {
|
||||||
|
char *uri = add_params_to_uri(conn->easy,
|
||||||
|
request->h.uri, request->http.params);
|
||||||
|
if (!uri) {
|
||||||
|
ogs_error("add_params_to_uri() failed");
|
||||||
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->h.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
/* HTTP Method */
|
/* HTTP Method */
|
||||||
if (strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PUT) == 0 ||
|
if (strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PUT) == 0 ||
|
||||||
|
@ -312,7 +364,11 @@ static connection_t *connection_add(
|
||||||
if (request->http.content) {
|
if (request->http.content) {
|
||||||
conn->content = ogs_memdup(
|
conn->content = ogs_memdup(
|
||||||
request->http.content, request->http.content_length);
|
request->http.content, request->http.content_length);
|
||||||
ogs_assert(conn->content);
|
if (!conn->content) {
|
||||||
|
ogs_error("conn->content is NULL");
|
||||||
|
_connection_remove(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
curl_easy_setopt(conn->easy,
|
curl_easy_setopt(conn->easy,
|
||||||
CURLOPT_POSTFIELDS, conn->content);
|
CURLOPT_POSTFIELDS, conn->content);
|
||||||
curl_easy_setopt(conn->easy,
|
curl_easy_setopt(conn->easy,
|
||||||
|
@ -336,11 +392,7 @@ static connection_t *connection_add(
|
||||||
CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
|
CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ogs_hash_count(request->http.params)) {
|
ogs_list_add(&client->connection_list, conn);
|
||||||
request->h.uri = add_params_to_uri(conn->easy,
|
|
||||||
request->h.uri, request->http.params);
|
|
||||||
ogs_expect_or_return_val(request->h.uri, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(conn->easy, CURLOPT_URL, request->h.uri);
|
curl_easy_setopt(conn->easy, CURLOPT_URL, request->h.uri);
|
||||||
|
|
||||||
|
@ -358,27 +410,11 @@ static connection_t *connection_add(
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connection_remove(connection_t *conn)
|
static void _connection_remove(connection_t *conn)
|
||||||
{
|
{
|
||||||
ogs_sbi_client_t *client = NULL;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ogs_assert(conn);
|
ogs_assert(conn);
|
||||||
client = conn->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
ogs_list_remove(&client->connection_list, conn);
|
|
||||||
|
|
||||||
ogs_assert(conn->timer);
|
|
||||||
ogs_timer_delete(conn->timer);
|
|
||||||
|
|
||||||
ogs_assert(conn->easy);
|
|
||||||
ogs_assert(client->multi);
|
|
||||||
curl_multi_remove_handle(client->multi, conn->easy);
|
|
||||||
curl_easy_cleanup(conn->easy);
|
|
||||||
|
|
||||||
ogs_assert(conn->method);
|
|
||||||
ogs_free(conn->method);
|
|
||||||
|
|
||||||
if (conn->content)
|
if (conn->content)
|
||||||
ogs_free(conn->content);
|
ogs_free(conn->content);
|
||||||
|
@ -386,19 +422,45 @@ static void connection_remove(connection_t *conn)
|
||||||
if (conn->location)
|
if (conn->location)
|
||||||
ogs_free(conn->location);
|
ogs_free(conn->location);
|
||||||
|
|
||||||
|
if (conn->memory)
|
||||||
|
ogs_free(conn->memory);
|
||||||
|
|
||||||
|
if (conn->easy)
|
||||||
|
curl_easy_cleanup(conn->easy);
|
||||||
|
|
||||||
|
if (conn->timer)
|
||||||
|
ogs_timer_delete(conn->timer);
|
||||||
|
|
||||||
if (conn->num_of_header) {
|
if (conn->num_of_header) {
|
||||||
for (i = 0; i < conn->num_of_header; i++)
|
for (i = 0; i < conn->num_of_header; i++)
|
||||||
ogs_free(conn->headers[i]);
|
if (conn->headers[i])
|
||||||
|
ogs_free(conn->headers[i]);
|
||||||
ogs_free(conn->headers);
|
ogs_free(conn->headers);
|
||||||
}
|
}
|
||||||
curl_slist_free_all(conn->header_list);
|
curl_slist_free_all(conn->header_list);
|
||||||
|
|
||||||
if (conn->memory)
|
if (conn->method)
|
||||||
ogs_free(conn->memory);
|
ogs_free(conn->method);
|
||||||
|
|
||||||
ogs_pool_free(&connection_pool, conn);
|
ogs_pool_free(&connection_pool, conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void connection_remove(connection_t *conn)
|
||||||
|
{
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
ogs_assert(conn);
|
||||||
|
client = conn->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
ogs_list_remove(&client->connection_list, conn);
|
||||||
|
|
||||||
|
ogs_assert(client->multi);
|
||||||
|
curl_multi_remove_handle(client->multi, conn->easy);
|
||||||
|
|
||||||
|
_connection_remove(conn);
|
||||||
|
}
|
||||||
|
|
||||||
static void connection_remove_all(ogs_sbi_client_t *client)
|
static void connection_remove_all(ogs_sbi_client_t *client)
|
||||||
{
|
{
|
||||||
connection_t *conn = NULL, *next_conn = NULL;
|
connection_t *conn = NULL, *next_conn = NULL;
|
||||||
|
@ -416,6 +478,11 @@ static void connection_timer_expired(void *data)
|
||||||
conn = data;
|
conn = data;
|
||||||
ogs_assert(conn);
|
ogs_assert(conn);
|
||||||
|
|
||||||
|
ogs_error("Connection timer expired");
|
||||||
|
|
||||||
|
ogs_assert(conn->client_cb);
|
||||||
|
conn->client_cb(OGS_TIMEUP, NULL, conn->data);
|
||||||
|
|
||||||
connection_remove(conn);
|
connection_remove(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,12 +554,12 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
if (conn->location)
|
if (conn->location)
|
||||||
ogs_sbi_header_set(response->http.headers,
|
ogs_sbi_header_set(response->http.headers,
|
||||||
OGS_SBI_LOCATION, conn->location);
|
OGS_SBI_LOCATION, conn->location);
|
||||||
|
|
||||||
ogs_assert(conn->client_cb);
|
|
||||||
conn->client_cb(response, conn->data);
|
|
||||||
} else
|
} else
|
||||||
ogs_warn("[%d] %s", res, conn->error);
|
ogs_warn("[%d] %s", res, conn->error);
|
||||||
|
|
||||||
|
ogs_assert(conn->client_cb);
|
||||||
|
conn->client_cb(res == CURLE_OK ? OGS_OK : OGS_ERROR,
|
||||||
|
response, conn->data);
|
||||||
connection_remove(conn);
|
connection_remove(conn);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -502,7 +569,7 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ogs_sbi_client_send_request(
|
bool ogs_sbi_client_send_reqmem_persistent(
|
||||||
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
ogs_sbi_request_t *request, void *data)
|
ogs_sbi_request_t *request, void *data)
|
||||||
{
|
{
|
||||||
|
@ -513,17 +580,128 @@ bool ogs_sbi_client_send_request(
|
||||||
|
|
||||||
if (request->h.uri == NULL) {
|
if (request->h.uri == NULL) {
|
||||||
request->h.uri = ogs_sbi_client_uri(client, &request->h);
|
request->h.uri = ogs_sbi_client_uri(client, &request->h);
|
||||||
|
ogs_expect_or_return_val(request->h.uri, false);
|
||||||
}
|
}
|
||||||
ogs_debug("[%s] %s", request->h.method, request->h.uri);
|
ogs_debug("[%s] %s", request->h.method, request->h.uri);
|
||||||
|
|
||||||
conn = connection_add(client, client_cb, request, data);
|
conn = connection_add(client, client_cb, request, data);
|
||||||
ogs_expect_or_return_val(conn, false);
|
ogs_expect_or_return_val(conn, false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ogs_sbi_client_send_request(
|
||||||
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
|
ogs_sbi_request_t *request, void *data)
|
||||||
|
{
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
ogs_assert(client);
|
||||||
|
ogs_assert(request);
|
||||||
|
|
||||||
|
rc = ogs_sbi_client_send_reqmem_persistent(
|
||||||
|
client, client_cb, request, data);
|
||||||
|
ogs_expect(rc == true);
|
||||||
|
|
||||||
ogs_sbi_request_free(request);
|
ogs_sbi_request_free(request);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ogs_sbi_scp_send_reqmem_persistent(
|
||||||
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
|
ogs_sbi_request_t *request, void *data)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *scp_instance = NULL;
|
||||||
|
connection_t *conn = NULL;
|
||||||
|
char *apiroot = NULL;
|
||||||
|
|
||||||
|
ogs_assert(client);
|
||||||
|
ogs_assert(request);
|
||||||
|
|
||||||
|
scp_instance = ogs_sbi_self()->scp_instance;
|
||||||
|
|
||||||
|
if (scp_instance) {
|
||||||
|
/*
|
||||||
|
* In case of indirect communication using SCP,
|
||||||
|
* add 3gpp-Sbi-Target-apiRoot to HTTP header and
|
||||||
|
* change CLIENT instance to SCP.
|
||||||
|
*/
|
||||||
|
apiroot = ogs_sbi_client_apiroot(client);
|
||||||
|
ogs_assert(apiroot);
|
||||||
|
|
||||||
|
ogs_sbi_header_set(request->http.headers,
|
||||||
|
OGS_SBI_CUSTOM_TARGET_APIROOT, apiroot);
|
||||||
|
|
||||||
|
ogs_free(apiroot);
|
||||||
|
|
||||||
|
client = scp_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->h.uri == NULL) {
|
||||||
|
/*
|
||||||
|
* Regardless of direct or indirect communication,
|
||||||
|
* if there is no URI, we automatically creates a URI
|
||||||
|
* with Client Address and request->h
|
||||||
|
*/
|
||||||
|
request->h.uri = ogs_sbi_client_uri(client, &request->h);
|
||||||
|
ogs_assert(request->h.uri);
|
||||||
|
|
||||||
|
ogs_debug("[%s] %s", request->h.method, request->h.uri);
|
||||||
|
|
||||||
|
} else if (scp_instance) {
|
||||||
|
/*
|
||||||
|
* In case of indirect communication using SCP,
|
||||||
|
* If the full URI is already defined, change full URI to SCP as below.
|
||||||
|
*
|
||||||
|
* OLD: http://127.0.0.5:7777/nnrf-nfm/v1/nf-status-notify
|
||||||
|
* NEW: https://scp.open5gs.org/nnrf-nfm/v1/nf-status-notify
|
||||||
|
*/
|
||||||
|
char *path = NULL;
|
||||||
|
char *old = NULL;
|
||||||
|
|
||||||
|
old = request->h.uri;
|
||||||
|
|
||||||
|
apiroot = ogs_sbi_client_apiroot(client);
|
||||||
|
ogs_assert(apiroot);
|
||||||
|
|
||||||
|
path = ogs_sbi_getpath_from_uri(request->h.uri);
|
||||||
|
ogs_assert(path);
|
||||||
|
|
||||||
|
request->h.uri = ogs_msprintf("%s/%s", apiroot, path);
|
||||||
|
ogs_assert(request->h.uri);
|
||||||
|
|
||||||
|
ogs_free(apiroot);
|
||||||
|
ogs_free(path);
|
||||||
|
ogs_free(old);
|
||||||
|
|
||||||
|
ogs_debug("[%s] %s", request->h.method, request->h.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = connection_add(client, client_cb, request, data);
|
||||||
|
ogs_expect_or_return_val(conn, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ogs_sbi_scp_send_request(
|
||||||
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
|
ogs_sbi_request_t *request, void *data)
|
||||||
|
{
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
ogs_assert(client);
|
||||||
|
ogs_assert(request);
|
||||||
|
|
||||||
|
rc = ogs_sbi_scp_send_reqmem_persistent(client, client_cb, request, data);
|
||||||
|
ogs_expect(rc == true);
|
||||||
|
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data)
|
static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data)
|
||||||
{
|
{
|
||||||
size_t realsize = 0;
|
size_t realsize = 0;
|
||||||
|
|
|
@ -53,7 +53,8 @@ extern "C" {
|
||||||
(__pClient)->reference_count); \
|
(__pClient)->reference_count); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
typedef int (*ogs_sbi_client_cb_f)(ogs_sbi_response_t *response, void *data);
|
typedef int (*ogs_sbi_client_cb_f)(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data);
|
||||||
|
|
||||||
typedef struct ogs_sbi_client_s {
|
typedef struct ogs_sbi_client_s {
|
||||||
ogs_socknode_t node;
|
ogs_socknode_t node;
|
||||||
|
@ -84,10 +85,23 @@ void ogs_sbi_client_remove(ogs_sbi_client_t *client);
|
||||||
void ogs_sbi_client_remove_all(void);
|
void ogs_sbi_client_remove_all(void);
|
||||||
ogs_sbi_client_t *ogs_sbi_client_find(ogs_sockaddr_t *addr);
|
ogs_sbi_client_t *ogs_sbi_client_find(ogs_sockaddr_t *addr);
|
||||||
|
|
||||||
|
void ogs_sbi_client_stop(ogs_sbi_client_t *client);
|
||||||
|
void ogs_sbi_client_stop_all(void);
|
||||||
|
|
||||||
|
bool ogs_sbi_client_send_reqmem_persistent(
|
||||||
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
|
ogs_sbi_request_t *request, void *data);
|
||||||
bool ogs_sbi_client_send_request(
|
bool ogs_sbi_client_send_request(
|
||||||
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
ogs_sbi_request_t *request, void *data);
|
ogs_sbi_request_t *request, void *data);
|
||||||
|
|
||||||
|
bool ogs_sbi_scp_send_reqmem_persistent(
|
||||||
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
|
ogs_sbi_request_t *request, void *data);
|
||||||
|
bool ogs_sbi_scp_send_request(
|
||||||
|
ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb,
|
||||||
|
ogs_sbi_request_t *request, void *data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -111,7 +111,8 @@ static int ogs_sbi_context_prepare(void)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ogs_sbi_context_validation(const char *local)
|
static int ogs_sbi_context_validation(
|
||||||
|
const char *local, const char *nrf, const char *scp)
|
||||||
{
|
{
|
||||||
/* If SMF is only used in 4G EPC, no SBI interface is required. */
|
/* If SMF is only used in 4G EPC, no SBI interface is required. */
|
||||||
if (strcmp(local, "smf") != 0 &&
|
if (strcmp(local, "smf") != 0 &&
|
||||||
|
@ -120,10 +121,48 @@ static int ogs_sbi_context_validation(const char *local)
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context_initialized == 1) {
|
||||||
|
switch (self.discovery_config.delegated) {
|
||||||
|
case OGS_SBI_DISCOVERY_DELEGATED_AUTO:
|
||||||
|
if (strcmp(local, "nrf") != 0 && /* Skip NRF */
|
||||||
|
strcmp(local, "smf") != 0 && /* Skip SMF since SMF can run 4G */
|
||||||
|
ogs_sbi_self()->nrf_instance == NULL &&
|
||||||
|
ogs_sbi_self()->scp_instance == NULL) {
|
||||||
|
ogs_error("DELEGATED_AUTO - Both NRF and %s are unavailable",
|
||||||
|
strcmp(scp, "next_scp") == 0 ? "Next-hop SCP" : "SCP");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OGS_SBI_DISCOVERY_DELEGATED_YES:
|
||||||
|
if (ogs_sbi_self()->scp_instance == NULL) {
|
||||||
|
ogs_error("DELEGATED_YES - no %s available",
|
||||||
|
strcmp(scp, "next_scp") == 0 ? "Next-hop SCP" : "SCP");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OGS_SBI_DISCOVERY_DELEGATED_NO:
|
||||||
|
if (ogs_sbi_self()->nrf_instance == NULL) {
|
||||||
|
ogs_error("DELEGATED_NO - no NRF available");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ogs_fatal("Invalid dicovery-config delegated [%d]",
|
||||||
|
self.discovery_config.delegated);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ogs_sbi_context_parse_config(const char *local, const char *remote)
|
ogs_sbi_nf_instance_t *ogs_sbi_scp_instance(void)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ogs_sbi_context_parse_config(
|
||||||
|
const char *local, const char *nrf, const char *scp)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
yaml_document_t *document = NULL;
|
yaml_document_t *document = NULL;
|
||||||
|
@ -363,17 +402,17 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (remote && !strcmp(root_key, remote)) {
|
} else if (nrf && !strcmp(root_key, nrf)) {
|
||||||
ogs_yaml_iter_t remote_iter;
|
ogs_yaml_iter_t nrf_iter;
|
||||||
ogs_yaml_iter_recurse(&root_iter, &remote_iter);
|
ogs_yaml_iter_recurse(&root_iter, &nrf_iter);
|
||||||
while (ogs_yaml_iter_next(&remote_iter)) {
|
while (ogs_yaml_iter_next(&nrf_iter)) {
|
||||||
const char *remote_key = ogs_yaml_iter_key(&remote_iter);
|
const char *nrf_key = ogs_yaml_iter_key(&nrf_iter);
|
||||||
ogs_assert(remote_key);
|
ogs_assert(nrf_key);
|
||||||
if (!strcmp(remote_key, "sbi")) {
|
if (!strcmp(nrf_key, "sbi")) {
|
||||||
ogs_yaml_iter_t sbi_array, sbi_iter;
|
ogs_yaml_iter_t sbi_array, sbi_iter;
|
||||||
ogs_yaml_iter_recurse(&remote_iter, &sbi_array);
|
ogs_yaml_iter_recurse(&nrf_iter, &sbi_array);
|
||||||
do {
|
do {
|
||||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
ogs_sbi_nf_instance_t *nrf_instance = NULL;
|
||||||
ogs_sbi_client_t *client = NULL;
|
ogs_sbi_client_t *client = NULL;
|
||||||
ogs_sockaddr_t *addr = NULL;
|
ogs_sockaddr_t *addr = NULL;
|
||||||
int family = AF_UNSPEC;
|
int family = AF_UNSPEC;
|
||||||
|
@ -476,12 +515,13 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
|
||||||
client = ogs_sbi_client_add(addr);
|
client = ogs_sbi_client_add(addr);
|
||||||
ogs_assert(client);
|
ogs_assert(client);
|
||||||
|
|
||||||
nf_instance = ogs_sbi_nf_instance_add();
|
ogs_sbi_self()->nrf_instance =
|
||||||
ogs_assert(nf_instance);
|
nrf_instance = ogs_sbi_nf_instance_add();
|
||||||
|
ogs_assert(nrf_instance);
|
||||||
ogs_sbi_nf_instance_set_type(
|
ogs_sbi_nf_instance_set_type(
|
||||||
nf_instance, OpenAPI_nf_type_NRF);
|
nrf_instance, OpenAPI_nf_type_NRF);
|
||||||
|
|
||||||
OGS_SBI_SETUP_CLIENT(nf_instance, client);
|
OGS_SBI_SETUP_CLIENT(nrf_instance, client);
|
||||||
|
|
||||||
if (key) client->tls.key = key;
|
if (key) client->tls.key = key;
|
||||||
if (pem) client->tls.pem = pem;
|
if (pem) client->tls.pem = pem;
|
||||||
|
@ -492,10 +532,175 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
|
||||||
YAML_SEQUENCE_NODE);
|
YAML_SEQUENCE_NODE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (scp && !strcmp(root_key, scp)) {
|
||||||
|
ogs_yaml_iter_t scp_iter;
|
||||||
|
ogs_yaml_iter_recurse(&root_iter, &scp_iter);
|
||||||
|
while (ogs_yaml_iter_next(&scp_iter)) {
|
||||||
|
const char *scp_key = ogs_yaml_iter_key(&scp_iter);
|
||||||
|
ogs_assert(scp_key);
|
||||||
|
if (!strcmp(scp_key, "sbi")) {
|
||||||
|
ogs_yaml_iter_t sbi_array, sbi_iter;
|
||||||
|
ogs_yaml_iter_recurse(&scp_iter, &sbi_array);
|
||||||
|
do {
|
||||||
|
ogs_sbi_nf_instance_t *scp_instance = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
ogs_sockaddr_t *addr = NULL;
|
||||||
|
int family = AF_UNSPEC;
|
||||||
|
int i, num = 0;
|
||||||
|
const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
|
||||||
|
uint16_t port = self.sbi_port;
|
||||||
|
const char *key = NULL;
|
||||||
|
const char *pem = NULL;
|
||||||
|
|
||||||
|
if (ogs_yaml_iter_type(&sbi_array) ==
|
||||||
|
YAML_MAPPING_NODE) {
|
||||||
|
memcpy(&sbi_iter, &sbi_array,
|
||||||
|
sizeof(ogs_yaml_iter_t));
|
||||||
|
} else if (ogs_yaml_iter_type(&sbi_array) ==
|
||||||
|
YAML_SEQUENCE_NODE) {
|
||||||
|
if (!ogs_yaml_iter_next(&sbi_array))
|
||||||
|
break;
|
||||||
|
ogs_yaml_iter_recurse(&sbi_array, &sbi_iter);
|
||||||
|
} else if (ogs_yaml_iter_type(&sbi_array) ==
|
||||||
|
YAML_SCALAR_NODE) {
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
|
||||||
|
while (ogs_yaml_iter_next(&sbi_iter)) {
|
||||||
|
const char *sbi_key =
|
||||||
|
ogs_yaml_iter_key(&sbi_iter);
|
||||||
|
ogs_assert(sbi_key);
|
||||||
|
if (!strcmp(sbi_key, "family")) {
|
||||||
|
const char *v = ogs_yaml_iter_value(&sbi_iter);
|
||||||
|
if (v) family = atoi(v);
|
||||||
|
if (family != AF_UNSPEC &&
|
||||||
|
family != AF_INET && family != AF_INET6) {
|
||||||
|
ogs_warn("Ignore family(%d) : "
|
||||||
|
"AF_UNSPEC(%d), "
|
||||||
|
"AF_INET(%d), AF_INET6(%d) ",
|
||||||
|
family, AF_UNSPEC, AF_INET, AF_INET6);
|
||||||
|
family = AF_UNSPEC;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(sbi_key, "addr") ||
|
||||||
|
!strcmp(sbi_key, "name")) {
|
||||||
|
ogs_yaml_iter_t hostname_iter;
|
||||||
|
ogs_yaml_iter_recurse(&sbi_iter,
|
||||||
|
&hostname_iter);
|
||||||
|
ogs_assert(ogs_yaml_iter_type(&hostname_iter) !=
|
||||||
|
YAML_MAPPING_NODE);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (ogs_yaml_iter_type(&hostname_iter) ==
|
||||||
|
YAML_SEQUENCE_NODE) {
|
||||||
|
if (!ogs_yaml_iter_next(&hostname_iter))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_assert(num < OGS_MAX_NUM_OF_HOSTNAME);
|
||||||
|
hostname[num++] =
|
||||||
|
ogs_yaml_iter_value(&hostname_iter);
|
||||||
|
} while (
|
||||||
|
ogs_yaml_iter_type(&hostname_iter) ==
|
||||||
|
YAML_SEQUENCE_NODE);
|
||||||
|
} else if (!strcmp(sbi_key, "port")) {
|
||||||
|
const char *v = ogs_yaml_iter_value(&sbi_iter);
|
||||||
|
if (v) port = atoi(v);
|
||||||
|
} else if (!strcmp(sbi_key, "tls")) {
|
||||||
|
ogs_yaml_iter_t tls_iter;
|
||||||
|
ogs_yaml_iter_recurse(&sbi_iter, &tls_iter);
|
||||||
|
|
||||||
|
while (ogs_yaml_iter_next(&tls_iter)) {
|
||||||
|
const char *tls_key =
|
||||||
|
ogs_yaml_iter_key(&tls_iter);
|
||||||
|
ogs_assert(tls_key);
|
||||||
|
|
||||||
|
if (!strcmp(tls_key, "key")) {
|
||||||
|
key = ogs_yaml_iter_value(&tls_iter);
|
||||||
|
} else if (!strcmp(tls_key, "pem")) {
|
||||||
|
pem = ogs_yaml_iter_value(&tls_iter);
|
||||||
|
} else
|
||||||
|
ogs_warn("unknown key `%s`", tls_key);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(sbi_key, "advertise")) {
|
||||||
|
/* Nothing in client */
|
||||||
|
} else
|
||||||
|
ogs_warn("unknown key `%s`", sbi_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = NULL;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
rv = ogs_addaddrinfo(&addr,
|
||||||
|
family, hostname[i], port, 0);
|
||||||
|
ogs_assert(rv == OGS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_filter_ip_version(&addr,
|
||||||
|
ogs_app()->parameter.no_ipv4,
|
||||||
|
ogs_app()->parameter.no_ipv6,
|
||||||
|
ogs_app()->parameter.prefer_ipv4);
|
||||||
|
|
||||||
|
if (addr == NULL) continue;
|
||||||
|
|
||||||
|
client = ogs_sbi_client_add(addr);
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
ogs_sbi_self()->scp_instance =
|
||||||
|
scp_instance = ogs_sbi_nf_instance_add();
|
||||||
|
ogs_assert(scp_instance);
|
||||||
|
ogs_sbi_nf_instance_set_type(
|
||||||
|
scp_instance, OpenAPI_nf_type_SCP);
|
||||||
|
|
||||||
|
OGS_SBI_SETUP_CLIENT(scp_instance, client);
|
||||||
|
|
||||||
|
if (key) client->tls.key = key;
|
||||||
|
if (pem) client->tls.pem = pem;
|
||||||
|
|
||||||
|
ogs_freeaddrinfo(addr);
|
||||||
|
|
||||||
|
} while (ogs_yaml_iter_type(&sbi_array) ==
|
||||||
|
YAML_SEQUENCE_NODE);
|
||||||
|
} else if (!strcmp(scp_key, "discovery")) {
|
||||||
|
ogs_yaml_iter_t discovery_iter;
|
||||||
|
yaml_node_t *node = yaml_document_get_node(
|
||||||
|
document, scp_iter.pair->value);
|
||||||
|
ogs_assert(node);
|
||||||
|
ogs_assert(node->type == YAML_MAPPING_NODE);
|
||||||
|
ogs_yaml_iter_recurse(&scp_iter, &discovery_iter);
|
||||||
|
while (ogs_yaml_iter_next(&discovery_iter)) {
|
||||||
|
const char *discovery_key =
|
||||||
|
ogs_yaml_iter_key(&discovery_iter);
|
||||||
|
ogs_assert(discovery_key);
|
||||||
|
if (!strcmp(discovery_key, "delegated")) {
|
||||||
|
yaml_node_t *discovery_node =
|
||||||
|
yaml_document_get_node(document,
|
||||||
|
discovery_iter.pair->value);
|
||||||
|
ogs_assert(discovery_node->type ==
|
||||||
|
YAML_SCALAR_NODE);
|
||||||
|
const char* delegated =
|
||||||
|
ogs_yaml_iter_value(&discovery_iter);
|
||||||
|
if (!strcmp(delegated, "auto"))
|
||||||
|
self.discovery_config.delegated =
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_AUTO;
|
||||||
|
else if (!strcmp(delegated, "yes"))
|
||||||
|
self.discovery_config.delegated =
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_YES;
|
||||||
|
else if (!strcmp(delegated, "no"))
|
||||||
|
self.discovery_config.delegated =
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_NO;
|
||||||
|
else
|
||||||
|
ogs_warn("unknown 'delegated' value `%s`",
|
||||||
|
delegated);
|
||||||
|
} else
|
||||||
|
ogs_warn("unknown key `%s`",
|
||||||
|
discovery_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = ogs_sbi_context_validation(local);
|
rv = ogs_sbi_context_validation(local, nrf, scp);
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
|
@ -515,19 +720,6 @@ ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(void)
|
||||||
nf_instance->time.heartbeat_interval =
|
nf_instance->time.heartbeat_interval =
|
||||||
ogs_app()->time.nf_instance.heartbeat_interval;
|
ogs_app()->time.nf_instance.heartbeat_interval;
|
||||||
|
|
||||||
nf_instance->t_registration_interval = ogs_timer_add(
|
|
||||||
ogs_app()->timer_mgr, NULL, nf_instance);
|
|
||||||
ogs_assert(nf_instance->t_registration_interval);
|
|
||||||
nf_instance->t_heartbeat_interval = ogs_timer_add(
|
|
||||||
ogs_app()->timer_mgr, NULL, nf_instance);
|
|
||||||
ogs_assert(nf_instance->t_heartbeat_interval);
|
|
||||||
nf_instance->t_no_heartbeat = ogs_timer_add(
|
|
||||||
ogs_app()->timer_mgr, NULL, nf_instance);
|
|
||||||
ogs_assert(nf_instance->t_no_heartbeat);
|
|
||||||
nf_instance->t_validity = ogs_timer_add(
|
|
||||||
ogs_app()->timer_mgr, NULL, nf_instance);
|
|
||||||
ogs_assert(nf_instance->t_validity);
|
|
||||||
|
|
||||||
nf_instance->priority = OGS_SBI_DEFAULT_PRIORITY;
|
nf_instance->priority = OGS_SBI_DEFAULT_PRIORITY;
|
||||||
nf_instance->capacity = OGS_SBI_DEFAULT_CAPACITY;
|
nf_instance->capacity = OGS_SBI_DEFAULT_CAPACITY;
|
||||||
nf_instance->load = OGS_SBI_DEFAULT_LOAD;
|
nf_instance->load = OGS_SBI_DEFAULT_LOAD;
|
||||||
|
@ -625,11 +817,6 @@ void ogs_sbi_nf_instance_remove(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
ogs_free(nf_instance->id);
|
ogs_free(nf_instance->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_timer_delete(nf_instance->t_registration_interval);
|
|
||||||
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
|
||||||
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
|
||||||
ogs_timer_delete(nf_instance->t_validity);
|
|
||||||
|
|
||||||
if (nf_instance->client)
|
if (nf_instance->client)
|
||||||
ogs_sbi_client_remove(nf_instance->client);
|
ogs_sbi_client_remove(nf_instance->client);
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,20 @@ typedef struct ogs_sbi_client_s ogs_sbi_client_t;
|
||||||
typedef struct ogs_sbi_smf_info_s ogs_sbi_smf_info_t;
|
typedef struct ogs_sbi_smf_info_s ogs_sbi_smf_info_t;
|
||||||
typedef struct ogs_sbi_nf_instance_s ogs_sbi_nf_instance_t;
|
typedef struct ogs_sbi_nf_instance_s ogs_sbi_nf_instance_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_AUTO = 0,
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_YES,
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_NO,
|
||||||
|
} ogs_sbi_discovery_delegated_mode;
|
||||||
|
|
||||||
|
typedef struct ogs_sbi_discovery_config_s {
|
||||||
|
ogs_sbi_discovery_delegated_mode delegated;
|
||||||
|
} ogs_sbi_discovery_config_t;
|
||||||
|
|
||||||
typedef struct ogs_sbi_context_s {
|
typedef struct ogs_sbi_context_s {
|
||||||
uint32_t sbi_port; /* SBI local port */
|
ogs_sbi_discovery_config_t discovery_config; /* SCP Discovery Delegated */
|
||||||
|
|
||||||
|
uint32_t sbi_port; /* SBI local port */
|
||||||
|
|
||||||
ogs_list_t server_list;
|
ogs_list_t server_list;
|
||||||
ogs_list_t client_list;
|
ogs_list_t client_list;
|
||||||
|
@ -47,25 +59,28 @@ typedef struct ogs_sbi_context_s {
|
||||||
ogs_list_t nf_instance_list;
|
ogs_list_t nf_instance_list;
|
||||||
ogs_list_t subscription_list;
|
ogs_list_t subscription_list;
|
||||||
|
|
||||||
ogs_sbi_nf_instance_t *nf_instance; /* SELF NF Instance */
|
ogs_sbi_nf_instance_t *nf_instance; /* SELF NF Instance */
|
||||||
|
ogs_sbi_nf_instance_t *nrf_instance; /* NRF Instance */
|
||||||
|
ogs_sbi_nf_instance_t *scp_instance; /* SCP Instance */
|
||||||
|
|
||||||
const char *content_encoding;
|
const char *content_encoding;
|
||||||
|
|
||||||
} ogs_sbi_context_t;
|
} ogs_sbi_context_t;
|
||||||
|
|
||||||
typedef struct ogs_sbi_nf_instance_s {
|
typedef struct ogs_sbi_nf_instance_s {
|
||||||
ogs_lnode_t lnode;
|
ogs_lnode_t lnode;
|
||||||
|
|
||||||
ogs_fsm_t sm; /* A state machine */
|
ogs_fsm_t sm; /* A state machine */
|
||||||
ogs_timer_t *t_registration_interval; /* timer to retry
|
ogs_timer_t *t_registration_interval; /* timer to retry
|
||||||
to register peer node */
|
to register peer node */
|
||||||
struct {
|
struct {
|
||||||
int heartbeat_interval;
|
int heartbeat_interval;
|
||||||
int validity_duration;
|
int validity_duration;
|
||||||
} time;
|
} time;
|
||||||
|
|
||||||
ogs_timer_t *t_heartbeat_interval; /* heartbeat interval */
|
ogs_timer_t *t_heartbeat_interval; /* heartbeat interval */
|
||||||
ogs_timer_t *t_no_heartbeat; /* check heartbeat */
|
ogs_timer_t *t_no_heartbeat; /* check heartbeat */
|
||||||
ogs_timer_t *t_validity; /* check validation */
|
ogs_timer_t *t_validity; /* check validation */
|
||||||
|
|
||||||
#define NF_INSTANCE_IS_SELF(_iD) \
|
#define NF_INSTANCE_IS_SELF(_iD) \
|
||||||
(_iD) && ogs_sbi_self()->nf_instance && \
|
(_iD) && ogs_sbi_self()->nf_instance && \
|
||||||
|
@ -77,7 +92,7 @@ typedef struct ogs_sbi_nf_instance_s {
|
||||||
#define NF_INSTANCE_IS_NRF(__nFInstance) \
|
#define NF_INSTANCE_IS_NRF(__nFInstance) \
|
||||||
((__nFInstance->nf_type) == OpenAPI_nf_type_NRF)
|
((__nFInstance->nf_type) == OpenAPI_nf_type_NRF)
|
||||||
|
|
||||||
char *id; /* NFInstanceId */
|
char *id; /* NFInstanceId */
|
||||||
|
|
||||||
OpenAPI_nf_type_e nf_type;
|
OpenAPI_nf_type_e nf_type;
|
||||||
OpenAPI_nf_status_e nf_status;
|
OpenAPI_nf_status_e nf_status;
|
||||||
|
@ -103,12 +118,12 @@ typedef struct ogs_sbi_nf_instance_s {
|
||||||
|
|
||||||
ogs_list_t nf_service_list;
|
ogs_list_t nf_service_list;
|
||||||
|
|
||||||
void *client; /* only used in CLIENT */
|
void *client; /* only used in CLIENT */
|
||||||
unsigned int reference_count; /* reference count for memory free */
|
unsigned int reference_count; /* reference count for memory free */
|
||||||
|
|
||||||
ogs_list_t nf_info_list;
|
ogs_list_t nf_info_list;
|
||||||
|
|
||||||
OpenAPI_nf_profile_t *nf_profile; /* stored NF Profile */
|
OpenAPI_nf_profile_t *nf_profile; /* stored NF Profile */
|
||||||
} ogs_sbi_nf_instance_t;
|
} ogs_sbi_nf_instance_t;
|
||||||
|
|
||||||
typedef struct ogs_sbi_nf_type_array_s {
|
typedef struct ogs_sbi_nf_type_array_s {
|
||||||
|
@ -196,19 +211,19 @@ typedef struct ogs_sbi_subscription_s {
|
||||||
int validity_duration;
|
int validity_duration;
|
||||||
} time;
|
} time;
|
||||||
|
|
||||||
ogs_timer_t *t_validity; /* check validation */
|
ogs_timer_t *t_validity; /* check validation */
|
||||||
|
|
||||||
char *id; /* SubscriptionId */
|
char *id; /* SubscriptionId */
|
||||||
char *req_nf_instance_id; /* reqNfInstanceId */
|
char *req_nf_instance_id; /* reqNfInstanceId */
|
||||||
OpenAPI_nf_type_e req_nf_type; /* reqNfType */
|
OpenAPI_nf_type_e req_nf_type; /* reqNfType */
|
||||||
OpenAPI_nf_status_e nf_status;
|
OpenAPI_nf_status_e nf_status;
|
||||||
char *notification_uri;
|
char *notification_uri;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
OpenAPI_nf_type_e nf_type; /* nfType */
|
OpenAPI_nf_type_e nf_type; /* nfType */
|
||||||
} subscr_cond;
|
} subscr_cond;
|
||||||
|
|
||||||
void *client; /* only used in SERVER */
|
void *client; /* only used in SERVER */
|
||||||
} ogs_sbi_subscription_t;
|
} ogs_sbi_subscription_t;
|
||||||
|
|
||||||
typedef struct ogs_sbi_smf_info_s {
|
typedef struct ogs_sbi_smf_info_s {
|
||||||
|
@ -249,7 +264,10 @@ typedef struct ogs_sbi_nf_info_s {
|
||||||
void ogs_sbi_context_init(void);
|
void ogs_sbi_context_init(void);
|
||||||
void ogs_sbi_context_final(void);
|
void ogs_sbi_context_final(void);
|
||||||
ogs_sbi_context_t *ogs_sbi_self(void);
|
ogs_sbi_context_t *ogs_sbi_self(void);
|
||||||
int ogs_sbi_context_parse_config(const char *local, const char *remote);
|
int ogs_sbi_context_parse_config(
|
||||||
|
const char *local, const char *nrf, const char *scp);
|
||||||
|
|
||||||
|
ogs_sbi_nf_instance_t *ogs_sbi_scp_instance(void);
|
||||||
|
|
||||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(void);
|
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(void);
|
||||||
void ogs_sbi_nf_instance_set_id(ogs_sbi_nf_instance_t *nf_instance, char *id);
|
void ogs_sbi_nf_instance_set_id(ogs_sbi_nf_instance_t *nf_instance, char *id);
|
||||||
|
|
|
@ -29,7 +29,6 @@ char *ogs_uridup(bool https, ogs_sockaddr_t *addr, ogs_sbi_header_t *h)
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
|
|
||||||
ogs_assert(addr);
|
ogs_assert(addr);
|
||||||
ogs_assert(h);
|
|
||||||
|
|
||||||
p = uri;
|
p = uri;
|
||||||
last = uri + OGS_HUGE_LEN;
|
last = uri + OGS_HUGE_LEN;
|
||||||
|
@ -61,16 +60,18 @@ char *ogs_uridup(bool https, ogs_sockaddr_t *addr, ogs_sbi_header_t *h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
ogs_assert(h->service.name);
|
if (h) {
|
||||||
p = ogs_slprintf(p, last, "/%s", h->service.name);
|
ogs_assert(h->service.name);
|
||||||
ogs_assert(h->api.version);
|
p = ogs_slprintf(p, last, "/%s", h->service.name);
|
||||||
p = ogs_slprintf(p, last, "/%s", h->api.version);
|
ogs_assert(h->api.version);
|
||||||
|
p = ogs_slprintf(p, last, "/%s", h->api.version);
|
||||||
|
|
||||||
/* Resource */
|
/* Resource */
|
||||||
ogs_assert(h->resource.component[0]);
|
ogs_assert(h->resource.component[0]);
|
||||||
for (i = 0; i < OGS_SBI_MAX_NUM_OF_RESOURCE_COMPONENT &&
|
for (i = 0; i < OGS_SBI_MAX_NUM_OF_RESOURCE_COMPONENT &&
|
||||||
h->resource.component[i]; i++)
|
h->resource.component[i]; i++)
|
||||||
p = ogs_slprintf(p, last, "/%s", h->resource.component[i]);
|
p = ogs_slprintf(p, last, "/%s", h->resource.component[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return ogs_strdup(uri);
|
return ogs_strdup(uri);
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,6 @@ char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h)
|
||||||
bool https = false;
|
bool https = false;
|
||||||
|
|
||||||
ogs_assert(server);
|
ogs_assert(server);
|
||||||
ogs_assert(h);
|
|
||||||
|
|
||||||
if (server->tls.key && server->tls.pem)
|
if (server->tls.key && server->tls.pem)
|
||||||
https = true;
|
https = true;
|
||||||
|
@ -100,7 +100,6 @@ char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h)
|
||||||
bool https = false;
|
bool https = false;
|
||||||
|
|
||||||
ogs_assert(client);
|
ogs_assert(client);
|
||||||
ogs_assert(h);
|
|
||||||
|
|
||||||
if (client->tls.key && client->tls.pem)
|
if (client->tls.key && client->tls.pem)
|
||||||
https = true;
|
https = true;
|
||||||
|
@ -108,6 +107,11 @@ char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h)
|
||||||
return ogs_uridup(https, client->node.addr, h);
|
return ogs_uridup(https, client->node.addr, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ogs_sbi_client_apiroot(ogs_sbi_client_t *client)
|
||||||
|
{
|
||||||
|
return ogs_sbi_client_uri(client, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a url-decoded version of str
|
* Returns a url-decoded version of str
|
||||||
* IMPORTANT: be sure to free() the returned string after use
|
* IMPORTANT: be sure to free() the returned string after use
|
||||||
|
@ -207,6 +211,57 @@ ogs_sockaddr_t *ogs_sbi_getaddr_from_uri(char *uri)
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ogs_sbi_getpath_from_uri(char *uri)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
struct yuarel yuarel;
|
||||||
|
char *p = NULL;
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
p = ogs_strdup(uri);
|
||||||
|
|
||||||
|
rv = yuarel_parse(&yuarel, p);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_free(p);
|
||||||
|
ogs_error("yuarel_parse() failed [%s]", uri);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yuarel.scheme) {
|
||||||
|
ogs_error("No http.scheme found [%s]", uri);
|
||||||
|
ogs_free(p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(yuarel.scheme, "https") == 0) {
|
||||||
|
|
||||||
|
} else if (strcmp(yuarel.scheme, "http") == 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ogs_error("Invalid http.scheme [%s:%s]", yuarel.scheme, uri);
|
||||||
|
ogs_free(p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yuarel.host) {
|
||||||
|
ogs_error("No http.host found [%s]", uri);
|
||||||
|
ogs_free(p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yuarel.path) {
|
||||||
|
ogs_error("No http.path found [%s]", uri);
|
||||||
|
ogs_free(p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = ogs_strdup(yuarel.path);
|
||||||
|
ogs_assert(path);
|
||||||
|
|
||||||
|
ogs_free(p);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
char *ogs_sbi_bitrate_to_string(uint64_t bitrate, int unit)
|
char *ogs_sbi_bitrate_to_string(uint64_t bitrate, int unit)
|
||||||
{
|
{
|
||||||
if (unit == OGS_SBI_BITRATE_KBPS) {
|
if (unit == OGS_SBI_BITRATE_KBPS) {
|
||||||
|
|
|
@ -34,10 +34,13 @@ typedef struct ogs_sbi_header_s ogs_sbi_header_t;
|
||||||
|
|
||||||
char *ogs_uridup(bool https, ogs_sockaddr_t *addr, ogs_sbi_header_t *h);
|
char *ogs_uridup(bool https, ogs_sockaddr_t *addr, ogs_sbi_header_t *h);
|
||||||
char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h);
|
char *ogs_sbi_server_uri(ogs_sbi_server_t *server, ogs_sbi_header_t *h);
|
||||||
|
char *ogs_sbi_client_apiroot(ogs_sbi_client_t *client);
|
||||||
char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h);
|
char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h);
|
||||||
|
|
||||||
char *ogs_sbi_parse_uri(char *uri, const char *delim, char **saveptr);
|
char *ogs_sbi_parse_uri(char *uri, const char *delim, char **saveptr);
|
||||||
|
|
||||||
ogs_sockaddr_t *ogs_sbi_getaddr_from_uri(char *uri);
|
ogs_sockaddr_t *ogs_sbi_getaddr_from_uri(char *uri);
|
||||||
|
char *ogs_sbi_getpath_from_uri(char *uri);
|
||||||
|
|
||||||
#define OGS_SBI_BITRATE_BPS 0
|
#define OGS_SBI_BITRATE_BPS 0
|
||||||
#define OGS_SBI_BITRATE_KBPS 1
|
#define OGS_SBI_BITRATE_KBPS 1
|
||||||
|
|
|
@ -252,7 +252,6 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
||||||
ogs_expect_or_return_val(message->h.method, NULL);
|
ogs_expect_or_return_val(message->h.method, NULL);
|
||||||
request->h.method = ogs_strdup(message->h.method);
|
request->h.method = ogs_strdup(message->h.method);
|
||||||
if (message->h.uri) {
|
if (message->h.uri) {
|
||||||
ogs_expect_or_return_val(message->h.uri, NULL);
|
|
||||||
request->h.uri = ogs_strdup(message->h.uri);
|
request->h.uri = ogs_strdup(message->h.uri);
|
||||||
ogs_expect_or_return_val(request->h.uri, NULL);
|
ogs_expect_or_return_val(request->h.uri, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -547,6 +546,11 @@ int ogs_sbi_parse_request(
|
||||||
|
|
||||||
for (hi = ogs_hash_first(request->http.headers);
|
for (hi = ogs_hash_first(request->http.headers);
|
||||||
hi; hi = ogs_hash_next(hi)) {
|
hi; hi = ogs_hash_next(hi)) {
|
||||||
|
/*
|
||||||
|
* <RFC 2616>
|
||||||
|
* Each header field consists of a name followed by a colon (":")
|
||||||
|
* and the field value. Field names are case-insensitive.
|
||||||
|
*/
|
||||||
if (!ogs_strcasecmp(ogs_hash_this_key(hi), OGS_SBI_ACCEPT_ENCODING)) {
|
if (!ogs_strcasecmp(ogs_hash_this_key(hi), OGS_SBI_ACCEPT_ENCODING)) {
|
||||||
message->http.content_encoding = ogs_hash_this_val(hi);
|
message->http.content_encoding = ogs_hash_this_val(hi);
|
||||||
} else if (!ogs_strcasecmp(
|
} else if (!ogs_strcasecmp(
|
||||||
|
@ -620,7 +624,7 @@ int ogs_sbi_parse_header(ogs_sbi_message_t *message, ogs_sbi_header_t *header)
|
||||||
{
|
{
|
||||||
struct yuarel yuarel;
|
struct yuarel yuarel;
|
||||||
char *saveptr = NULL;
|
char *saveptr = NULL;
|
||||||
char *uri = NULL, *p = NULL;;
|
char *uri = NULL, *p = NULL;
|
||||||
|
|
||||||
char *component = NULL;
|
char *component = NULL;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -691,6 +695,21 @@ void ogs_sbi_header_free(ogs_sbi_header_t *h)
|
||||||
ogs_free(h->resource.component[i]);
|
ogs_free(h->resource.component[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ogs_sbi_http_hash_free(ogs_hash_t *hash)
|
||||||
|
{
|
||||||
|
ogs_hash_index_t *hi;
|
||||||
|
|
||||||
|
ogs_assert(hash);
|
||||||
|
|
||||||
|
for (hi = ogs_hash_first(hash); hi; hi = ogs_hash_next(hi)) {
|
||||||
|
char *key = (char *)ogs_hash_this_key(hi);
|
||||||
|
char *val = ogs_hash_this_val(hi);
|
||||||
|
ogs_hash_set(hash, key, strlen(key), NULL);
|
||||||
|
ogs_free(key);
|
||||||
|
ogs_free(val);
|
||||||
|
}
|
||||||
|
ogs_hash_destroy(hash);
|
||||||
|
}
|
||||||
|
|
||||||
static char *build_json(ogs_sbi_message_t *message)
|
static char *build_json(ogs_sbi_message_t *message)
|
||||||
{
|
{
|
||||||
|
@ -2152,29 +2171,12 @@ static void http_message_free(ogs_sbi_http_message_t *http)
|
||||||
int i;
|
int i;
|
||||||
ogs_assert(http);
|
ogs_assert(http);
|
||||||
|
|
||||||
if (http->params) {
|
if (http->params)
|
||||||
ogs_hash_index_t *hi;
|
ogs_sbi_http_hash_free(http->params);
|
||||||
for (hi = ogs_hash_first(http->params); hi; hi = ogs_hash_next(hi)) {
|
|
||||||
char *key = (char *)ogs_hash_this_key(hi);
|
if (http->headers)
|
||||||
char *val = ogs_hash_this_val(hi);
|
ogs_sbi_http_hash_free(http->headers);
|
||||||
ogs_hash_set(http->params, key, strlen(key), NULL);
|
|
||||||
ogs_free(key);
|
|
||||||
ogs_free(val);
|
|
||||||
}
|
|
||||||
ogs_hash_destroy(http->params);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (http->headers) {
|
|
||||||
ogs_hash_index_t *hi;
|
|
||||||
for (hi = ogs_hash_first(http->headers); hi; hi = ogs_hash_next(hi)) {
|
|
||||||
char *key = (char *)ogs_hash_this_key(hi);
|
|
||||||
char *val = ogs_hash_this_val(hi);
|
|
||||||
ogs_hash_set(http->headers, key, strlen(key), NULL);
|
|
||||||
ogs_free(key);
|
|
||||||
ogs_free(val);
|
|
||||||
}
|
|
||||||
ogs_hash_destroy(http->headers);
|
|
||||||
}
|
|
||||||
if (http->content)
|
if (http->content)
|
||||||
ogs_free(http->content);
|
ogs_free(http->content);
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,21 @@ extern "C" {
|
||||||
#define OGS_SBI_APPLICATION_5GNAS_TYPE "vnd.3gpp.5gnas"
|
#define OGS_SBI_APPLICATION_5GNAS_TYPE "vnd.3gpp.5gnas"
|
||||||
#define OGS_SBI_APPLICATION_NGAP_TYPE "vnd.3gpp.ngap"
|
#define OGS_SBI_APPLICATION_NGAP_TYPE "vnd.3gpp.ngap"
|
||||||
|
|
||||||
|
#define OGS_SBI_CUSTOM_3GPP_COMMON "3gpp-Sbi-"
|
||||||
|
#define OGS_SBI_CUSTOM_MESSAGE_PRIORITY "3gpp-Sbi-Message-Priority"
|
||||||
|
#define OGS_SBI_CUSTOM_CALLBACK "3gpp-Sbi-Callback"
|
||||||
|
#define OGS_SBI_CUSTOM_TARGET_APIROOT "3gpp-Sbi-Target-apiRoot"
|
||||||
|
#define OGS_SBI_CUSTOM_ROUTING_BINDING "3gpp-Sbi-Routing-Binding"
|
||||||
|
#define OGS_SBI_CUSTOM_BINDING "3gpp-Sbi-Binding"
|
||||||
|
#define OGS_SBI_CUSTOM_DISCOVERY_COMMON "3gpp-Sbi-Discovery-"
|
||||||
|
#define OGS_SBI_CUSTOM_PRODUCER_ID "3gpp-Sbi-Producer-Id"
|
||||||
|
#define OGS_SBI_CUSTOM_OCI "3gpp-Sbi-Oci"
|
||||||
|
#define OGS_SBI_CUSTOM_CLIENT_CREDENTIALS "3gpp-Sbi-Client-Credentials"
|
||||||
|
#define OGS_SBI_CUSTOM_NRF_URI "3gpp-Sbi-Nrf-Uri"
|
||||||
|
#define OGS_SBI_CUSTOM_TARGET_NF_ID "3gpp-Sbi-Target-Nf-Id"
|
||||||
|
#define OGS_SBI_CUSTOM_ACCESS_SCOPE "3gpp-Sbi-Access-Scope"
|
||||||
|
#define OGS_SBI_CUSTOM_ACCESS_TOKEN "3gpp-Sbi-Access-Token"
|
||||||
|
|
||||||
#define OGS_SBI_CONTENT_JSON_TYPE \
|
#define OGS_SBI_CONTENT_JSON_TYPE \
|
||||||
OGS_SBI_APPLICATION_TYPE "/" OGS_SBI_APPLICATION_JSON_TYPE
|
OGS_SBI_APPLICATION_TYPE "/" OGS_SBI_APPLICATION_JSON_TYPE
|
||||||
#define OGS_SBI_CONTENT_PROBLEM_TYPE \
|
#define OGS_SBI_CONTENT_PROBLEM_TYPE \
|
||||||
|
@ -477,6 +492,8 @@ ogs_pkbuf_t *ogs_sbi_find_part_by_content_id(
|
||||||
int ogs_sbi_parse_header(ogs_sbi_message_t *message, ogs_sbi_header_t *header);
|
int ogs_sbi_parse_header(ogs_sbi_message_t *message, ogs_sbi_header_t *header);
|
||||||
void ogs_sbi_header_free(ogs_sbi_header_t *h);
|
void ogs_sbi_header_free(ogs_sbi_header_t *h);
|
||||||
|
|
||||||
|
void ogs_sbi_http_hash_free(ogs_hash_t *hash);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,8 @@ static int server_start(ogs_sbi_server_t *server,
|
||||||
int (*cb)(ogs_sbi_request_t *request, void *data));
|
int (*cb)(ogs_sbi_request_t *request, void *data));
|
||||||
static void server_stop(ogs_sbi_server_t *server);
|
static void server_stop(ogs_sbi_server_t *server);
|
||||||
|
|
||||||
|
static bool server_send_rspmem_persistent(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
static bool server_send_response(
|
static bool server_send_response(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
|
|
||||||
|
@ -47,7 +49,9 @@ const ogs_sbi_server_actions_t ogs_mhd_server_actions = {
|
||||||
server_start,
|
server_start,
|
||||||
server_stop,
|
server_stop,
|
||||||
|
|
||||||
|
server_send_rspmem_persistent,
|
||||||
server_send_response,
|
server_send_response,
|
||||||
|
|
||||||
server_from_stream,
|
server_from_stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -296,7 +300,7 @@ static void free_callback(void *cls)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool server_send_response(
|
static bool server_send_rspmem_persistent(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -312,10 +316,14 @@ static bool server_send_response(
|
||||||
ogs_sbi_request_t *request = NULL;
|
ogs_sbi_request_t *request = NULL;
|
||||||
ogs_sbi_session_t *sbi_sess = NULL;
|
ogs_sbi_session_t *sbi_sess = NULL;
|
||||||
|
|
||||||
sbi_sess = (ogs_sbi_session_t *)stream;
|
|
||||||
ogs_assert(sbi_sess);
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
|
sbi_sess = ogs_pool_cycle(&session_pool, (ogs_sbi_session_t *)stream);
|
||||||
|
if (!sbi_sess) {
|
||||||
|
ogs_error("session has already been removed");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
connection = sbi_sess->connection;
|
connection = sbi_sess->connection;
|
||||||
ogs_assert(connection);
|
ogs_assert(connection);
|
||||||
|
|
||||||
|
@ -370,7 +378,6 @@ static bool server_send_response(
|
||||||
request = sbi_sess->request;
|
request = sbi_sess->request;
|
||||||
ogs_assert(request);
|
ogs_assert(request);
|
||||||
|
|
||||||
ogs_sbi_response_free(response);
|
|
||||||
session_remove(sbi_sess);
|
session_remove(sbi_sess);
|
||||||
|
|
||||||
request->poll.write = ogs_pollset_add(ogs_app()->pollset,
|
request->poll.write = ogs_pollset_add(ogs_app()->pollset,
|
||||||
|
@ -387,6 +394,20 @@ static bool server_send_response(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool server_send_response(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
||||||
|
{
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
ogs_assert(response);
|
||||||
|
|
||||||
|
rc = server_send_rspmem_persistent(stream, response);
|
||||||
|
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static void run(short when, ogs_socket_t fd, void *data)
|
static void run(short when, ogs_socket_t fd, void *data)
|
||||||
{
|
{
|
||||||
struct MHD_Daemon *mhd_daemon = data;
|
struct MHD_Daemon *mhd_daemon = data;
|
||||||
|
@ -539,19 +560,15 @@ suspend:
|
||||||
sbi_sess = session_add(server, request, connection);
|
sbi_sess = session_add(server, request, connection);
|
||||||
ogs_assert(sbi_sess);
|
ogs_assert(sbi_sess);
|
||||||
|
|
||||||
if (server->cb) {
|
ogs_assert(server->cb);
|
||||||
if (server->cb(request, sbi_sess) != OGS_OK) {
|
if (server->cb(request, sbi_sess) != OGS_OK) {
|
||||||
ogs_warn("server callback error");
|
ogs_error("server callback error");
|
||||||
ogs_assert(true ==
|
ogs_assert(true ==
|
||||||
ogs_sbi_server_send_error((ogs_sbi_stream_t *)sbi_sess,
|
ogs_sbi_server_send_error((ogs_sbi_stream_t *)sbi_sess,
|
||||||
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL,
|
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL,
|
||||||
"server callback error", NULL));
|
"server callback error", NULL));
|
||||||
|
|
||||||
return MHD_YES;
|
return MHD_YES;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ogs_fatal("server callback is not registered");
|
|
||||||
ogs_assert_if_reached();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MHD_YES;
|
return MHD_YES;
|
||||||
|
|
|
@ -33,6 +33,8 @@ static int server_start(ogs_sbi_server_t *server,
|
||||||
int (*cb)(ogs_sbi_request_t *request, void *data));
|
int (*cb)(ogs_sbi_request_t *request, void *data));
|
||||||
static void server_stop(ogs_sbi_server_t *server);
|
static void server_stop(ogs_sbi_server_t *server);
|
||||||
|
|
||||||
|
static bool server_send_rspmem_persistent(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
static bool server_send_response(
|
static bool server_send_response(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
|
|
||||||
|
@ -45,7 +47,9 @@ const ogs_sbi_server_actions_t ogs_nghttp2_server_actions = {
|
||||||
server_start,
|
server_start,
|
||||||
server_stop,
|
server_stop,
|
||||||
|
|
||||||
|
server_send_rspmem_persistent,
|
||||||
server_send_response,
|
server_send_response,
|
||||||
|
|
||||||
server_from_stream,
|
server_from_stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -284,7 +288,7 @@ static ssize_t response_read_callback(nghttp2_session *session,
|
||||||
return response->http.content_length;
|
return response->http.content_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool server_send_response(
|
static bool server_send_rspmem_persistent(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
||||||
{
|
{
|
||||||
ogs_sbi_session_t *sbi_sess = NULL;
|
ogs_sbi_session_t *sbi_sess = NULL;
|
||||||
|
@ -299,11 +303,17 @@ static bool server_send_response(
|
||||||
char srv_version[128];
|
char srv_version[128];
|
||||||
char clen[128];
|
char clen[128];
|
||||||
|
|
||||||
ogs_assert(stream);
|
ogs_assert(response);
|
||||||
|
|
||||||
|
stream = ogs_pool_cycle(&stream_pool, stream);
|
||||||
|
if (!stream) {
|
||||||
|
ogs_error("stream has already been closed");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
sbi_sess = stream->session;
|
sbi_sess = stream->session;
|
||||||
ogs_assert(sbi_sess);
|
ogs_assert(sbi_sess);
|
||||||
ogs_assert(sbi_sess->session);
|
ogs_assert(sbi_sess->session);
|
||||||
ogs_assert(response);
|
|
||||||
|
|
||||||
sock = sbi_sess->sock;
|
sock = sbi_sess->sock;
|
||||||
ogs_assert(sock);
|
ogs_assert(sock);
|
||||||
|
@ -375,12 +385,25 @@ static bool server_send_response(
|
||||||
session_remove(sbi_sess);
|
session_remove(sbi_sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_sbi_response_free(response);
|
|
||||||
ogs_free(nva);
|
ogs_free(nva);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool server_send_response(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
||||||
|
{
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
ogs_assert(response);
|
||||||
|
|
||||||
|
rc = server_send_rspmem_persistent(stream, response);
|
||||||
|
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static ogs_sbi_server_t *server_from_stream(ogs_sbi_stream_t *stream)
|
static ogs_sbi_server_t *server_from_stream(ogs_sbi_stream_t *stream)
|
||||||
{
|
{
|
||||||
ogs_sbi_session_t *sbi_sess = NULL;
|
ogs_sbi_session_t *sbi_sess = NULL;
|
||||||
|
|
|
@ -68,13 +68,12 @@ bool ogs_sbi_send(ogs_sbi_nf_instance_t *nf_instance,
|
||||||
ogs_freeaddrinfo(addr);
|
ogs_freeaddrinfo(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ogs_sbi_xact_remove() will call ogs_sbi_request_free()
|
||||||
|
* As such, we'll use ogs_sbi_client_send_reqmem_persistent() */
|
||||||
ogs_expect_or_return_val(true ==
|
ogs_expect_or_return_val(true ==
|
||||||
ogs_sbi_client_send_request(
|
ogs_sbi_scp_send_reqmem_persistent(
|
||||||
client, client_cb, request, xact), false);
|
client, client_cb, request, xact), false);
|
||||||
|
|
||||||
/* Prevent ogs_sbi_request_free() in ogs_sbi_xact_remove() */
|
|
||||||
xact->request = NULL;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +124,23 @@ bool ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ogs_nnrf_nfm_send_nf_register(
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_request_t *(*build)(void))
|
||||||
|
{
|
||||||
|
ogs_sbi_request_t *request = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
ogs_assert(build);
|
||||||
|
|
||||||
|
request = (*build)();
|
||||||
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
|
return ogs_sbi_scp_send_request(client, client->cb, request, nf_instance);
|
||||||
|
}
|
||||||
|
|
||||||
bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance)
|
bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
{
|
{
|
||||||
ogs_sbi_request_t *request = NULL;
|
ogs_sbi_request_t *request = NULL;
|
||||||
|
@ -137,8 +153,7 @@ bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
request = ogs_nnrf_nfm_build_update();
|
request = ogs_nnrf_nfm_build_update();
|
||||||
ogs_expect_or_return_val(request, false);
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
return ogs_sbi_scp_send_request(client, client->cb, request, nf_instance);
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance)
|
bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
|
@ -153,8 +168,7 @@ bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
request = ogs_nnrf_nfm_build_de_register();
|
request = ogs_nnrf_nfm_build_de_register();
|
||||||
ogs_expect_or_return_val(request, false);
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
return ogs_sbi_scp_send_request(client, client->cb, request, nf_instance);
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client,
|
bool ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client,
|
||||||
|
@ -180,7 +194,7 @@ bool ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client,
|
||||||
request = ogs_nnrf_nfm_build_status_subscribe(subscription);
|
request = ogs_nnrf_nfm_build_status_subscribe(subscription);
|
||||||
ogs_expect_or_return_val(request, false);
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
return ogs_sbi_scp_send_request(
|
||||||
client, client->cb, request, subscription);
|
client, client->cb, request, subscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,13 +205,14 @@ bool ogs_nnrf_nfm_send_nf_status_unsubscribe(
|
||||||
ogs_sbi_client_t *client = NULL;
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
ogs_assert(subscription);
|
ogs_assert(subscription);
|
||||||
client = subscription->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
request = ogs_nnrf_nfm_build_status_unsubscribe(subscription);
|
request = ogs_nnrf_nfm_build_status_unsubscribe(subscription);
|
||||||
ogs_expect_or_return_val(request, false);
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
client = subscription->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
return ogs_sbi_scp_send_request(
|
||||||
client, client->cb, request, subscription);
|
client, client->cb, request, subscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,15 +223,15 @@ bool ogs_nnrf_disc_send_nf_discover(ogs_sbi_nf_instance_t *nf_instance,
|
||||||
ogs_sbi_request_t *request = NULL;
|
ogs_sbi_request_t *request = NULL;
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
ogs_assert(nf_instance->nf_type);
|
|
||||||
client = nf_instance->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
ogs_assert(ogs_sbi_self()->nf_instance);
|
ogs_assert(ogs_sbi_self()->nf_instance);
|
||||||
request = ogs_nnrf_disc_build_discover(
|
request = ogs_nnrf_disc_build_discover(
|
||||||
target_nf_type, ogs_sbi_self()->nf_instance->nf_type);
|
target_nf_type, ogs_sbi_self()->nf_instance->nf_type);
|
||||||
ogs_expect_or_return_val(request, false);
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(client, client->cb, request, data);
|
return ogs_sbi_client_send_request(client, client->cb, request, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ bool ogs_sbi_send(ogs_sbi_nf_instance_t *nf_instance,
|
||||||
bool ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact,
|
bool ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact,
|
||||||
ogs_fsm_handler_t nf_state_registered, ogs_sbi_client_cb_f client_cb);
|
ogs_fsm_handler_t nf_state_registered, ogs_sbi_client_cb_f client_cb);
|
||||||
|
|
||||||
|
bool ogs_nnrf_nfm_send_nf_register(
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_request_t *(*build)(void));
|
||||||
bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance);
|
bool ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance);
|
||||||
bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance);
|
bool ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance);
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,12 @@ void ogs_sbi_server_stop_all(void)
|
||||||
ogs_sbi_server_actions.stop(server);
|
ogs_sbi_server_actions.stop(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ogs_sbi_server_send_rspmem_persistent(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
||||||
|
{
|
||||||
|
return ogs_sbi_server_actions.send_rspmem_persistent(stream, response);
|
||||||
|
}
|
||||||
|
|
||||||
bool ogs_sbi_server_send_response(
|
bool ogs_sbi_server_send_response(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,8 @@ typedef struct ogs_sbi_server_actions_s {
|
||||||
int (*cb)(ogs_sbi_request_t *request, void *data));
|
int (*cb)(ogs_sbi_request_t *request, void *data));
|
||||||
void (*stop)(ogs_sbi_server_t *server);
|
void (*stop)(ogs_sbi_server_t *server);
|
||||||
|
|
||||||
|
bool (*send_rspmem_persistent)(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
bool (*send_response)(
|
bool (*send_response)(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
|
|
||||||
|
@ -74,6 +76,8 @@ int ogs_sbi_server_start_all(
|
||||||
int (*cb)(ogs_sbi_request_t *request, void *data));
|
int (*cb)(ogs_sbi_request_t *request, void *data));
|
||||||
void ogs_sbi_server_stop_all(void);
|
void ogs_sbi_server_stop_all(void);
|
||||||
|
|
||||||
|
bool ogs_sbi_server_send_rspmem_persistent(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
bool ogs_sbi_server_send_response(
|
bool ogs_sbi_server_send_response(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
ogs_sbi_stream_t *stream, ogs_sbi_response_t *response);
|
||||||
bool ogs_sbi_server_send_error(ogs_sbi_stream_t *stream,
|
bool ogs_sbi_server_send_error(ogs_sbi_stream_t *stream,
|
||||||
|
|
|
@ -31,6 +31,7 @@ if [ "$SYSTEM" = "Linux" ]; then
|
||||||
ip addr del fd69:f21d:873c:fa::18 dev lo 2> /dev/null
|
ip addr del fd69:f21d:873c:fa::18 dev lo 2> /dev/null
|
||||||
ip addr del fd69:f21d:873c:fa::19 dev lo 2> /dev/null
|
ip addr del fd69:f21d:873c:fa::19 dev lo 2> /dev/null
|
||||||
ip addr del fd69:f21d:873c:fa::20 dev lo 2> /dev/null
|
ip addr del fd69:f21d:873c:fa::20 dev lo 2> /dev/null
|
||||||
|
ip addr del fd69:f21d:873c:fb::10 dev lo 2> /dev/null
|
||||||
ip addr add fd69:f21d:873c:fa::1 dev lo
|
ip addr add fd69:f21d:873c:fa::1 dev lo
|
||||||
ip addr add fd69:f21d:873c:fa::2 dev lo
|
ip addr add fd69:f21d:873c:fa::2 dev lo
|
||||||
ip addr add fd69:f21d:873c:fa::3 dev lo
|
ip addr add fd69:f21d:873c:fa::3 dev lo
|
||||||
|
@ -51,11 +52,8 @@ if [ "$SYSTEM" = "Linux" ]; then
|
||||||
ip addr add fd69:f21d:873c:fa::18 dev lo
|
ip addr add fd69:f21d:873c:fa::18 dev lo
|
||||||
ip addr add fd69:f21d:873c:fa::19 dev lo
|
ip addr add fd69:f21d:873c:fa::19 dev lo
|
||||||
ip addr add fd69:f21d:873c:fa::20 dev lo
|
ip addr add fd69:f21d:873c:fa::20 dev lo
|
||||||
|
ip addr add fd69:f21d:873c:fb::10 dev lo
|
||||||
else
|
else
|
||||||
ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
|
|
||||||
ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
|
|
||||||
ifconfig lo0 alias 127.0.0.4 netmask 255.255.255.255
|
|
||||||
ifconfig lo0 alias 127.0.0.5 netmask 255.255.255.255
|
|
||||||
sysctl -w net.inet.ip.forwarding=1
|
sysctl -w net.inet.ip.forwarding=1
|
||||||
sysctl -w net.inet6.ip6.forwarding=1
|
sysctl -w net.inet6.ip6.forwarding=1
|
||||||
ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
|
||||||
|
@ -77,6 +75,7 @@ else
|
||||||
ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||||
ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||||
ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||||
|
ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||||
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::1 prefixlen 128 2> /dev/null
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::1 prefixlen 128 2> /dev/null
|
||||||
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::2 prefixlen 128 2> /dev/null
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::2 prefixlen 128 2> /dev/null
|
||||||
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::3 prefixlen 128 2> /dev/null
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::3 prefixlen 128 2> /dev/null
|
||||||
|
@ -97,6 +96,7 @@ else
|
||||||
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::18 prefixlen 128 2> /dev/null
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::18 prefixlen 128 2> /dev/null
|
||||||
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::19 prefixlen 128 2> /dev/null
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::19 prefixlen 128 2> /dev/null
|
||||||
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::20 prefixlen 128 2> /dev/null
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fa::20 prefixlen 128 2> /dev/null
|
||||||
|
ifconfig lo0 inet6 delete fd69:f21d:873c:fb::10 prefixlen 128 2> /dev/null
|
||||||
ifconfig lo0 inet6 add fd69:f21d:873c:fa::1 prefixlen 128
|
ifconfig lo0 inet6 add fd69:f21d:873c:fa::1 prefixlen 128
|
||||||
ifconfig lo0 inet6 add fd69:f21d:873c:fa::2 prefixlen 128
|
ifconfig lo0 inet6 add fd69:f21d:873c:fa::2 prefixlen 128
|
||||||
ifconfig lo0 inet6 add fd69:f21d:873c:fa::3 prefixlen 128
|
ifconfig lo0 inet6 add fd69:f21d:873c:fa::3 prefixlen 128
|
||||||
|
@ -117,6 +117,7 @@ else
|
||||||
ifconfig lo0 inet6 add fd69:f21d:873c:fa::18 prefixlen 128
|
ifconfig lo0 inet6 add fd69:f21d:873c:fa::18 prefixlen 128
|
||||||
ifconfig lo0 inet6 add fd69:f21d:873c:fa::19 prefixlen 128
|
ifconfig lo0 inet6 add fd69:f21d:873c:fa::19 prefixlen 128
|
||||||
ifconfig lo0 inet6 add fd69:f21d:873c:fa::20 prefixlen 128
|
ifconfig lo0 inet6 add fd69:f21d:873c:fa::20 prefixlen 128
|
||||||
|
ifconfig lo0 inet6 add fd69:f21d:873c:fb::10 prefixlen 128
|
||||||
if [ "$SYSTEM" = "Darwin" ]; then
|
if [ "$SYSTEM" = "Darwin" ]; then
|
||||||
if ! test -f /etc/pf.anchors/org.open5gs; then
|
if ! test -f /etc/pf.anchors/org.open5gs; then
|
||||||
sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
||||||
|
|
|
@ -37,6 +37,7 @@ else
|
||||||
ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||||
ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||||
ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||||
|
ifconfig lo0 alias 127.0.1.10 netmask 255.255.255.255
|
||||||
if [ "$SYSTEM" = "Darwin" ]; then
|
if [ "$SYSTEM" = "Darwin" ]; then
|
||||||
if ! test -f /etc/pf.anchors/org.open5gs; then
|
if ! test -f /etc/pf.anchors/org.open5gs; then
|
||||||
sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
||||||
|
|
|
@ -119,7 +119,7 @@ void amf_sctp_event_push(amf_event_e id,
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_free(e->ngap.addr);
|
ogs_free(e->ngap.addr);
|
||||||
if (e->pkbuf)
|
if (e->pkbuf)
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
|
|
|
@ -35,7 +35,7 @@ int amf_initialize()
|
||||||
amf_context_init();
|
amf_context_init();
|
||||||
amf_event_init();
|
amf_event_init();
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("amf", "nrf");
|
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();
|
||||||
|
|
|
@ -61,16 +61,18 @@ void amf_nf_state_initial(ogs_fsm_t *s, amf_event_t *e)
|
||||||
nf_instance = e->sbi.data;
|
nf_instance = e->sbi.data;
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
amf_timer_nf_instance_registration_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_registration_interval);
|
ogs_assert(nf_instance->t_registration_interval);
|
||||||
nf_instance->t_registration_interval->cb =
|
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
amf_timer_nf_instance_registration_interval;
|
amf_timer_nf_instance_heartbeat_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_heartbeat_interval);
|
ogs_assert(nf_instance->t_heartbeat_interval);
|
||||||
nf_instance->t_heartbeat_interval->cb =
|
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
amf_timer_nf_instance_heartbeat_interval;
|
amf_timer_nf_instance_no_heartbeat, nf_instance);
|
||||||
ogs_assert(nf_instance->t_no_heartbeat);
|
ogs_assert(nf_instance->t_no_heartbeat);
|
||||||
nf_instance->t_no_heartbeat->cb = amf_timer_nf_instance_no_heartbeat;
|
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
amf_timer_nf_instance_validity, nf_instance);
|
||||||
ogs_assert(nf_instance->t_validity);
|
ogs_assert(nf_instance->t_validity);
|
||||||
nf_instance->t_validity->cb = amf_timer_nf_instance_validity;
|
|
||||||
|
|
||||||
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
OGS_FSM_TRAN(s, &amf_nf_state_will_register);
|
OGS_FSM_TRAN(s, &amf_nf_state_will_register);
|
||||||
|
@ -82,10 +84,20 @@ void amf_nf_state_initial(ogs_fsm_t *s, amf_event_t *e)
|
||||||
|
|
||||||
void amf_nf_state_final(ogs_fsm_t *s, amf_event_t *e)
|
void amf_nf_state_final(ogs_fsm_t *s, amf_event_t *e)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
ogs_assert(s);
|
ogs_assert(s);
|
||||||
ogs_assert(e);
|
ogs_assert(e);
|
||||||
|
|
||||||
amf_sm_debug(e);
|
amf_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
ogs_timer_delete(nf_instance->t_registration_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
||||||
|
ogs_timer_delete(nf_instance->t_validity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amf_nf_state_will_register(ogs_fsm_t *s, amf_event_t *e)
|
void amf_nf_state_will_register(ogs_fsm_t *s, amf_event_t *e)
|
||||||
|
@ -110,7 +122,8 @@ void amf_nf_state_will_register(ogs_fsm_t *s, amf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == amf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, amf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OGS_FSM_EXIT_SIG:
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
@ -166,7 +179,8 @@ void amf_nf_state_will_register(ogs_fsm_t *s, amf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == amf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, amf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -128,7 +128,7 @@ int ngap_send_to_5gsm(amf_ue_t *amf_ue, ogs_pkbuf_t *esmbuf)
|
||||||
e->pkbuf = esmbuf;
|
e->pkbuf = esmbuf;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
|
||||||
e->pkbuf = nasbuf;
|
e->pkbuf = nasbuf;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ngap_send_to_nas() failed:%d", (int)rv);
|
ogs_error("ngap_send_to_nas() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -45,11 +46,18 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_cb(ogs_sbi_response_t *response, void *data)
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
amf_event_t *e = NULL;
|
amf_event_t *e = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
e = amf_event_new(AMF_EVT_SBI_CLIENT);
|
e = amf_event_new(AMF_EVT_SBI_CLIENT);
|
||||||
|
@ -59,7 +67,8 @@ static int client_cb(ogs_sbi_response_t *response, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -91,20 +100,30 @@ int amf_sbi_open(void)
|
||||||
(char*)OGS_SBI_API_V1_0_0, NULL);
|
(char*)OGS_SBI_API_V1_0_0, NULL);
|
||||||
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_SMF);
|
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_SMF);
|
||||||
|
|
||||||
|
/* Initialize SCP NF Instance */
|
||||||
|
nf_instance = ogs_sbi_self()->scp_instance;
|
||||||
|
if (nf_instance) {
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
/* Client callback is only used when NF sends to SCP */
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
client->cb = client_cb;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize NRF NF Instance */
|
/* Initialize NRF NF Instance */
|
||||||
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) {
|
nf_instance = ogs_sbi_self()->nrf_instance;
|
||||||
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
if (nf_instance) {
|
||||||
ogs_sbi_client_t *client = NULL;
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
/* Client callback is only used when NF sends to NRF */
|
/* Client callback is only used when NF sends to NRF */
|
||||||
client = nf_instance->client;
|
client = nf_instance->client;
|
||||||
ogs_assert(client);
|
ogs_assert(client);
|
||||||
client->cb = client_cb;
|
client->cb = client_cb;
|
||||||
|
|
||||||
/* NFRegister is sent and the response is received
|
/* NFRegister is sent and the response is received
|
||||||
* by the above client callback. */
|
* by the above client callback. */
|
||||||
amf_nf_fsm_init(nf_instance);
|
amf_nf_fsm_init(nf_instance);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
|
@ -112,25 +131,10 @@ int amf_sbi_open(void)
|
||||||
|
|
||||||
void amf_sbi_close(void)
|
void amf_sbi_close(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
ogs_sbi_server_stop_all();
|
ogs_sbi_server_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool amf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
|
|
||||||
{
|
|
||||||
ogs_sbi_request_t *request = NULL;
|
|
||||||
ogs_sbi_client_t *client = NULL;
|
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
|
||||||
client = nf_instance->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
request = amf_nnrf_nfm_build_register();
|
|
||||||
ogs_expect_or_return_val(request, false);
|
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool amf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
bool amf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
||||||
{
|
{
|
||||||
return ogs_sbi_send(nf_instance, client_cb, xact);
|
return ogs_sbi_send(nf_instance, client_cb, xact);
|
||||||
|
@ -203,13 +207,21 @@ bool amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static int client_discover_cb(ogs_sbi_response_t *response, void *data)
|
static int client_discover_cb(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
ogs_sbi_message_t message;
|
ogs_sbi_message_t message;
|
||||||
amf_sess_t *sess = data;
|
amf_sess_t *sess = data;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_discover_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
ogs_assert(sess->sbi.type == OGS_SBI_OBJ_SESS_TYPE);
|
ogs_assert(sess->sbi.type == OGS_SBI_OBJ_SESS_TYPE);
|
||||||
|
@ -395,12 +407,19 @@ void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue, int state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_notify_cb(ogs_sbi_response_t *response, void *data)
|
static int client_notify_cb(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
ogs_sbi_message_t message;
|
ogs_sbi_message_t message;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_notify_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
rv = ogs_sbi_parse_response(&message, response);
|
rv = ogs_sbi_parse_response(&message, response);
|
||||||
|
|
|
@ -34,8 +34,6 @@ extern "C" {
|
||||||
int amf_sbi_open(void);
|
int amf_sbi_open(void);
|
||||||
void amf_sbi_close(void);
|
void amf_sbi_close(void);
|
||||||
|
|
||||||
bool amf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance);
|
|
||||||
|
|
||||||
bool amf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
bool amf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
||||||
bool amf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
bool amf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
amf_ue_t *amf_ue, void *data,
|
amf_ue_t *amf_ue, void *data,
|
||||||
|
|
|
@ -109,7 +109,7 @@ void amf_timer_ng_delayed_send(void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_timer_delete(e->timer);
|
ogs_timer_delete(e->timer);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ static void sbi_timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
ogs_error("ogs_queue_push() failed [%d] in %s",
|
||||||
(int)rv, amf_timer_get_name(e->timer_id));
|
(int)rv, amf_timer_get_name(e->timer_id));
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ static void gmm_timer_event_send(
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ void amf_timer_ng_holding_timer_expire(void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
amf_event_free(e);
|
amf_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ int ausf_initialize()
|
||||||
ausf_context_init();
|
ausf_context_init();
|
||||||
ausf_event_init();
|
ausf_event_init();
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("ausf", "nrf");
|
rv = ogs_sbi_context_parse_config("ausf", "nrf", "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = ausf_context_parse_config();
|
rv = ausf_context_parse_config();
|
||||||
|
|
|
@ -61,16 +61,18 @@ void ausf_nf_state_initial(ogs_fsm_t *s, ausf_event_t *e)
|
||||||
nf_instance = e->sbi.data;
|
nf_instance = e->sbi.data;
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
ausf_timer_nf_instance_registration_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_registration_interval);
|
ogs_assert(nf_instance->t_registration_interval);
|
||||||
nf_instance->t_registration_interval->cb =
|
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
ausf_timer_nf_instance_registration_interval;
|
ausf_timer_nf_instance_heartbeat_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_heartbeat_interval);
|
ogs_assert(nf_instance->t_heartbeat_interval);
|
||||||
nf_instance->t_heartbeat_interval->cb =
|
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
ausf_timer_nf_instance_heartbeat_interval;
|
ausf_timer_nf_instance_no_heartbeat, nf_instance);
|
||||||
ogs_assert(nf_instance->t_no_heartbeat);
|
ogs_assert(nf_instance->t_no_heartbeat);
|
||||||
nf_instance->t_no_heartbeat->cb = ausf_timer_nf_instance_no_heartbeat;
|
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
ausf_timer_nf_instance_validity, nf_instance);
|
||||||
ogs_assert(nf_instance->t_validity);
|
ogs_assert(nf_instance->t_validity);
|
||||||
nf_instance->t_validity->cb = ausf_timer_nf_instance_validity;
|
|
||||||
|
|
||||||
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
OGS_FSM_TRAN(s, &ausf_nf_state_will_register);
|
OGS_FSM_TRAN(s, &ausf_nf_state_will_register);
|
||||||
|
@ -82,10 +84,20 @@ void ausf_nf_state_initial(ogs_fsm_t *s, ausf_event_t *e)
|
||||||
|
|
||||||
void ausf_nf_state_final(ogs_fsm_t *s, ausf_event_t *e)
|
void ausf_nf_state_final(ogs_fsm_t *s, ausf_event_t *e)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
ogs_assert(s);
|
ogs_assert(s);
|
||||||
ogs_assert(e);
|
ogs_assert(e);
|
||||||
|
|
||||||
ausf_sm_debug(e);
|
ausf_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
ogs_timer_delete(nf_instance->t_registration_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
||||||
|
ogs_timer_delete(nf_instance->t_validity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ausf_nf_state_will_register(ogs_fsm_t *s, ausf_event_t *e)
|
void ausf_nf_state_will_register(ogs_fsm_t *s, ausf_event_t *e)
|
||||||
|
@ -110,7 +122,8 @@ void ausf_nf_state_will_register(ogs_fsm_t *s, ausf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == ausf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, ausf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OGS_FSM_EXIT_SIG:
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
@ -166,7 +179,8 @@ void ausf_nf_state_will_register(ogs_fsm_t *s, ausf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == ausf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, ausf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -35,7 +35,8 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
ausf_event_free(e);
|
ausf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -43,11 +44,18 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_cb(ogs_sbi_response_t *response, void *data)
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
ausf_event_t *e = NULL;
|
ausf_event_t *e = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
e = ausf_event_new(AUSF_EVT_SBI_CLIENT);
|
e = ausf_event_new(AUSF_EVT_SBI_CLIENT);
|
||||||
|
@ -57,7 +65,8 @@ static int client_cb(ogs_sbi_response_t *response, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
ausf_event_free(e);
|
ausf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -110,25 +119,10 @@ int ausf_sbi_open(void)
|
||||||
|
|
||||||
void ausf_sbi_close(void)
|
void ausf_sbi_close(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
ogs_sbi_server_stop_all();
|
ogs_sbi_server_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ausf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
|
|
||||||
{
|
|
||||||
ogs_sbi_request_t *request = NULL;
|
|
||||||
ogs_sbi_client_t *client = NULL;
|
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
|
||||||
client = nf_instance->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
request = ausf_nnrf_nfm_build_register();
|
|
||||||
ogs_expect_or_return_val(request, false);
|
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ausf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
bool ausf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
||||||
{
|
{
|
||||||
return ogs_sbi_send(nf_instance, client_cb, xact);
|
return ogs_sbi_send(nf_instance, client_cb, xact);
|
||||||
|
|
|
@ -30,8 +30,6 @@ extern "C" {
|
||||||
int ausf_sbi_open(void);
|
int ausf_sbi_open(void);
|
||||||
void ausf_sbi_close(void);
|
void ausf_sbi_close(void);
|
||||||
|
|
||||||
bool ausf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance);
|
|
||||||
|
|
||||||
bool ausf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
bool ausf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
||||||
bool ausf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
bool ausf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
ausf_ue_t *ausf_ue, ogs_sbi_stream_t *stream, void *data,
|
ausf_ue_t *ausf_ue, ogs_sbi_stream_t *stream, void *data,
|
||||||
|
|
|
@ -79,7 +79,7 @@ static void sbi_timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
ogs_error("ogs_queue_push() failed [%d] in %s",
|
||||||
(int)rv, ausf_timer_get_name(e->timer_id));
|
(int)rv, ausf_timer_get_name(e->timer_id));
|
||||||
ausf_event_free(e);
|
ausf_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ int bsf_initialize()
|
||||||
bsf_context_init();
|
bsf_context_init();
|
||||||
bsf_event_init();
|
bsf_event_init();
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("bsf", "nrf");
|
rv = ogs_sbi_context_parse_config("bsf", "nrf", "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = bsf_context_parse_config();
|
rv = bsf_context_parse_config();
|
||||||
|
|
|
@ -61,16 +61,18 @@ void bsf_nf_state_initial(ogs_fsm_t *s, bsf_event_t *e)
|
||||||
nf_instance = e->sbi.data;
|
nf_instance = e->sbi.data;
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
bsf_timer_nf_instance_registration_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_registration_interval);
|
ogs_assert(nf_instance->t_registration_interval);
|
||||||
nf_instance->t_registration_interval->cb =
|
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
bsf_timer_nf_instance_registration_interval;
|
bsf_timer_nf_instance_heartbeat_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_heartbeat_interval);
|
ogs_assert(nf_instance->t_heartbeat_interval);
|
||||||
nf_instance->t_heartbeat_interval->cb =
|
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
bsf_timer_nf_instance_heartbeat_interval;
|
bsf_timer_nf_instance_no_heartbeat, nf_instance);
|
||||||
ogs_assert(nf_instance->t_no_heartbeat);
|
ogs_assert(nf_instance->t_no_heartbeat);
|
||||||
nf_instance->t_no_heartbeat->cb = bsf_timer_nf_instance_no_heartbeat;
|
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
bsf_timer_nf_instance_validity, nf_instance);
|
||||||
ogs_assert(nf_instance->t_validity);
|
ogs_assert(nf_instance->t_validity);
|
||||||
nf_instance->t_validity->cb = bsf_timer_nf_instance_validity;
|
|
||||||
|
|
||||||
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
OGS_FSM_TRAN(s, &bsf_nf_state_will_register);
|
OGS_FSM_TRAN(s, &bsf_nf_state_will_register);
|
||||||
|
@ -82,10 +84,20 @@ void bsf_nf_state_initial(ogs_fsm_t *s, bsf_event_t *e)
|
||||||
|
|
||||||
void bsf_nf_state_final(ogs_fsm_t *s, bsf_event_t *e)
|
void bsf_nf_state_final(ogs_fsm_t *s, bsf_event_t *e)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
ogs_assert(s);
|
ogs_assert(s);
|
||||||
ogs_assert(e);
|
ogs_assert(e);
|
||||||
|
|
||||||
bsf_sm_debug(e);
|
bsf_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
ogs_timer_delete(nf_instance->t_registration_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
||||||
|
ogs_timer_delete(nf_instance->t_validity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
|
void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
|
||||||
|
@ -110,7 +122,8 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == bsf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, bsf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OGS_FSM_EXIT_SIG:
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
@ -166,7 +179,8 @@ void bsf_nf_state_will_register(ogs_fsm_t *s, bsf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == bsf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, bsf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -35,7 +35,8 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
bsf_event_free(e);
|
bsf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -43,11 +44,18 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_cb(ogs_sbi_response_t *response, void *data)
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
bsf_event_t *e = NULL;
|
bsf_event_t *e = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
e = bsf_event_new(BSF_EVT_SBI_CLIENT);
|
e = bsf_event_new(BSF_EVT_SBI_CLIENT);
|
||||||
|
@ -57,7 +65,8 @@ static int client_cb(ogs_sbi_response_t *response, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
bsf_event_free(e);
|
bsf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -110,25 +119,10 @@ int bsf_sbi_open(void)
|
||||||
|
|
||||||
void bsf_sbi_close(void)
|
void bsf_sbi_close(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
ogs_sbi_server_stop_all();
|
ogs_sbi_server_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bsf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
|
|
||||||
{
|
|
||||||
ogs_sbi_request_t *request = NULL;
|
|
||||||
ogs_sbi_client_t *client = NULL;
|
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
|
||||||
client = nf_instance->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
request = bsf_nnrf_nfm_build_register();
|
|
||||||
ogs_expect_or_return_val(request, false);
|
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bsf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
bool bsf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
||||||
{
|
{
|
||||||
return ogs_sbi_send(nf_instance, client_cb, xact);
|
return ogs_sbi_send(nf_instance, client_cb, xact);
|
||||||
|
|
|
@ -29,8 +29,6 @@ extern "C" {
|
||||||
int bsf_sbi_open(void);
|
int bsf_sbi_open(void);
|
||||||
void bsf_sbi_close(void);
|
void bsf_sbi_close(void);
|
||||||
|
|
||||||
bool bsf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance);
|
|
||||||
|
|
||||||
bool bsf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
bool bsf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
||||||
|
|
||||||
bool bsf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
bool bsf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
|
|
|
@ -81,7 +81,7 @@ static void timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
ogs_error("ogs_queue_push() failed [%d] in %s",
|
||||||
(int)rv, bsf_timer_get_name(e->timer_id));
|
(int)rv, bsf_timer_get_name(e->timer_id));
|
||||||
bsf_event_free(e);
|
bsf_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ subdir('sgwu')
|
||||||
subdir('pcrf')
|
subdir('pcrf')
|
||||||
|
|
||||||
subdir('nrf')
|
subdir('nrf')
|
||||||
|
subdir('scp')
|
||||||
|
|
||||||
subdir('udr')
|
subdir('udr')
|
||||||
subdir('udm')
|
subdir('udm')
|
||||||
subdir('pcf')
|
subdir('pcf')
|
||||||
|
|
|
@ -125,7 +125,7 @@ void mme_sctp_event_push(mme_event_e id,
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_free(e->addr);
|
ogs_free(e->addr);
|
||||||
if (e->pkbuf)
|
if (e->pkbuf)
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
|
|
|
@ -111,7 +111,7 @@ void mme_timer_s1_delayed_send(void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_timer_delete(e->timer);
|
ogs_timer_delete(e->timer);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ static void emm_timer_event_send(
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ static void esm_timer_event_send(
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ void mme_timer_sgs_cli_conn_to_srv(void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ void mme_timer_s1_holding_timer_expire(void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ void mme_timer_s11_holding_timer_expire(void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ int s1ap_send_to_esm(
|
||||||
e->create_action = create_action;
|
e->create_action = create_action;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
|
||||||
e->pkbuf = nasbuf;
|
e->pkbuf = nasbuf;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("s1ap_send_to_nas() failed:%d", (int)rv);
|
ogs_error("s1ap_send_to_nas() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
mme_event_free(e);
|
mme_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ int nrf_initialize()
|
||||||
nrf_context_init();
|
nrf_context_init();
|
||||||
nrf_event_init();
|
nrf_event_init();
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("nrf", NULL);
|
rv = ogs_sbi_context_parse_config("nrf", NULL, "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = nrf_context_parse_config();
|
rv = nrf_context_parse_config();
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "nnrf-build.h"
|
#include "nnrf-build.h"
|
||||||
|
|
||||||
ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify(
|
ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify(
|
||||||
ogs_sbi_client_t *client, ogs_sbi_subscription_t *subscription,
|
ogs_sbi_subscription_t *subscription,
|
||||||
OpenAPI_notification_event_type_e event,
|
OpenAPI_notification_event_type_e event,
|
||||||
ogs_sbi_nf_instance_t *nf_instance)
|
ogs_sbi_nf_instance_t *nf_instance)
|
||||||
{
|
{
|
||||||
|
@ -32,7 +32,6 @@ ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify(
|
||||||
|
|
||||||
OpenAPI_notification_data_t *NotificationData = NULL;
|
OpenAPI_notification_data_t *NotificationData = NULL;
|
||||||
|
|
||||||
ogs_assert(client);
|
|
||||||
ogs_assert(subscription);
|
ogs_assert(subscription);
|
||||||
ogs_assert(event);
|
ogs_assert(event);
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify(
|
ogs_sbi_request_t *nrf_nnrf_nfm_build_nf_status_notify(
|
||||||
ogs_sbi_client_t *client, ogs_sbi_subscription_t *subscription,
|
ogs_sbi_subscription_t *subscription,
|
||||||
OpenAPI_notification_event_type_e event,
|
OpenAPI_notification_event_type_e event,
|
||||||
ogs_sbi_nf_instance_t *nf_instance);
|
ogs_sbi_nf_instance_t *nf_instance);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,11 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
if (rv != OGS_DONE)
|
||||||
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
else
|
||||||
|
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
nrf_event_free(e);
|
nrf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -43,12 +47,19 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_notify_cb(ogs_sbi_response_t *response, void *data)
|
static int client_notify_cb(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
ogs_sbi_message_t message;
|
ogs_sbi_message_t message;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_notify_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
rv = ogs_sbi_parse_response(&message, response);
|
rv = ogs_sbi_parse_response(&message, response);
|
||||||
|
@ -69,14 +80,28 @@ static int client_notify_cb(ogs_sbi_response_t *response, void *data)
|
||||||
|
|
||||||
int nrf_sbi_open(void)
|
int nrf_sbi_open(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
if (ogs_sbi_server_start_all(server_cb) != OGS_OK)
|
if (ogs_sbi_server_start_all(server_cb) != OGS_OK)
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
|
|
||||||
|
/* Initialize SCP NF Instance */
|
||||||
|
nf_instance = ogs_sbi_self()->scp_instance;
|
||||||
|
if (nf_instance) {
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
/* Client callback is only used when NF sends to SCP */
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
client->cb = client_notify_cb;
|
||||||
|
}
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nrf_sbi_close(void)
|
void nrf_sbi_close(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
ogs_sbi_server_stop_all();
|
ogs_sbi_server_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +117,10 @@ bool nrf_nnrf_nfm_send_nf_status_notify(ogs_sbi_subscription_t *subscription,
|
||||||
ogs_assert(client);
|
ogs_assert(client);
|
||||||
|
|
||||||
request = nrf_nnrf_nfm_build_nf_status_notify(
|
request = nrf_nnrf_nfm_build_nf_status_notify(
|
||||||
client, subscription, event, nf_instance);
|
subscription, event, nf_instance);
|
||||||
ogs_expect_or_return_val(request, false);
|
ogs_expect_or_return_val(request, false);
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(client, client_notify_cb, request, NULL);
|
return ogs_sbi_scp_send_request(client, client_notify_cb, request, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nrf_nnrf_nfm_send_nf_status_notify_all(
|
bool nrf_nnrf_nfm_send_nf_status_notify_all(
|
||||||
|
|
|
@ -68,7 +68,7 @@ static void timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
nrf_event_free(e);
|
nrf_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ int nssf_initialize()
|
||||||
nssf_context_init();
|
nssf_context_init();
|
||||||
nssf_event_init();
|
nssf_event_init();
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("nssf", "nrf");
|
rv = ogs_sbi_context_parse_config("nssf", "nrf", "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = nssf_context_parse_config();
|
rv = nssf_context_parse_config();
|
||||||
|
|
|
@ -61,16 +61,18 @@ void nssf_nf_state_initial(ogs_fsm_t *s, nssf_event_t *e)
|
||||||
nf_instance = e->sbi.data;
|
nf_instance = e->sbi.data;
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
nssf_timer_nf_instance_registration_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_registration_interval);
|
ogs_assert(nf_instance->t_registration_interval);
|
||||||
nf_instance->t_registration_interval->cb =
|
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
nssf_timer_nf_instance_registration_interval;
|
nssf_timer_nf_instance_heartbeat_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_heartbeat_interval);
|
ogs_assert(nf_instance->t_heartbeat_interval);
|
||||||
nf_instance->t_heartbeat_interval->cb =
|
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
nssf_timer_nf_instance_heartbeat_interval;
|
nssf_timer_nf_instance_no_heartbeat, nf_instance);
|
||||||
ogs_assert(nf_instance->t_no_heartbeat);
|
ogs_assert(nf_instance->t_no_heartbeat);
|
||||||
nf_instance->t_no_heartbeat->cb = nssf_timer_nf_instance_no_heartbeat;
|
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
nssf_timer_nf_instance_validity, nf_instance);
|
||||||
ogs_assert(nf_instance->t_validity);
|
ogs_assert(nf_instance->t_validity);
|
||||||
nf_instance->t_validity->cb = nssf_timer_nf_instance_validity;
|
|
||||||
|
|
||||||
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
OGS_FSM_TRAN(s, &nssf_nf_state_will_register);
|
OGS_FSM_TRAN(s, &nssf_nf_state_will_register);
|
||||||
|
@ -82,10 +84,20 @@ void nssf_nf_state_initial(ogs_fsm_t *s, nssf_event_t *e)
|
||||||
|
|
||||||
void nssf_nf_state_final(ogs_fsm_t *s, nssf_event_t *e)
|
void nssf_nf_state_final(ogs_fsm_t *s, nssf_event_t *e)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
ogs_assert(s);
|
ogs_assert(s);
|
||||||
ogs_assert(e);
|
ogs_assert(e);
|
||||||
|
|
||||||
nssf_sm_debug(e);
|
nssf_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
ogs_timer_delete(nf_instance->t_registration_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
||||||
|
ogs_timer_delete(nf_instance->t_validity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nssf_nf_state_will_register(ogs_fsm_t *s, nssf_event_t *e)
|
void nssf_nf_state_will_register(ogs_fsm_t *s, nssf_event_t *e)
|
||||||
|
@ -110,7 +122,8 @@ void nssf_nf_state_will_register(ogs_fsm_t *s, nssf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == nssf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, nssf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OGS_FSM_EXIT_SIG:
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
@ -166,7 +179,8 @@ void nssf_nf_state_will_register(ogs_fsm_t *s, nssf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == nssf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, nssf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -35,7 +35,8 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
nssf_event_free(e);
|
nssf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -43,11 +44,18 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_cb(ogs_sbi_response_t *response, void *data)
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
nssf_event_t *e = NULL;
|
nssf_event_t *e = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
e = nssf_event_new(NSSF_EVT_SBI_CLIENT);
|
e = nssf_event_new(NSSF_EVT_SBI_CLIENT);
|
||||||
|
@ -57,7 +65,8 @@ static int client_cb(ogs_sbi_response_t *response, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
nssf_event_free(e);
|
nssf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -110,21 +119,6 @@ int nssf_sbi_open(void)
|
||||||
|
|
||||||
void nssf_sbi_close(void)
|
void nssf_sbi_close(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
ogs_sbi_server_stop_all();
|
ogs_sbi_server_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nssf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
|
|
||||||
{
|
|
||||||
ogs_sbi_request_t *request = NULL;
|
|
||||||
ogs_sbi_client_t *client = NULL;
|
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
|
||||||
client = nf_instance->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
request = nssf_nnrf_nfm_build_register();
|
|
||||||
ogs_expect_or_return_val(request, false);
|
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ extern "C" {
|
||||||
int nssf_sbi_open(void);
|
int nssf_sbi_open(void);
|
||||||
void nssf_sbi_close(void);
|
void nssf_sbi_close(void);
|
||||||
|
|
||||||
bool nssf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -64,7 +64,7 @@ static void sbi_timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
ogs_error("ogs_queue_push() failed [%d] in %s",
|
||||||
(int)rv, nssf_timer_get_name(e->timer_id));
|
(int)rv, nssf_timer_get_name(e->timer_id));
|
||||||
nssf_event_free(e);
|
nssf_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ int pcf_initialize()
|
||||||
pcf_context_init();
|
pcf_context_init();
|
||||||
pcf_event_init();
|
pcf_event_init();
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("pcf", "nrf");
|
rv = ogs_sbi_context_parse_config("pcf", "nrf", "scp");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = pcf_context_parse_config();
|
rv = pcf_context_parse_config();
|
||||||
|
|
|
@ -61,16 +61,18 @@ void pcf_nf_state_initial(ogs_fsm_t *s, pcf_event_t *e)
|
||||||
nf_instance = e->sbi.data;
|
nf_instance = e->sbi.data;
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
pcf_timer_nf_instance_registration_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_registration_interval);
|
ogs_assert(nf_instance->t_registration_interval);
|
||||||
nf_instance->t_registration_interval->cb =
|
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
pcf_timer_nf_instance_registration_interval;
|
pcf_timer_nf_instance_heartbeat_interval, nf_instance);
|
||||||
ogs_assert(nf_instance->t_heartbeat_interval);
|
ogs_assert(nf_instance->t_heartbeat_interval);
|
||||||
nf_instance->t_heartbeat_interval->cb =
|
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
pcf_timer_nf_instance_heartbeat_interval;
|
pcf_timer_nf_instance_no_heartbeat, nf_instance);
|
||||||
ogs_assert(nf_instance->t_no_heartbeat);
|
ogs_assert(nf_instance->t_no_heartbeat);
|
||||||
nf_instance->t_no_heartbeat->cb = pcf_timer_nf_instance_no_heartbeat;
|
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
pcf_timer_nf_instance_validity, nf_instance);
|
||||||
ogs_assert(nf_instance->t_validity);
|
ogs_assert(nf_instance->t_validity);
|
||||||
nf_instance->t_validity->cb = pcf_timer_nf_instance_validity;
|
|
||||||
|
|
||||||
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
OGS_FSM_TRAN(s, &pcf_nf_state_will_register);
|
OGS_FSM_TRAN(s, &pcf_nf_state_will_register);
|
||||||
|
@ -82,10 +84,20 @@ void pcf_nf_state_initial(ogs_fsm_t *s, pcf_event_t *e)
|
||||||
|
|
||||||
void pcf_nf_state_final(ogs_fsm_t *s, pcf_event_t *e)
|
void pcf_nf_state_final(ogs_fsm_t *s, pcf_event_t *e)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
ogs_assert(s);
|
ogs_assert(s);
|
||||||
ogs_assert(e);
|
ogs_assert(e);
|
||||||
|
|
||||||
pcf_sm_debug(e);
|
pcf_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
ogs_timer_delete(nf_instance->t_registration_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
||||||
|
ogs_timer_delete(nf_instance->t_validity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcf_nf_state_will_register(ogs_fsm_t *s, pcf_event_t *e)
|
void pcf_nf_state_will_register(ogs_fsm_t *s, pcf_event_t *e)
|
||||||
|
@ -110,7 +122,8 @@ void pcf_nf_state_will_register(ogs_fsm_t *s, pcf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == pcf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, pcf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OGS_FSM_EXIT_SIG:
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
@ -167,7 +180,8 @@ void pcf_nf_state_will_register(ogs_fsm_t *s, pcf_event_t *e)
|
||||||
ogs_timer_start(nf_instance->t_registration_interval,
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
ogs_app()->time.message.sbi.nf_register_interval);
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
ogs_assert(true == pcf_nnrf_nfm_send_nf_register(nf_instance));
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, pcf_nnrf_nfm_build_register));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -35,7 +35,8 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(request);
|
||||||
pcf_event_free(e);
|
pcf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -43,11 +44,18 @@ static int server_cb(ogs_sbi_request_t *request, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_cb(ogs_sbi_response_t *response, void *data)
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
pcf_event_t *e = NULL;
|
pcf_event_t *e = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
e = pcf_event_new(PCF_EVT_SBI_CLIENT);
|
e = pcf_event_new(PCF_EVT_SBI_CLIENT);
|
||||||
|
@ -57,7 +65,8 @@ static int client_cb(ogs_sbi_response_t *response, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
pcf_event_free(e);
|
pcf_event_free(e);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -123,25 +132,10 @@ int pcf_sbi_open(void)
|
||||||
|
|
||||||
void pcf_sbi_close(void)
|
void pcf_sbi_close(void)
|
||||||
{
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
ogs_sbi_server_stop_all();
|
ogs_sbi_server_stop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance)
|
|
||||||
{
|
|
||||||
ogs_sbi_request_t *request = NULL;
|
|
||||||
ogs_sbi_client_t *client = NULL;
|
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
|
||||||
client = nf_instance->client;
|
|
||||||
ogs_assert(client);
|
|
||||||
|
|
||||||
request = pcf_nnrf_nfm_build_register();
|
|
||||||
ogs_expect_or_return_val(request, false);
|
|
||||||
|
|
||||||
return ogs_sbi_client_send_request(
|
|
||||||
client, client->cb, request, nf_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pcf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
bool pcf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
||||||
{
|
{
|
||||||
return ogs_sbi_send(nf_instance, client_cb, xact);
|
return ogs_sbi_send(nf_instance, client_cb, xact);
|
||||||
|
@ -209,12 +203,19 @@ bool pcf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_notify_cb(ogs_sbi_response_t *response, void *data)
|
static int client_notify_cb(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
ogs_sbi_message_t message;
|
ogs_sbi_message_t message;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_notify_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
rv = ogs_sbi_parse_response(&message, response);
|
rv = ogs_sbi_parse_response(&message, response);
|
||||||
|
@ -234,12 +235,13 @@ static int client_notify_cb(ogs_sbi_response_t *response, void *data)
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_delete_notify_cb(ogs_sbi_response_t *response, void *data)
|
static int client_delete_notify_cb(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data)
|
||||||
{
|
{
|
||||||
pcf_app_t *app_session = data;
|
pcf_app_t *app_session = data;
|
||||||
|
|
||||||
ogs_assert(app_session);
|
ogs_assert(app_session);
|
||||||
client_notify_cb(response, data);
|
client_notify_cb(status, response, data);
|
||||||
|
|
||||||
pcf_app_remove(app_session);
|
pcf_app_remove(app_session);
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,6 @@ extern "C" {
|
||||||
int pcf_sbi_open(void);
|
int pcf_sbi_open(void);
|
||||||
void pcf_sbi_close(void);
|
void pcf_sbi_close(void);
|
||||||
|
|
||||||
bool pcf_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance);
|
|
||||||
|
|
||||||
bool pcf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
bool pcf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
||||||
bool pcf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
bool pcf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
pcf_ue_t *pcf_ue, ogs_sbi_stream_t *stream, void *data,
|
pcf_ue_t *pcf_ue, ogs_sbi_stream_t *stream, void *data,
|
||||||
|
|
|
@ -79,7 +79,7 @@ static void sbi_timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
ogs_error("ogs_queue_push() failed [%d] in %s",
|
||||||
(int)rv, pcf_timer_get_name(e->timer_id));
|
(int)rv, pcf_timer_get_name(e->timer_id));
|
||||||
pcf_event_free(e);
|
pcf_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Open5GS.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ogs-app.h"
|
||||||
|
|
||||||
|
int app_initialize(const char *const argv[])
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = scp_initialize();
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("Failed to intialize SCP");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
ogs_info("SCP initialize...done");
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_terminate(void)
|
||||||
|
{
|
||||||
|
scp_terminate();
|
||||||
|
ogs_info("SCP terminate...done");
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* 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 "context.h"
|
||||||
|
|
||||||
|
static scp_context_t self;
|
||||||
|
|
||||||
|
int __scp_log_domain;
|
||||||
|
|
||||||
|
static OGS_POOL(scp_conn_pool, scp_conn_t);
|
||||||
|
|
||||||
|
static int context_initialized = 0;
|
||||||
|
|
||||||
|
static int max_num_of_scp_conn = 0;
|
||||||
|
|
||||||
|
void scp_context_init(void)
|
||||||
|
{
|
||||||
|
ogs_assert(context_initialized == 0);
|
||||||
|
|
||||||
|
/* Initialize SCP context */
|
||||||
|
memset(&self, 0, sizeof(scp_context_t));
|
||||||
|
|
||||||
|
ogs_log_install_domain(&__scp_log_domain, "scp", ogs_core()->log.level);
|
||||||
|
|
||||||
|
#define MAX_NUM_OF_SCP_CONN 8
|
||||||
|
max_num_of_scp_conn = ogs_app()->max.ue * MAX_NUM_OF_SCP_CONN;
|
||||||
|
|
||||||
|
ogs_pool_init(&scp_conn_pool, max_num_of_scp_conn);
|
||||||
|
|
||||||
|
context_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_context_final(void)
|
||||||
|
{
|
||||||
|
ogs_assert(context_initialized == 1);
|
||||||
|
|
||||||
|
scp_conn_remove_all();
|
||||||
|
|
||||||
|
ogs_pool_final(&scp_conn_pool);
|
||||||
|
|
||||||
|
context_initialized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
scp_context_t *scp_self(void)
|
||||||
|
{
|
||||||
|
return &self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scp_context_prepare(void)
|
||||||
|
{
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scp_context_validation(void)
|
||||||
|
{
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scp_context_parse_config(void)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
yaml_document_t *document = NULL;
|
||||||
|
ogs_yaml_iter_t root_iter;
|
||||||
|
|
||||||
|
document = ogs_app()->document;
|
||||||
|
ogs_assert(document);
|
||||||
|
|
||||||
|
rv = scp_context_prepare();
|
||||||
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
ogs_yaml_iter_init(&root_iter, document);
|
||||||
|
while (ogs_yaml_iter_next(&root_iter)) {
|
||||||
|
const char *root_key = ogs_yaml_iter_key(&root_iter);
|
||||||
|
ogs_assert(root_key);
|
||||||
|
if (!strcmp(root_key, "scp")) {
|
||||||
|
ogs_yaml_iter_t scp_iter;
|
||||||
|
ogs_yaml_iter_recurse(&root_iter, &scp_iter);
|
||||||
|
while (ogs_yaml_iter_next(&scp_iter)) {
|
||||||
|
const char *scp_key = ogs_yaml_iter_key(&scp_iter);
|
||||||
|
ogs_assert(scp_key);
|
||||||
|
if (!strcmp(scp_key, "sbi")) {
|
||||||
|
/* handle config in sbi library */
|
||||||
|
} else
|
||||||
|
ogs_warn("unknown key `%s`", scp_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = scp_context_validation();
|
||||||
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
scp_conn_t *scp_conn_add(ogs_sbi_stream_t *stream)
|
||||||
|
{
|
||||||
|
scp_conn_t *conn = NULL;
|
||||||
|
|
||||||
|
ogs_assert(stream);
|
||||||
|
|
||||||
|
ogs_pool_alloc(&scp_conn_pool, &conn);
|
||||||
|
if (!conn) {
|
||||||
|
ogs_error("Maximum number of connection[%d] reached",
|
||||||
|
max_num_of_scp_conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(conn, 0, sizeof *conn);
|
||||||
|
|
||||||
|
conn->stream = stream;
|
||||||
|
|
||||||
|
ogs_list_add(&self.conn_list, conn);
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_conn_remove(scp_conn_t *conn)
|
||||||
|
{
|
||||||
|
ogs_assert(conn);
|
||||||
|
|
||||||
|
ogs_list_remove(&self.conn_list, conn);
|
||||||
|
|
||||||
|
if (conn->client)
|
||||||
|
ogs_sbi_client_remove(conn->client);
|
||||||
|
|
||||||
|
ogs_pool_free(&scp_conn_pool, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_conn_remove_all(void)
|
||||||
|
{
|
||||||
|
scp_conn_t *conn = NULL, *next_conn = NULL;
|
||||||
|
|
||||||
|
ogs_list_for_each_safe(&self.conn_list, next_conn, conn)
|
||||||
|
scp_conn_remove(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
scp_conn_t *scp_conn_find(uint32_t index)
|
||||||
|
{
|
||||||
|
return ogs_pool_find(&scp_conn_pool, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_conn_select_nf(scp_conn_t *sess, OpenAPI_nf_type_e nf_type)
|
||||||
|
{
|
||||||
|
ogs_assert(sess);
|
||||||
|
ogs_assert(nf_type);
|
||||||
|
|
||||||
|
ogs_sbi_select_nf(&sess->sbi, nf_type, scp_nf_state_registered);
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_CONTEXT_H
|
||||||
|
#define SCP_CONTEXT_H
|
||||||
|
|
||||||
|
#include "ogs-sbi.h"
|
||||||
|
#include "ogs-app.h"
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
#include "scp-sm.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int __scp_log_domain;
|
||||||
|
|
||||||
|
#undef OGS_LOG_DOMAIN
|
||||||
|
#define OGS_LOG_DOMAIN __scp_log_domain
|
||||||
|
|
||||||
|
typedef struct scp_context_s {
|
||||||
|
ogs_list_t conn_list;
|
||||||
|
} scp_context_t;
|
||||||
|
|
||||||
|
#define SCP_NF_INSTANCE_CLEAR(_cAUSE, _nFInstance) \
|
||||||
|
do { \
|
||||||
|
ogs_assert(_nFInstance); \
|
||||||
|
if ((_nFInstance)->reference_count == 1) { \
|
||||||
|
ogs_info("[%s] (%s) NF removed", (_nFInstance)->id, (_cAUSE)); \
|
||||||
|
scp_nf_fsm_fini((_nFInstance)); \
|
||||||
|
} else { \
|
||||||
|
/* There is an assocation with other context */ \
|
||||||
|
ogs_info("[%s:%d] (%s) NF suspended", \
|
||||||
|
_nFInstance->id, _nFInstance->reference_count, (_cAUSE)); \
|
||||||
|
OGS_FSM_TRAN(&_nFInstance->sm, scp_nf_state_de_registered); \
|
||||||
|
ogs_fsm_dispatch(&_nFInstance->sm, NULL); \
|
||||||
|
} \
|
||||||
|
ogs_sbi_nf_instance_remove(_nFInstance); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
typedef struct scp_conn_s scp_conn_t;
|
||||||
|
|
||||||
|
typedef struct scp_conn_s {
|
||||||
|
ogs_sbi_object_t sbi;
|
||||||
|
|
||||||
|
ogs_sbi_client_t *client;
|
||||||
|
|
||||||
|
ogs_sbi_stream_t *stream;
|
||||||
|
ogs_sbi_request_t *request;
|
||||||
|
|
||||||
|
} scp_conn_t;
|
||||||
|
|
||||||
|
void scp_context_init(void);
|
||||||
|
void scp_context_final(void);
|
||||||
|
scp_context_t *scp_self(void);
|
||||||
|
|
||||||
|
int scp_context_parse_config(void);
|
||||||
|
|
||||||
|
scp_conn_t *scp_conn_add(ogs_sbi_stream_t *stream);
|
||||||
|
void scp_conn_remove(scp_conn_t *sess);
|
||||||
|
void scp_conn_remove_all(void);
|
||||||
|
|
||||||
|
scp_conn_t *scp_conn_find(uint32_t index);
|
||||||
|
|
||||||
|
void scp_conn_select_nf(scp_conn_t *sess, OpenAPI_nf_type_e nf_type);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_CONTEXT_H */
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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 "event.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
static OGS_POOL(pool, scp_event_t);
|
||||||
|
|
||||||
|
void scp_event_init(void)
|
||||||
|
{
|
||||||
|
ogs_pool_init(&pool, ogs_app()->pool.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_event_final(void)
|
||||||
|
{
|
||||||
|
ogs_pool_final(&pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
scp_event_t *scp_event_new(scp_event_e id)
|
||||||
|
{
|
||||||
|
scp_event_t *e = NULL;
|
||||||
|
|
||||||
|
ogs_pool_alloc(&pool, &e);
|
||||||
|
ogs_assert(e);
|
||||||
|
memset(e, 0, sizeof(*e));
|
||||||
|
|
||||||
|
e->id = id;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_event_free(scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_assert(e);
|
||||||
|
ogs_pool_free(&pool, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *scp_event_get_name(scp_event_t *e)
|
||||||
|
{
|
||||||
|
if (e == NULL)
|
||||||
|
return OGS_FSM_NAME_INIT_SIG;
|
||||||
|
|
||||||
|
switch (e->id) {
|
||||||
|
case OGS_FSM_ENTRY_SIG:
|
||||||
|
return OGS_FSM_NAME_ENTRY_SIG;
|
||||||
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
return OGS_FSM_NAME_EXIT_SIG;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_SERVER:
|
||||||
|
return "SCP_EVT_SBI_SERVER";
|
||||||
|
case SCP_EVT_SBI_CLIENT:
|
||||||
|
return "SCP_EVT_SBI_CLIENT";
|
||||||
|
case SCP_EVT_SBI_TIMER:
|
||||||
|
return "SCP_EVT_SBI_TIMER";
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN_EVENT";
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_EVENT_H
|
||||||
|
#define SCP_EVENT_H
|
||||||
|
|
||||||
|
#include "ogs-core.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct scp_sess_s scp_sess_t;
|
||||||
|
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
|
||||||
|
typedef struct ogs_sbi_response_s ogs_sbi_response_t;
|
||||||
|
typedef struct ogs_sbi_message_s ogs_sbi_message_t;
|
||||||
|
typedef struct ogs_sbi_nf_instance_s ogs_sbi_nf_instance_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCP_EVT_BASE = OGS_FSM_USER_SIG,
|
||||||
|
|
||||||
|
SCP_EVT_SBI_SERVER,
|
||||||
|
SCP_EVT_SBI_CLIENT,
|
||||||
|
SCP_EVT_SBI_TIMER,
|
||||||
|
|
||||||
|
SCP_EVT_TOP,
|
||||||
|
|
||||||
|
} scp_event_e;
|
||||||
|
|
||||||
|
typedef struct scp_event_s {
|
||||||
|
int id;
|
||||||
|
ogs_pkbuf_t *pkbuf;
|
||||||
|
int timer_id;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
ogs_sbi_request_t *request;
|
||||||
|
ogs_sbi_response_t *response;
|
||||||
|
void *data;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
ogs_sbi_message_t *message;
|
||||||
|
} sbi;
|
||||||
|
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance;
|
||||||
|
scp_sess_t *sess;
|
||||||
|
} scp_event_t;
|
||||||
|
|
||||||
|
void scp_event_init(void);
|
||||||
|
void scp_event_final(void);
|
||||||
|
|
||||||
|
scp_event_t *scp_event_new(scp_event_e id);
|
||||||
|
void scp_event_free(scp_event_t *e);
|
||||||
|
|
||||||
|
const char *scp_event_get_name(scp_event_t *e);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_EVENT_H */
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* 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 "context.h"
|
||||||
|
#include "sbi-path.h"
|
||||||
|
|
||||||
|
static ogs_thread_t *thread;
|
||||||
|
static void scp_main(void *data);
|
||||||
|
|
||||||
|
static int initialized = 0;
|
||||||
|
|
||||||
|
int scp_initialize()
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
ogs_sbi_context_init();
|
||||||
|
|
||||||
|
scp_context_init();
|
||||||
|
scp_event_init();
|
||||||
|
|
||||||
|
rv = ogs_sbi_context_parse_config("scp", "nrf", "next_scp");
|
||||||
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
rv = scp_context_parse_config();
|
||||||
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
rv = ogs_log_config_domain(
|
||||||
|
ogs_app()->logger.domain, ogs_app()->logger.level);
|
||||||
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
|
rv = scp_sbi_open();
|
||||||
|
if (rv != 0) return OGS_ERROR;
|
||||||
|
|
||||||
|
thread = ogs_thread_create(scp_main, NULL);
|
||||||
|
if (!thread) return OGS_ERROR;
|
||||||
|
|
||||||
|
initialized = 1;
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ogs_timer_t *t_termination_holding = NULL;
|
||||||
|
|
||||||
|
static void event_termination(void)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
/* Sending NF Instance De-registeration to NRF */
|
||||||
|
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance)
|
||||||
|
scp_nf_fsm_fini(nf_instance);
|
||||||
|
|
||||||
|
/* Starting holding timer */
|
||||||
|
t_termination_holding = ogs_timer_add(ogs_app()->timer_mgr, NULL, NULL);
|
||||||
|
ogs_assert(t_termination_holding);
|
||||||
|
#define TERMINATION_HOLDING_TIME ogs_time_from_msec(300)
|
||||||
|
ogs_timer_start(t_termination_holding, TERMINATION_HOLDING_TIME);
|
||||||
|
|
||||||
|
/* Sending termination event to the queue */
|
||||||
|
ogs_queue_term(ogs_app()->queue);
|
||||||
|
ogs_pollset_notify(ogs_app()->pollset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_terminate(void)
|
||||||
|
{
|
||||||
|
if (!initialized) return;
|
||||||
|
|
||||||
|
/* Daemon terminating */
|
||||||
|
event_termination();
|
||||||
|
ogs_thread_destroy(thread);
|
||||||
|
ogs_timer_delete(t_termination_holding);
|
||||||
|
|
||||||
|
scp_sbi_close();
|
||||||
|
|
||||||
|
scp_context_final();
|
||||||
|
|
||||||
|
ogs_sbi_context_final();
|
||||||
|
|
||||||
|
scp_event_final(); /* Destroy event */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scp_main(void *data)
|
||||||
|
{
|
||||||
|
ogs_fsm_t scp_sm;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
ogs_fsm_create(&scp_sm, scp_state_initial, scp_state_final);
|
||||||
|
ogs_fsm_init(&scp_sm, 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 ( ;; ) {
|
||||||
|
scp_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(&scp_sm, e);
|
||||||
|
scp_event_free(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
|
||||||
|
ogs_fsm_fini(&scp_sm, 0);
|
||||||
|
ogs_fsm_delete(&scp_sm);
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
|
||||||
|
# This file is part of Open5GS.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
libscp_sources = files('''
|
||||||
|
context.c
|
||||||
|
event.c
|
||||||
|
timer.c
|
||||||
|
|
||||||
|
nnrf-build.c
|
||||||
|
nnrf-handler.c
|
||||||
|
nf-sm.c
|
||||||
|
|
||||||
|
nscp-handler.c
|
||||||
|
|
||||||
|
sbi-path.c
|
||||||
|
scp-sm.c
|
||||||
|
|
||||||
|
init.c
|
||||||
|
'''.split())
|
||||||
|
|
||||||
|
libscp = static_library('scp',
|
||||||
|
sources : libscp_sources,
|
||||||
|
dependencies : [libapp_dep,
|
||||||
|
libcrypt_dep,
|
||||||
|
libsbi_dep],
|
||||||
|
install : false)
|
||||||
|
|
||||||
|
libscp_dep = declare_dependency(
|
||||||
|
link_with : libscp,
|
||||||
|
dependencies : [libapp_dep,
|
||||||
|
libcrypt_dep,
|
||||||
|
libsbi_dep])
|
||||||
|
|
||||||
|
scp_sources = files('''
|
||||||
|
app.c
|
||||||
|
../main.c
|
||||||
|
'''.split())
|
||||||
|
|
||||||
|
executable('open5gs-scpd',
|
||||||
|
sources : scp_sources,
|
||||||
|
c_args : '-DDEFAULT_CONFIG_FILENAME="@0@/scp.yaml"'.format(open5gs_sysconfdir),
|
||||||
|
include_directories : srcinc,
|
||||||
|
dependencies : libscp_dep,
|
||||||
|
install_rpath : libdir,
|
||||||
|
install : true)
|
|
@ -0,0 +1,442 @@
|
||||||
|
/*
|
||||||
|
* 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 "context.h"
|
||||||
|
|
||||||
|
#include "sbi-path.h"
|
||||||
|
#include "nnrf-handler.h"
|
||||||
|
|
||||||
|
void scp_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
|
{
|
||||||
|
scp_event_t e;
|
||||||
|
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
memset(&e, 0, sizeof(e));
|
||||||
|
e.sbi.data = nf_instance;
|
||||||
|
|
||||||
|
ogs_fsm_create(&nf_instance->sm,
|
||||||
|
scp_nf_state_initial, scp_nf_state_final);
|
||||||
|
ogs_fsm_init(&nf_instance->sm, &e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance)
|
||||||
|
{
|
||||||
|
scp_event_t e;
|
||||||
|
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
memset(&e, 0, sizeof(e));
|
||||||
|
e.sbi.data = nf_instance;
|
||||||
|
|
||||||
|
ogs_fsm_fini(&nf_instance->sm, &e);
|
||||||
|
ogs_fsm_delete(&nf_instance->sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_state_initial(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
ogs_assert(s);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
nf_instance->t_registration_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
scp_timer_nf_instance_registration_interval, nf_instance);
|
||||||
|
ogs_assert(nf_instance->t_registration_interval);
|
||||||
|
nf_instance->t_heartbeat_interval = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
scp_timer_nf_instance_heartbeat_interval, nf_instance);
|
||||||
|
ogs_assert(nf_instance->t_heartbeat_interval);
|
||||||
|
nf_instance->t_no_heartbeat = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
scp_timer_nf_instance_no_heartbeat, nf_instance);
|
||||||
|
ogs_assert(nf_instance->t_no_heartbeat);
|
||||||
|
nf_instance->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
scp_timer_nf_instance_validity, nf_instance);
|
||||||
|
ogs_assert(nf_instance->t_validity);
|
||||||
|
|
||||||
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_will_register);
|
||||||
|
} else {
|
||||||
|
ogs_assert(nf_instance->id);
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_registered);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_state_final(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
ogs_assert(s);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
ogs_timer_delete(nf_instance->t_registration_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_delete(nf_instance->t_no_heartbeat);
|
||||||
|
ogs_timer_delete(nf_instance->t_validity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_state_will_register(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
ogs_sbi_message_t *message = NULL;
|
||||||
|
ogs_sockaddr_t *addr = NULL;
|
||||||
|
|
||||||
|
ogs_assert(s);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(ogs_sbi_self()->nf_instance);
|
||||||
|
ogs_assert(NF_INSTANCE_IS_NRF(nf_instance));
|
||||||
|
|
||||||
|
switch (e->id) {
|
||||||
|
case OGS_FSM_ENTRY_SIG:
|
||||||
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, scp_nnrf_nfm_build_register));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
ogs_timer_stop(nf_instance->t_registration_interval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_CLIENT:
|
||||||
|
message = e->sbi.message;
|
||||||
|
ogs_assert(message);
|
||||||
|
|
||||||
|
SWITCH(message->h.service.name)
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
||||||
|
|
||||||
|
SWITCH(message->h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||||
|
|
||||||
|
if (message->res_status == OGS_SBI_HTTP_STATUS_OK ||
|
||||||
|
message->res_status == OGS_SBI_HTTP_STATUS_CREATED) {
|
||||||
|
scp_nnrf_handle_nf_register(nf_instance, message);
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_registered);
|
||||||
|
} else {
|
||||||
|
ogs_error("[%s] HTTP Response Status Code [%d]",
|
||||||
|
ogs_sbi_self()->nf_instance->id,
|
||||||
|
message->res_status);
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_exception);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("[%s] Invalid resource name [%s]",
|
||||||
|
ogs_sbi_self()->nf_instance->id,
|
||||||
|
message->h.resource.component[0]);
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("[%s] Invalid API name [%s]",
|
||||||
|
ogs_sbi_self()->nf_instance->id, message->h.service.name);
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_TIMER:
|
||||||
|
switch(e->timer_id) {
|
||||||
|
case SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
addr = client->node.addr;
|
||||||
|
ogs_assert(addr);
|
||||||
|
|
||||||
|
ogs_warn("[%s] Retry to registration with NRF",
|
||||||
|
ogs_sbi_self()->nf_instance->id);
|
||||||
|
|
||||||
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
|
ogs_app()->time.message.sbi.nf_register_interval);
|
||||||
|
|
||||||
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_register(
|
||||||
|
nf_instance, scp_nnrf_nfm_build_register));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s] Unknown timer[%s:%d]",
|
||||||
|
ogs_sbi_self()->nf_instance->id,
|
||||||
|
scp_timer_get_name(e->timer_id), e->timer_id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s] Unknown event %s",
|
||||||
|
ogs_sbi_self()->nf_instance->id, scp_event_get_name(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_state_registered(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
ogs_sbi_message_t *message = NULL;
|
||||||
|
ogs_assert(s);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(ogs_sbi_self()->nf_instance);
|
||||||
|
|
||||||
|
switch (e->id) {
|
||||||
|
case OGS_FSM_ENTRY_SIG:
|
||||||
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
|
ogs_info("[%s] NF registered [Heartbeat:%ds]",
|
||||||
|
ogs_sbi_self()->nf_instance->id,
|
||||||
|
nf_instance->time.heartbeat_interval);
|
||||||
|
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
if (nf_instance->time.heartbeat_interval) {
|
||||||
|
ogs_timer_start(nf_instance->t_heartbeat_interval,
|
||||||
|
ogs_time_from_sec(nf_instance->time.heartbeat_interval));
|
||||||
|
ogs_timer_start(nf_instance->t_no_heartbeat,
|
||||||
|
ogs_time_from_sec(
|
||||||
|
nf_instance->time.heartbeat_interval +
|
||||||
|
ogs_app()->time.nf_instance.no_heartbeat_margin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
|
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
|
||||||
|
|
||||||
|
if (nf_instance->time.heartbeat_interval) {
|
||||||
|
ogs_timer_stop(nf_instance->t_heartbeat_interval);
|
||||||
|
ogs_timer_stop(nf_instance->t_no_heartbeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!OGS_FSM_CHECK(&nf_instance->sm, scp_nf_state_exception)) {
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_nnrf_nfm_send_nf_de_register(nf_instance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_CLIENT:
|
||||||
|
message = e->sbi.message;
|
||||||
|
ogs_assert(message);
|
||||||
|
|
||||||
|
SWITCH(message->h.service.name)
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
||||||
|
|
||||||
|
SWITCH(message->h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||||
|
|
||||||
|
if (message->res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT ||
|
||||||
|
message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||||||
|
if (nf_instance->time.heartbeat_interval)
|
||||||
|
ogs_timer_start(nf_instance->t_no_heartbeat,
|
||||||
|
ogs_time_from_sec(
|
||||||
|
nf_instance->time.heartbeat_interval +
|
||||||
|
ogs_app()->time.nf_instance.
|
||||||
|
no_heartbeat_margin));
|
||||||
|
} else {
|
||||||
|
ogs_warn("[%s] HTTP response error [%d]",
|
||||||
|
ogs_sbi_self()->nf_instance->id,
|
||||||
|
message->res_status);
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("[%s] Invalid resource name [%s]",
|
||||||
|
ogs_sbi_self()->nf_instance->id,
|
||||||
|
message->h.resource.component[0]);
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("[%s] Invalid API name [%s]",
|
||||||
|
ogs_sbi_self()->nf_instance->id, message->h.service.name);
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_TIMER:
|
||||||
|
switch(e->timer_id) {
|
||||||
|
case SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
|
||||||
|
if (nf_instance->time.heartbeat_interval)
|
||||||
|
ogs_timer_start(nf_instance->t_heartbeat_interval,
|
||||||
|
ogs_time_from_sec(nf_instance->time.heartbeat_interval));
|
||||||
|
|
||||||
|
ogs_assert(true == ogs_nnrf_nfm_send_nf_update(nf_instance));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT:
|
||||||
|
ogs_error("[%s] No heartbeat", ogs_sbi_self()->nf_instance->id);
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_will_register);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_TIMER_NF_INSTANCE_VALIDITY:
|
||||||
|
ogs_assert(!NF_INSTANCE_IS_NRF(nf_instance));
|
||||||
|
ogs_assert(nf_instance->id);
|
||||||
|
|
||||||
|
ogs_info("[%s] NF expired", nf_instance->id);
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_de_registered);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s:%s] Unknown timer[%s:%d]",
|
||||||
|
OpenAPI_nf_type_ToString(nf_instance->nf_type),
|
||||||
|
nf_instance->id ? nf_instance->id : "Undefined",
|
||||||
|
scp_timer_get_name(e->timer_id), e->timer_id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s:%s] Unknown event %s",
|
||||||
|
OpenAPI_nf_type_ToString(nf_instance->nf_type),
|
||||||
|
nf_instance->id ? nf_instance->id : "Undefined",
|
||||||
|
scp_event_get_name(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_state_de_registered(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
ogs_assert(s);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(ogs_sbi_self()->nf_instance);
|
||||||
|
|
||||||
|
switch (e->id) {
|
||||||
|
case OGS_FSM_ENTRY_SIG:
|
||||||
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
|
ogs_info("[%s] NF de-registered", ogs_sbi_self()->nf_instance->id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s:%s] Unknown event %s",
|
||||||
|
OpenAPI_nf_type_ToString(nf_instance->nf_type),
|
||||||
|
nf_instance->id ? nf_instance->id : "Undefined",
|
||||||
|
scp_event_get_name(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nf_state_exception(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
ogs_sbi_message_t *message = NULL;
|
||||||
|
ogs_sockaddr_t *addr = NULL;
|
||||||
|
ogs_assert(s);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(ogs_sbi_self()->nf_instance);
|
||||||
|
|
||||||
|
switch (e->id) {
|
||||||
|
case OGS_FSM_ENTRY_SIG:
|
||||||
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
|
ogs_timer_start(nf_instance->t_registration_interval,
|
||||||
|
ogs_app()->time.message.sbi.
|
||||||
|
nf_register_interval_in_exception);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
if (NF_INSTANCE_IS_NRF(nf_instance)) {
|
||||||
|
ogs_timer_stop(nf_instance->t_registration_interval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_TIMER:
|
||||||
|
switch(e->timer_id) {
|
||||||
|
case SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
addr = client->node.addr;
|
||||||
|
ogs_assert(addr);
|
||||||
|
|
||||||
|
ogs_warn("[%s] Retry to registration with NRF",
|
||||||
|
ogs_sbi_self()->nf_instance->id);
|
||||||
|
|
||||||
|
OGS_FSM_TRAN(s, &scp_nf_state_will_register);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s:%s] Unknown timer[%s:%d]",
|
||||||
|
OpenAPI_nf_type_ToString(nf_instance->nf_type),
|
||||||
|
nf_instance->id ? nf_instance->id : "Undefined",
|
||||||
|
scp_timer_get_name(e->timer_id), e->timer_id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_CLIENT:
|
||||||
|
message = e->sbi.message;
|
||||||
|
ogs_assert(message);
|
||||||
|
|
||||||
|
SWITCH(message->h.service.name)
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
||||||
|
|
||||||
|
SWITCH(message->h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||||
|
break;
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
message->h.resource.component[0]);
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid API name [%s]", message->h.service.name);
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("[%s:%s] Unknown event %s",
|
||||||
|
OpenAPI_nf_type_ToString(nf_instance->nf_type),
|
||||||
|
nf_instance->id ? nf_instance->id : "Undefined",
|
||||||
|
scp_event_get_name(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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 "nnrf-build.h"
|
||||||
|
|
||||||
|
ogs_sbi_request_t *scp_nnrf_nfm_build_register(void)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
ogs_sbi_message_t message;
|
||||||
|
ogs_sbi_request_t *request = NULL;
|
||||||
|
|
||||||
|
OpenAPI_nf_profile_t *NFProfile = NULL;
|
||||||
|
|
||||||
|
nf_instance = ogs_sbi_self()->nf_instance;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(nf_instance->id);
|
||||||
|
|
||||||
|
memset(&message, 0, sizeof(message));
|
||||||
|
message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
|
||||||
|
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM;
|
||||||
|
message.h.api.version = (char *)OGS_SBI_API_V1;
|
||||||
|
message.h.resource.component[0] =
|
||||||
|
(char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
|
||||||
|
message.h.resource.component[1] = nf_instance->id;
|
||||||
|
|
||||||
|
message.http.content_encoding = (char*)ogs_sbi_self()->content_encoding;
|
||||||
|
|
||||||
|
NFProfile = ogs_nnrf_nfm_build_nf_profile();
|
||||||
|
ogs_expect_or_return_val(NFProfile, NULL);
|
||||||
|
|
||||||
|
message.NFProfile = NFProfile;
|
||||||
|
|
||||||
|
request = ogs_sbi_build_request(&message);
|
||||||
|
|
||||||
|
ogs_sbi_nnrf_free_nf_profile(NFProfile);
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_NNRF_BUILD_H
|
||||||
|
#define SCP_NNRF_BUILD_H
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ogs_sbi_request_t *scp_nnrf_nfm_build_register(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_NNRF_BUILD_H */
|
|
@ -0,0 +1,348 @@
|
||||||
|
/*
|
||||||
|
* 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 "sbi-path.h"
|
||||||
|
#include "nnrf-handler.h"
|
||||||
|
|
||||||
|
void scp_nnrf_handle_nf_register(
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg)
|
||||||
|
{
|
||||||
|
OpenAPI_nf_profile_t *NFProfile = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
ogs_assert(recvmsg);
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
NFProfile = recvmsg->NFProfile;
|
||||||
|
if (!NFProfile) {
|
||||||
|
ogs_error("No NFProfile");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TIME : Update heartbeat from NRF */
|
||||||
|
if (NFProfile->is_heart_beat_timer == true)
|
||||||
|
nf_instance->time.heartbeat_interval = NFProfile->heart_beat_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nnrf_handle_nf_status_subscribe(
|
||||||
|
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg)
|
||||||
|
{
|
||||||
|
OpenAPI_subscription_data_t *SubscriptionData = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
ogs_assert(recvmsg);
|
||||||
|
ogs_assert(subscription);
|
||||||
|
client = subscription->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
SubscriptionData = recvmsg->SubscriptionData;
|
||||||
|
if (!SubscriptionData) {
|
||||||
|
ogs_error("No SubscriptionData");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SubscriptionData->subscription_id) {
|
||||||
|
ogs_error("No SubscriptionId");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ogs_sbi_subscription_set_id(
|
||||||
|
subscription, SubscriptionData->subscription_id);
|
||||||
|
|
||||||
|
if (SubscriptionData->validity_time) {
|
||||||
|
#define VALIDITY_MINIMUM (10LL * OGS_USEC_PER_SEC) /* 10 seconds */
|
||||||
|
ogs_time_t time, duration;
|
||||||
|
if (ogs_sbi_time_from_string(
|
||||||
|
&time, SubscriptionData->validity_time) == true) {
|
||||||
|
duration = time - ogs_time_now();
|
||||||
|
if (duration < VALIDITY_MINIMUM) {
|
||||||
|
duration = VALIDITY_MINIMUM;
|
||||||
|
ogs_warn("[%s] Forced to %lld seconds", subscription->id,
|
||||||
|
(long long)ogs_time_sec(VALIDITY_MINIMUM));
|
||||||
|
}
|
||||||
|
subscription->t_validity = ogs_timer_add(ogs_app()->timer_mgr,
|
||||||
|
scp_timer_subscription_validity, subscription);
|
||||||
|
ogs_assert(subscription->t_validity);
|
||||||
|
ogs_timer_start(subscription->t_validity, duration);
|
||||||
|
} else {
|
||||||
|
ogs_error("Cannot parse validitiyTime [%s]",
|
||||||
|
SubscriptionData->validity_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool scp_nnrf_handle_nf_status_notify(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
bool handled;
|
||||||
|
|
||||||
|
ogs_sbi_response_t *response = NULL;
|
||||||
|
OpenAPI_notification_data_t *NotificationData = NULL;
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
ogs_sbi_message_t message;
|
||||||
|
ogs_sbi_header_t header;
|
||||||
|
|
||||||
|
ogs_assert(stream);
|
||||||
|
ogs_assert(recvmsg);
|
||||||
|
|
||||||
|
NotificationData = recvmsg->NotificationData;
|
||||||
|
if (!NotificationData) {
|
||||||
|
ogs_error("No NotificationData");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "No NotificationData", NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NotificationData->nf_instance_uri) {
|
||||||
|
ogs_error("No nfInstanceUri");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "No nfInstanceUri", NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&header, 0, sizeof(header));
|
||||||
|
header.uri = NotificationData->nf_instance_uri;
|
||||||
|
|
||||||
|
rv = ogs_sbi_parse_header(&message, &header);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("Cannot parse nfInstanceUri [%s]", header.uri);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "Cannot parse nfInstanceUri", header.uri));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!message.h.resource.component[1]) {
|
||||||
|
ogs_error("No nfInstanceId [%s]", header.uri);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "Cannot parse nfInstanceUri", header.uri));
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NF_INSTANCE_IS_SELF(message.h.resource.component[1])) {
|
||||||
|
ogs_warn("[%s] The notification is not allowed",
|
||||||
|
message.h.resource.component[1]);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_FORBIDDEN,
|
||||||
|
recvmsg, "The notification is not allowed",
|
||||||
|
message.h.resource.component[1]));
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NotificationData->event ==
|
||||||
|
OpenAPI_notification_event_type_NF_REGISTERED) {
|
||||||
|
|
||||||
|
OpenAPI_nf_profile_t *NFProfile = NULL;
|
||||||
|
|
||||||
|
NFProfile = NotificationData->nf_profile;
|
||||||
|
if (!NFProfile) {
|
||||||
|
ogs_error("No NFProfile");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "No NFProfile", NULL));
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
|
||||||
|
if (!nf_instance) {
|
||||||
|
nf_instance = ogs_sbi_nf_instance_add();
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_sbi_nf_instance_set_id(nf_instance,
|
||||||
|
message.h.resource.component[1]);
|
||||||
|
|
||||||
|
scp_nf_fsm_init(nf_instance);
|
||||||
|
|
||||||
|
ogs_info("[%s] (NRF-notify) NF registered", nf_instance->id);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nf_instance->reference_count++;
|
||||||
|
|
||||||
|
OGS_FSM_TRAN(&nf_instance->sm, scp_nf_state_registered);
|
||||||
|
ogs_fsm_dispatch(&nf_instance->sm, NULL);
|
||||||
|
|
||||||
|
ogs_warn("[%s] (NRF-notify) NF has already been added",
|
||||||
|
message.h.resource.component[1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = ogs_sbi_nnrf_handle_nf_profile(
|
||||||
|
nf_instance, NFProfile, stream, recvmsg);
|
||||||
|
if (!handled) {
|
||||||
|
SCP_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_info("[%s] (NRF-notify) NF Profile updated", nf_instance->id);
|
||||||
|
|
||||||
|
handled = ogs_sbi_client_associate(nf_instance);
|
||||||
|
if (!handled) {
|
||||||
|
ogs_error("[%s] Cannot associate NF EndPoint", nf_instance->id);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "Cannot find NF EndPoint", nf_instance->id));
|
||||||
|
SCP_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (NotificationData->event ==
|
||||||
|
OpenAPI_notification_event_type_NF_DEREGISTERED) {
|
||||||
|
nf_instance = ogs_sbi_nf_instance_find(message.h.resource.component[1]);
|
||||||
|
if (nf_instance) {
|
||||||
|
SCP_NF_INSTANCE_CLEAR("NRF-notify", nf_instance);
|
||||||
|
} else {
|
||||||
|
ogs_warn("[%s] (NRF-notify) Not found",
|
||||||
|
message.h.resource.component[1]);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_NOT_FOUND,
|
||||||
|
recvmsg, "Not found", message.h.resource.component[1]));
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char *eventstr = OpenAPI_notification_event_type_ToString(
|
||||||
|
NotificationData->event);
|
||||||
|
ogs_error("Not supported event [%d:%s]",
|
||||||
|
NotificationData->event, eventstr ? eventstr : "Unknown");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg, "Not supported event",
|
||||||
|
eventstr ? eventstr : "Unknown"));
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = ogs_sbi_build_response(recvmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
|
||||||
|
ogs_assert(response);
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
|
||||||
|
|
||||||
|
ogs_sbi_header_free(&header);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_nnrf_handle_nf_discover(
|
||||||
|
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
|
||||||
|
{
|
||||||
|
ogs_sbi_object_t *sbi_object = NULL;
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
OpenAPI_search_result_t *SearchResult = NULL;
|
||||||
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
bool handled;
|
||||||
|
|
||||||
|
ogs_assert(xact);
|
||||||
|
sbi_object = xact->sbi_object;
|
||||||
|
ogs_assert(sbi_object);
|
||||||
|
ogs_assert(recvmsg);
|
||||||
|
|
||||||
|
SearchResult = recvmsg->SearchResult;
|
||||||
|
if (!SearchResult) {
|
||||||
|
ogs_error("No SearchResult");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(SearchResult->nf_instances, node) {
|
||||||
|
OpenAPI_nf_profile_t *NFProfile = NULL;
|
||||||
|
|
||||||
|
if (!node->data) continue;
|
||||||
|
|
||||||
|
NFProfile = node->data;
|
||||||
|
|
||||||
|
nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id);
|
||||||
|
if (!nf_instance) {
|
||||||
|
nf_instance = ogs_sbi_nf_instance_add();
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_sbi_nf_instance_set_id(nf_instance, NFProfile->nf_instance_id);
|
||||||
|
|
||||||
|
scp_nf_fsm_init(nf_instance);
|
||||||
|
|
||||||
|
ogs_info("[%s] (NF-discover) NF registered", nf_instance->id);
|
||||||
|
} else {
|
||||||
|
nf_instance->reference_count++;
|
||||||
|
|
||||||
|
OGS_FSM_TRAN(&nf_instance->sm, scp_nf_state_registered);
|
||||||
|
ogs_fsm_dispatch(&nf_instance->sm, NULL);
|
||||||
|
|
||||||
|
ogs_warn("[%s] (NF-discover) NF has already been added",
|
||||||
|
NFProfile->nf_instance_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NF_INSTANCE_IS_OTHERS(nf_instance->id)) {
|
||||||
|
scp_conn_t *conn = NULL;
|
||||||
|
|
||||||
|
handled = ogs_sbi_nnrf_handle_nf_profile(
|
||||||
|
nf_instance, NFProfile, NULL, NULL);
|
||||||
|
if (!handled) {
|
||||||
|
ogs_error("ogs_sbi_nnrf_handle_nf_profile() failed [%s]",
|
||||||
|
nf_instance->id);
|
||||||
|
SCP_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = ogs_sbi_client_associate(nf_instance);
|
||||||
|
if (!handled) {
|
||||||
|
ogs_error("[%s] Cannot assciate NF EndPoint", nf_instance->id);
|
||||||
|
SCP_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = (scp_conn_t *)sbi_object;
|
||||||
|
ogs_assert(conn);
|
||||||
|
scp_conn_select_nf(conn, nf_instance->nf_type);
|
||||||
|
|
||||||
|
/* TIME : Update validity from NRF */
|
||||||
|
if (SearchResult->is_validity_period &&
|
||||||
|
SearchResult->validity_period) {
|
||||||
|
nf_instance->time.validity_duration =
|
||||||
|
SearchResult->validity_period;
|
||||||
|
|
||||||
|
ogs_assert(nf_instance->t_validity);
|
||||||
|
ogs_timer_start(nf_instance->t_validity,
|
||||||
|
ogs_time_from_sec(nf_instance->time.validity_duration));
|
||||||
|
|
||||||
|
} else
|
||||||
|
ogs_warn("[%s] NF Instance validity-time should not 0",
|
||||||
|
nf_instance->id);
|
||||||
|
|
||||||
|
ogs_info("[%s] (NF-discover) NF Profile updated", nf_instance->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_assert(xact->target_nf_type);
|
||||||
|
nf_instance = OGS_SBI_NF_INSTANCE(sbi_object, xact->target_nf_type);
|
||||||
|
if (!nf_instance) {
|
||||||
|
ogs_error("(NF discover) No [%s]",
|
||||||
|
OpenAPI_nf_type_ToString(xact->target_nf_type));
|
||||||
|
} else {
|
||||||
|
scp_sbi_send(nf_instance, xact);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_NNRF_HANDLER_H
|
||||||
|
#define SCP_NNRF_HANDLER_H
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void scp_nnrf_handle_nf_register(
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg);
|
||||||
|
void scp_nnrf_handle_nf_status_subscribe(
|
||||||
|
ogs_sbi_subscription_t *subscription, ogs_sbi_message_t *recvmsg);
|
||||||
|
|
||||||
|
bool scp_nnrf_handle_nf_status_notify(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
||||||
|
|
||||||
|
void scp_nnrf_handle_nf_discover(
|
||||||
|
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_NNRF_HANDLER_H */
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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 "sbi-path.h"
|
||||||
|
#include "nscp-handler.h"
|
||||||
|
|
||||||
|
bool scp_nscp_management_handle_pcf_binding(
|
||||||
|
scp_conn_t *conn, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_NSCP_HANDLER_H
|
||||||
|
#define SCP_NSCP_HANDLER_H
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool scp_nscp_management_handle_pcf_binding(
|
||||||
|
scp_conn_t *conn, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_NSCP_HANDLER_H */
|
|
@ -0,0 +1,410 @@
|
||||||
|
/*
|
||||||
|
* 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 "sbi-path.h"
|
||||||
|
|
||||||
|
static int request_handler(ogs_sbi_request_t *request, void *data);
|
||||||
|
static int response_handler(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data);
|
||||||
|
|
||||||
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data);
|
||||||
|
|
||||||
|
int scp_sbi_open(void)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
|
||||||
|
if (ogs_sbi_server_start_all(request_handler) != OGS_OK)
|
||||||
|
return OGS_ERROR;
|
||||||
|
|
||||||
|
/* Add SELF NF instance */
|
||||||
|
nf_instance = ogs_sbi_self()->nf_instance;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
|
||||||
|
/* Build NF instance information. It will be transmitted to NRF. */
|
||||||
|
ogs_sbi_nf_instance_build_default(nf_instance, OpenAPI_nf_type_SCP);
|
||||||
|
|
||||||
|
/* Initialize SCP NF Instance */
|
||||||
|
nf_instance = ogs_sbi_self()->scp_instance;
|
||||||
|
if (nf_instance) {
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
/* Client callback is only used when NF sends to SCP */
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
client->cb = client_cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize NRF NF Instance */
|
||||||
|
nf_instance = ogs_sbi_self()->nrf_instance;
|
||||||
|
if (nf_instance) {
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
|
/* Client callback is only used when NF sends to NRF */
|
||||||
|
client = nf_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
client->cb = client_cb;
|
||||||
|
|
||||||
|
/* NFRegister is sent and the response is received
|
||||||
|
* by the above client callback. */
|
||||||
|
scp_nf_fsm_init(nf_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_sbi_close(void)
|
||||||
|
{
|
||||||
|
ogs_sbi_client_stop_all();
|
||||||
|
ogs_sbi_server_stop_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int request_handler(ogs_sbi_request_t *source, void *data)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
ogs_hash_index_t *hi;
|
||||||
|
ogs_sbi_stream_t *stream = data;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *target_apiroot;
|
||||||
|
char *discovery;
|
||||||
|
char *accept;
|
||||||
|
char *content_type;
|
||||||
|
char *content_encoding;
|
||||||
|
} headers;
|
||||||
|
|
||||||
|
ogs_assert(source);
|
||||||
|
ogs_assert(source->h.uri);
|
||||||
|
ogs_assert(stream);
|
||||||
|
|
||||||
|
memset(&headers, 0, sizeof(headers));
|
||||||
|
|
||||||
|
/* Extract HTTP Header */
|
||||||
|
for (hi = ogs_hash_first(source->http.headers);
|
||||||
|
hi; hi = ogs_hash_next(hi)) {
|
||||||
|
char *key = (char *)ogs_hash_this_key(hi);
|
||||||
|
char *val = ogs_hash_this_val(hi);
|
||||||
|
|
||||||
|
if (!key || !val) {
|
||||||
|
ogs_error("No Key[%s] Value[%s]", key, val);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* <RFC 2616>
|
||||||
|
* Each header field consists of a name followed by a colon (":")
|
||||||
|
* and the field value. Field names are case-insensitive.
|
||||||
|
*/
|
||||||
|
if (!strcasecmp(key, OGS_SBI_CUSTOM_TARGET_APIROOT)) {
|
||||||
|
headers.target_apiroot = val;
|
||||||
|
} else if (!strncasecmp(key,
|
||||||
|
OGS_SBI_CUSTOM_DISCOVERY_COMMON,
|
||||||
|
strlen(OGS_SBI_CUSTOM_DISCOVERY_COMMON))) {
|
||||||
|
headers.discovery = val;
|
||||||
|
} else if (!strcasecmp(key, OGS_SBI_ACCEPT)) {
|
||||||
|
headers.accept = val;
|
||||||
|
} else if (!strcasecmp(key, OGS_SBI_CONTENT_TYPE)) {
|
||||||
|
headers.content_type = val;
|
||||||
|
} else if (!strcasecmp(key, OGS_SBI_ACCEPT_ENCODING)) {
|
||||||
|
headers.content_encoding = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers.target_apiroot) {
|
||||||
|
ogs_sbi_nf_instance_t *scp_instance = NULL;
|
||||||
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
ogs_sbi_request_t target;
|
||||||
|
|
||||||
|
scp_conn_t *conn = NULL;
|
||||||
|
|
||||||
|
memset(&target, 0, sizeof(target));
|
||||||
|
|
||||||
|
conn = scp_conn_add(stream);
|
||||||
|
if (!conn) {
|
||||||
|
ogs_error("scp_conn_add() failed");
|
||||||
|
ogs_sbi_request_free(source);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ogs_sbi_self()->discovery_config.delegated ==
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_AUTO) {
|
||||||
|
scp_instance = ogs_sbi_self()->scp_instance;
|
||||||
|
} else if (ogs_sbi_self()->discovery_config.delegated ==
|
||||||
|
OGS_SBI_DISCOVERY_DELEGATED_YES) {
|
||||||
|
scp_instance = ogs_sbi_self()->scp_instance;
|
||||||
|
ogs_assert(scp_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTTP Method */
|
||||||
|
target.h.method = source->h.method;
|
||||||
|
|
||||||
|
/* HTTP Headers
|
||||||
|
*
|
||||||
|
* To remove the followings,
|
||||||
|
* Scheme - https
|
||||||
|
* Authority - scp.open5gs.org
|
||||||
|
*
|
||||||
|
* We regenerate the HTTP Headers.
|
||||||
|
*/
|
||||||
|
target.http.headers = ogs_hash_make();
|
||||||
|
ogs_assert(target.http.headers);
|
||||||
|
|
||||||
|
if (headers.content_type)
|
||||||
|
ogs_sbi_header_set(target.http.headers,
|
||||||
|
OGS_SBI_CONTENT_TYPE, headers.content_type);
|
||||||
|
if (headers.accept)
|
||||||
|
ogs_sbi_header_set(target.http.headers,
|
||||||
|
OGS_SBI_ACCEPT, headers.accept);
|
||||||
|
if (headers.content_encoding)
|
||||||
|
ogs_sbi_header_set(target.http.headers,
|
||||||
|
OGS_SBI_ACCEPT_ENCODING, headers.content_encoding);
|
||||||
|
|
||||||
|
/* HTTP Params */
|
||||||
|
target.http.params = source->http.params;
|
||||||
|
|
||||||
|
/* HTTP Content */
|
||||||
|
target.http.content = source->http.content;
|
||||||
|
target.http.content_length = source->http.content_length;
|
||||||
|
|
||||||
|
if (scp_instance) {
|
||||||
|
char *apiroot = NULL;
|
||||||
|
|
||||||
|
if (headers.target_apiroot)
|
||||||
|
ogs_sbi_header_set(target.http.headers,
|
||||||
|
OGS_SBI_CUSTOM_TARGET_APIROOT, headers.target_apiroot);
|
||||||
|
|
||||||
|
/* Client Instance */
|
||||||
|
client = scp_instance->client;
|
||||||
|
ogs_assert(client);
|
||||||
|
|
||||||
|
/* Client ApiRoot */
|
||||||
|
apiroot = ogs_sbi_client_apiroot(client);
|
||||||
|
ogs_assert(apiroot);
|
||||||
|
|
||||||
|
/* Setup New URI */
|
||||||
|
target.h.uri = ogs_msprintf("%s%s", apiroot, source->h.uri);
|
||||||
|
ogs_assert(target.h.uri);
|
||||||
|
|
||||||
|
ogs_free(apiroot);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ogs_sockaddr_t *addr = NULL;
|
||||||
|
|
||||||
|
/* Find or Add Client Instance */
|
||||||
|
addr = ogs_sbi_getaddr_from_uri(headers.target_apiroot);
|
||||||
|
if (!addr) {
|
||||||
|
ogs_error("Invalid Target-apiRoot [%s]",
|
||||||
|
headers.target_apiroot);
|
||||||
|
ogs_sbi_http_hash_free(target.http.headers);
|
||||||
|
ogs_free(target.h.uri);
|
||||||
|
|
||||||
|
ogs_sbi_request_free(source);
|
||||||
|
scp_conn_remove(conn);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
client = ogs_sbi_client_find(addr);
|
||||||
|
if (!client) {
|
||||||
|
client = ogs_sbi_client_add(addr);
|
||||||
|
ogs_assert(client);
|
||||||
|
client->cb = client_cb;
|
||||||
|
}
|
||||||
|
OGS_SBI_SETUP_CLIENT(conn, client);
|
||||||
|
|
||||||
|
ogs_freeaddrinfo(addr);
|
||||||
|
|
||||||
|
/* Setup New URI */
|
||||||
|
target.h.uri = ogs_msprintf("%s%s",
|
||||||
|
headers.target_apiroot, source->h.uri);
|
||||||
|
ogs_assert(target.h.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the HTTP Request with New URI and HTTP Headers */
|
||||||
|
if (ogs_sbi_client_send_reqmem_persistent(
|
||||||
|
client, response_handler, &target, conn) != true) {
|
||||||
|
ogs_error("ogs_sbi_client_send_request() failed");
|
||||||
|
ogs_sbi_http_hash_free(target.http.headers);
|
||||||
|
ogs_free(target.h.uri);
|
||||||
|
|
||||||
|
ogs_sbi_request_free(source);
|
||||||
|
scp_conn_remove(conn);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_sbi_http_hash_free(target.http.headers);
|
||||||
|
ogs_free(target.h.uri);
|
||||||
|
|
||||||
|
} else if (headers.discovery) {
|
||||||
|
scp_event_t *e = NULL;
|
||||||
|
|
||||||
|
e = scp_event_new(SCP_EVT_SBI_SERVER);
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
e->sbi.request = source;
|
||||||
|
e->sbi.data = stream;
|
||||||
|
|
||||||
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_request_free(source);
|
||||||
|
scp_event_free(e);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ogs_sbi_message_t message;
|
||||||
|
|
||||||
|
ogs_error("Unknown HTTP Headers");
|
||||||
|
ogs_error(" [%s:%s]", source->h.method, source->h.uri);
|
||||||
|
for (hi = ogs_hash_first(source->http.headers);
|
||||||
|
hi; hi = ogs_hash_next(hi)) {
|
||||||
|
char *key = (char *)ogs_hash_this_key(hi);
|
||||||
|
char *val = ogs_hash_this_val(hi);
|
||||||
|
ogs_error(" [%s:%s]", key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = ogs_sbi_parse_request(&message, source);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("cannot parse HTTP sbi_message");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
NULL, "cannot parse HTTP sbi_message", NULL));
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
&message, "SCP - HTTP Client", NULL));
|
||||||
|
|
||||||
|
ogs_sbi_message_free(&message);
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int response_handler(
|
||||||
|
int status, ogs_sbi_response_t *response, void *data)
|
||||||
|
{
|
||||||
|
scp_conn_t *conn = data;
|
||||||
|
ogs_sbi_stream_t *stream = NULL;
|
||||||
|
|
||||||
|
ogs_assert(conn);
|
||||||
|
stream = conn->stream;
|
||||||
|
ogs_assert(stream);
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"response_handler() failed [%d]", status);
|
||||||
|
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL,
|
||||||
|
"response_handler() failed", NULL));
|
||||||
|
|
||||||
|
scp_conn_remove(conn);
|
||||||
|
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_assert(response);
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
|
||||||
|
scp_conn_remove(conn);
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int client_cb(int status, ogs_sbi_response_t *response, void *data)
|
||||||
|
{
|
||||||
|
scp_event_t *e = NULL;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (status != OGS_OK) {
|
||||||
|
ogs_log_message(
|
||||||
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
|
"client_cb() failed [%d]", status);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_assert(response);
|
||||||
|
|
||||||
|
e = scp_event_new(SCP_EVT_SBI_CLIENT);
|
||||||
|
ogs_assert(e);
|
||||||
|
e->sbi.response = response;
|
||||||
|
e->sbi.data = data;
|
||||||
|
|
||||||
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
scp_event_free(e);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool scp_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact)
|
||||||
|
{
|
||||||
|
return ogs_sbi_send(nf_instance, client_cb, xact);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool scp_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
|
scp_conn_t *conn, ogs_sbi_stream_t *stream, void *data,
|
||||||
|
ogs_sbi_request_t *(*build)(scp_conn_t *conn, void *data))
|
||||||
|
{
|
||||||
|
ogs_sbi_xact_t *xact = NULL;
|
||||||
|
|
||||||
|
ogs_assert(target_nf_type);
|
||||||
|
|
||||||
|
ogs_assert(conn);
|
||||||
|
ogs_assert(stream);
|
||||||
|
ogs_assert(build);
|
||||||
|
|
||||||
|
xact = ogs_sbi_xact_add(target_nf_type, &conn->sbi,
|
||||||
|
(ogs_sbi_build_f)build, conn, data,
|
||||||
|
scp_timer_sbi_client_wait_expire);
|
||||||
|
if (!xact) {
|
||||||
|
ogs_error("scp_sbi_discover_and_send() failed");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
|
||||||
|
"Cannot discover", NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
xact->assoc_stream = stream;
|
||||||
|
|
||||||
|
if (ogs_sbi_discover_and_send(xact,
|
||||||
|
(ogs_fsm_handler_t)scp_nf_state_registered, client_cb) != true) {
|
||||||
|
ogs_error("scp_sbi_discover_and_send() failed");
|
||||||
|
ogs_sbi_xact_remove(xact);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
|
||||||
|
"Cannot discover", NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -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 SCP_SBI_PATH_H
|
||||||
|
#define SCP_SBI_PATH_H
|
||||||
|
|
||||||
|
#include "nnrf-build.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int scp_sbi_open(void);
|
||||||
|
void scp_sbi_close(void);
|
||||||
|
|
||||||
|
bool scp_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
|
||||||
|
|
||||||
|
bool scp_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
|
||||||
|
scp_conn_t *conn, ogs_sbi_stream_t *stream, void *data,
|
||||||
|
ogs_sbi_request_t *(*build)(scp_conn_t *conn, void *data));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_SBI_PATH_H */
|
|
@ -0,0 +1,369 @@
|
||||||
|
/*
|
||||||
|
* 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 "sbi-path.h"
|
||||||
|
#include "nnrf-handler.h"
|
||||||
|
#include "nscp-handler.h"
|
||||||
|
|
||||||
|
void scp_state_initial(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
ogs_assert(s);
|
||||||
|
|
||||||
|
OGS_FSM_TRAN(s, &scp_state_operational);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_state_final(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
ogs_assert(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_state_operational(ogs_fsm_t *s, scp_event_t *e)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
ogs_sbi_stream_t *stream = NULL;
|
||||||
|
ogs_sbi_request_t *request = NULL;
|
||||||
|
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||||
|
ogs_sbi_subscription_t *subscription = NULL;
|
||||||
|
ogs_sbi_response_t *response = NULL;
|
||||||
|
ogs_sbi_message_t message;
|
||||||
|
ogs_sbi_xact_t *sbi_xact = NULL;
|
||||||
|
|
||||||
|
scp_sm_debug(e);
|
||||||
|
|
||||||
|
ogs_assert(s);
|
||||||
|
|
||||||
|
switch (e->id) {
|
||||||
|
case OGS_FSM_ENTRY_SIG:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OGS_FSM_EXIT_SIG:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_SERVER:
|
||||||
|
request = e->sbi.request;
|
||||||
|
ogs_assert(request);
|
||||||
|
stream = e->sbi.data;
|
||||||
|
ogs_assert(stream);
|
||||||
|
|
||||||
|
rv = ogs_sbi_parse_request(&message, request);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
/* 'sbi_message' buffer is released in ogs_sbi_parse_request() */
|
||||||
|
ogs_error("cannot parse HTTP sbi_message");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
NULL, "cannot parse HTTP sbi_message", NULL));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(message.h.api.version, OGS_SBI_API_V1) != 0) {
|
||||||
|
ogs_error("Not supported version [%s]", message.h.api.version);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
&message, "Not supported version", NULL));
|
||||||
|
ogs_sbi_message_free(&message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH(message.h.service.name)
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
||||||
|
|
||||||
|
SWITCH(message.h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
|
||||||
|
SWITCH(message.h.method)
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||||||
|
scp_nnrf_handle_nf_status_notify(stream, &message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_FORBIDDEN, &message,
|
||||||
|
"Invalid HTTP method", message.h.method));
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
message.h.resource.component[0]);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
||||||
|
"Invalid resource name",
|
||||||
|
message.h.resource.component[0]));
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NBSF_MANAGEMENT)
|
||||||
|
SWITCH(message.h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_PCF_BINDINGS)
|
||||||
|
if (message.h.resource.component[1]) {
|
||||||
|
sess = scp_sess_find_by_binding_id(
|
||||||
|
message.h.resource.component[1]);
|
||||||
|
} else {
|
||||||
|
SWITCH(message.h.method)
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||||||
|
if (message.PcfBinding &&
|
||||||
|
message.PcfBinding->snssai &&
|
||||||
|
message.PcfBinding->dnn) {
|
||||||
|
ogs_s_nssai_t s_nssai;
|
||||||
|
|
||||||
|
s_nssai.sst = message.PcfBinding->snssai->sst;
|
||||||
|
s_nssai.sd = ogs_s_nssai_sd_from_string(
|
||||||
|
message.PcfBinding->snssai->sd);
|
||||||
|
|
||||||
|
sess = scp_sess_find_by_snssai_and_dnn(
|
||||||
|
&s_nssai, message.PcfBinding->dnn);
|
||||||
|
if (!sess) {
|
||||||
|
sess = scp_sess_add_by_snssai_and_dnn(
|
||||||
|
&s_nssai, message.PcfBinding->dnn);
|
||||||
|
ogs_assert(sess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_GET)
|
||||||
|
if (!sess && message.param.ipv4addr)
|
||||||
|
sess = scp_sess_find_by_ipv4addr(
|
||||||
|
message.param.ipv4addr);
|
||||||
|
if (!sess && message.param.ipv6prefix)
|
||||||
|
sess = scp_sess_find_by_ipv6prefix(
|
||||||
|
message.param.ipv6prefix);
|
||||||
|
break;
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
||||||
|
END
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sess) {
|
||||||
|
ogs_error("Not found [%s]", message.h.uri);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_NOT_FOUND,
|
||||||
|
&message, "Not found", message.h.uri));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
scp_nscp_management_handle_pcf_binding(sess, stream, &message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
message.h.resource.component[0]);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
||||||
|
"Invalid resource name",
|
||||||
|
message.h.resource.component[0]));
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid API name [%s]", message.h.service.name);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &message,
|
||||||
|
"Invalid API name", message.h.service.name));
|
||||||
|
END
|
||||||
|
|
||||||
|
/* In lib/sbi/server.c, notify_completed() releases 'request' buffer. */
|
||||||
|
ogs_sbi_message_free(&message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_CLIENT:
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
response = e->sbi.response;
|
||||||
|
ogs_assert(response);
|
||||||
|
rv = ogs_sbi_parse_response(&message, response);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("cannot parse HTTP response");
|
||||||
|
ogs_sbi_message_free(&message);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(message.h.api.version, OGS_SBI_API_V1) != 0) {
|
||||||
|
ogs_error("Not supported version [%s]", message.h.api.version);
|
||||||
|
ogs_sbi_message_free(&message);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH(message.h.service.name)
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
|
||||||
|
|
||||||
|
SWITCH(message.h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||||
|
|
||||||
|
e->sbi.message = &message;
|
||||||
|
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||||
|
subscription = e->sbi.data;
|
||||||
|
ogs_assert(subscription);
|
||||||
|
|
||||||
|
SWITCH(message.h.method)
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||||||
|
if (message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
|
||||||
|
message.res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||||||
|
scp_nnrf_handle_nf_status_subscribe(
|
||||||
|
subscription, &message);
|
||||||
|
} else {
|
||||||
|
ogs_error("HTTP response error : %d",
|
||||||
|
message.res_status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_DELETE)
|
||||||
|
if (message.res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT) {
|
||||||
|
ogs_sbi_subscription_remove(subscription);
|
||||||
|
} else {
|
||||||
|
ogs_error("HTTP response error : %d",
|
||||||
|
message.res_status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
message.h.resource.component[0]);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
|
||||||
|
SWITCH(message.h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||||
|
sbi_xact = e->sbi.data;
|
||||||
|
ogs_assert(sbi_xact);
|
||||||
|
|
||||||
|
SWITCH(message.h.method)
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_GET)
|
||||||
|
if (message.res_status == OGS_SBI_HTTP_STATUS_OK)
|
||||||
|
scp_nnrf_handle_nf_discover(sbi_xact, &message);
|
||||||
|
else
|
||||||
|
ogs_error("HTTP response error [%d]",
|
||||||
|
message.res_status);
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid HTTP method [%s]", message.h.method);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
message.h.resource.component[0]);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid service name [%s]", message.h.service.name);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
|
||||||
|
ogs_sbi_message_free(&message);
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_EVT_SBI_TIMER:
|
||||||
|
ogs_assert(e);
|
||||||
|
|
||||||
|
switch(e->timer_id) {
|
||||||
|
case SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
|
||||||
|
case SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
|
||||||
|
case SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT:
|
||||||
|
case SCP_TIMER_NF_INSTANCE_VALIDITY:
|
||||||
|
nf_instance = e->sbi.data;
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
|
||||||
|
|
||||||
|
ogs_fsm_dispatch(&nf_instance->sm, e);
|
||||||
|
if (OGS_FSM_CHECK(&nf_instance->sm, scp_nf_state_exception))
|
||||||
|
ogs_error("[%s:%s] State machine exception [%d]",
|
||||||
|
OpenAPI_nf_type_ToString(nf_instance->nf_type),
|
||||||
|
nf_instance->id, e->timer_id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_TIMER_SUBSCRIPTION_VALIDITY:
|
||||||
|
subscription = e->sbi.data;
|
||||||
|
ogs_assert(subscription);
|
||||||
|
|
||||||
|
ogs_assert(ogs_sbi_self()->nf_instance);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client,
|
||||||
|
ogs_sbi_self()->nf_instance->nf_type,
|
||||||
|
subscription->req_nf_instance_id,
|
||||||
|
subscription->subscr_cond.nf_type));
|
||||||
|
|
||||||
|
ogs_info("Subscription validity expired [%s]", subscription->id);
|
||||||
|
ogs_sbi_subscription_remove(subscription);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCP_TIMER_SBI_CLIENT_WAIT:
|
||||||
|
sbi_xact = e->sbi.data;
|
||||||
|
ogs_assert(sbi_xact);
|
||||||
|
|
||||||
|
stream = sbi_xact->assoc_stream;
|
||||||
|
/* Here, we should not use ogs_assert(stream)
|
||||||
|
* since 'namf-comm' service has no an associated stream. */
|
||||||
|
|
||||||
|
ogs_sbi_xact_remove(sbi_xact);
|
||||||
|
|
||||||
|
ogs_error("Cannot receive SBI message");
|
||||||
|
if (stream) {
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
|
||||||
|
"Cannot receive SBI message", NULL));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("Unknown timer[%s:%d]",
|
||||||
|
scp_timer_get_name(e->timer_id), e->timer_id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ogs_error("No handler for event %s", scp_event_get_name(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_SM_H
|
||||||
|
#define SCP_SM_H
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void scp_state_initial(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_state_final(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_state_operational(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_state_exception(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
|
||||||
|
void scp_nf_fsm_init(ogs_sbi_nf_instance_t *nf_instance);
|
||||||
|
void scp_nf_fsm_fini(ogs_sbi_nf_instance_t *nf_instance);
|
||||||
|
|
||||||
|
void scp_nf_state_initial(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_nf_state_final(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_nf_state_will_register(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_nf_state_registered(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_nf_state_de_registered(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
void scp_nf_state_exception(ogs_fsm_t *s, scp_event_t *e);
|
||||||
|
|
||||||
|
#define scp_sm_debug(__pe) \
|
||||||
|
ogs_debug("%s(): %s", __func__, scp_event_get_name(__pe))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_SM_H */
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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 "timer.h"
|
||||||
|
#include "event.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
const char *scp_timer_get_name(scp_timer_e id)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
case SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
|
||||||
|
return "SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL";
|
||||||
|
case SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
|
||||||
|
return "SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL";
|
||||||
|
case SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT:
|
||||||
|
return "SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT";
|
||||||
|
case SCP_TIMER_NF_INSTANCE_VALIDITY:
|
||||||
|
return "SCP_TIMER_NF_INSTANCE_VALIDITY";
|
||||||
|
case SCP_TIMER_SUBSCRIPTION_VALIDITY:
|
||||||
|
return "SCP_TIMER_SUBSCRIPTION_VALIDITY";
|
||||||
|
case SCP_TIMER_SBI_CLIENT_WAIT:
|
||||||
|
return "SCP_TIMER_SBI_CLIENT_WAIT";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN_TIMER";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timer_send_event(int timer_id, void *data)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
scp_event_t *e = NULL;
|
||||||
|
ogs_assert(data);
|
||||||
|
|
||||||
|
switch (timer_id) {
|
||||||
|
case SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
|
||||||
|
case SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
|
||||||
|
case SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT:
|
||||||
|
case SCP_TIMER_NF_INSTANCE_VALIDITY:
|
||||||
|
case SCP_TIMER_SUBSCRIPTION_VALIDITY:
|
||||||
|
e = scp_event_new(SCP_EVT_SBI_TIMER);
|
||||||
|
ogs_assert(e);
|
||||||
|
e->timer_id = timer_id;
|
||||||
|
e->sbi.data = data;
|
||||||
|
break;
|
||||||
|
case SCP_TIMER_SBI_CLIENT_WAIT:
|
||||||
|
e = scp_event_new(SCP_EVT_SBI_TIMER);
|
||||||
|
if (!e) {
|
||||||
|
ogs_sbi_xact_t *sbi_xact = data;
|
||||||
|
ogs_assert(sbi_xact);
|
||||||
|
|
||||||
|
ogs_error("timer_send_event() failed");
|
||||||
|
ogs_sbi_xact_remove(sbi_xact);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e->timer_id = timer_id;
|
||||||
|
e->sbi.data = data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ogs_fatal("Unknown timer id[%d]", timer_id);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
||||||
|
(int)rv, scp_timer_get_name(e->timer_id));
|
||||||
|
scp_event_free(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_timer_nf_instance_registration_interval(void *data)
|
||||||
|
{
|
||||||
|
timer_send_event(SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_timer_nf_instance_heartbeat_interval(void *data)
|
||||||
|
{
|
||||||
|
timer_send_event(SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_timer_nf_instance_no_heartbeat(void *data)
|
||||||
|
{
|
||||||
|
timer_send_event(SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_timer_nf_instance_validity(void *data)
|
||||||
|
{
|
||||||
|
timer_send_event(SCP_TIMER_NF_INSTANCE_VALIDITY, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_timer_subscription_validity(void *data)
|
||||||
|
{
|
||||||
|
timer_send_event(SCP_TIMER_SUBSCRIPTION_VALIDITY, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scp_timer_sbi_client_wait_expire(void *data)
|
||||||
|
{
|
||||||
|
timer_send_event(SCP_TIMER_SBI_CLIENT_WAIT, data);
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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 SCP_TIMER_H
|
||||||
|
#define SCP_TIMER_H
|
||||||
|
|
||||||
|
#include "ogs-core.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* forward declaration */
|
||||||
|
typedef enum {
|
||||||
|
SCP_TIMER_BASE = 0,
|
||||||
|
|
||||||
|
SCP_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL,
|
||||||
|
SCP_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL,
|
||||||
|
SCP_TIMER_NF_INSTANCE_NO_HEARTBEAT,
|
||||||
|
SCP_TIMER_NF_INSTANCE_VALIDITY,
|
||||||
|
SCP_TIMER_SUBSCRIPTION_VALIDITY,
|
||||||
|
SCP_TIMER_SBI_CLIENT_WAIT,
|
||||||
|
|
||||||
|
MAX_NUM_OF_SCP_TIMER,
|
||||||
|
|
||||||
|
} scp_timer_e;
|
||||||
|
|
||||||
|
const char *scp_timer_get_name(scp_timer_e id);
|
||||||
|
|
||||||
|
void scp_timer_nf_instance_registration_interval(void *data);
|
||||||
|
void scp_timer_nf_instance_heartbeat_interval(void *data);
|
||||||
|
void scp_timer_nf_instance_no_heartbeat(void *data);
|
||||||
|
void scp_timer_nf_instance_validity(void *data);
|
||||||
|
void scp_timer_subscription_validity(void *data);
|
||||||
|
void scp_timer_sbi_client_wait_expire(void *data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SCP_TIMER_H */
|
|
@ -117,7 +117,7 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
sgwc_event_free(e);
|
sgwc_event_free(e);
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,8 @@ int sgwc_pfcp_send_bearer_to_modify_list(
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
|
|
||||||
|
xact->local_seid = sess->sgwc_sxa_seid;
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||||
h.seid = sess->sgwu_sxa_seid;
|
h.seid = sess->sgwu_sxa_seid;
|
||||||
|
@ -377,6 +379,7 @@ int sgwc_pfcp_send_session_report_response(
|
||||||
ogs_pfcp_header_t h;
|
ogs_pfcp_header_t h;
|
||||||
|
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
|
xact->local_seid = sess->sgwc_sxa_seid;
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
|
||||||
|
|
|
@ -316,7 +316,7 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
sgwc_event_free(e);
|
sgwc_event_free(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -689,6 +689,7 @@ void sgwc_s11_handle_create_bearer_response(
|
||||||
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
|
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
|
||||||
ogs_gtp2_uli_t uli;
|
ogs_gtp2_uli_t uli;
|
||||||
|
|
||||||
|
ogs_assert(sgwc_ue);
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
rsp = &message->create_bearer_response;
|
rsp = &message->create_bearer_response;
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
@ -715,30 +716,10 @@ void sgwc_s11_handle_create_bearer_response(
|
||||||
rv = ogs_gtp_xact_commit(s11_xact);
|
rv = ogs_gtp_xact_commit(s11_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
ogs_expect(rv == OGS_OK);
|
||||||
|
|
||||||
/************************
|
|
||||||
* Check SGWC-UE Context
|
|
||||||
************************/
|
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
||||||
|
|
||||||
if (!sgwc_ue) {
|
|
||||||
ogs_error("No Context in TEID");
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
||||||
ogs_assert(OGS_OK ==
|
|
||||||
sgwc_pfcp_send_bearer_modification_request(
|
|
||||||
bearer, NULL, NULL,
|
|
||||||
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************
|
/*****************************************
|
||||||
* Check Mandatory/Conditional IE Missing
|
* Check Mandatory/Conditional IE Missing
|
||||||
*****************************************/
|
*****************************************/
|
||||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (rsp->bearer_contexts.presence == 0) {
|
if (rsp->bearer_contexts.presence == 0) {
|
||||||
ogs_error("No Bearer");
|
ogs_error("No Bearer");
|
||||||
|
@ -873,6 +854,7 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
sgwc_bearer_t *bearer = NULL;
|
sgwc_bearer_t *bearer = NULL;
|
||||||
ogs_gtp2_update_bearer_response_t *rsp = NULL;
|
ogs_gtp2_update_bearer_response_t *rsp = NULL;
|
||||||
|
|
||||||
|
ogs_assert(sgwc_ue);
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
rsp = &message->update_bearer_response;
|
rsp = &message->update_bearer_response;
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
@ -899,26 +881,10 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
rv = ogs_gtp_xact_commit(s11_xact);
|
rv = ogs_gtp_xact_commit(s11_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
ogs_expect(rv == OGS_OK);
|
||||||
|
|
||||||
/************************
|
|
||||||
* Check SGWC-UE Context
|
|
||||||
************************/
|
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
||||||
|
|
||||||
if (!sgwc_ue) {
|
|
||||||
ogs_error("No Context in TEID");
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************
|
/*****************************************
|
||||||
* Check Mandatory/Conditional IE Missing
|
* Check Mandatory/Conditional IE Missing
|
||||||
*****************************************/
|
*****************************************/
|
||||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (rsp->bearer_contexts.presence == 0) {
|
if (rsp->bearer_contexts.presence == 0) {
|
||||||
ogs_error("No Bearer");
|
ogs_error("No Bearer");
|
||||||
|
@ -1005,6 +971,7 @@ void sgwc_s11_handle_delete_bearer_response(
|
||||||
sgwc_bearer_t *bearer = NULL;
|
sgwc_bearer_t *bearer = NULL;
|
||||||
ogs_gtp2_delete_bearer_response_t *rsp = NULL;
|
ogs_gtp2_delete_bearer_response_t *rsp = NULL;
|
||||||
|
|
||||||
|
ogs_assert(sgwc_ue);
|
||||||
ogs_assert(message);
|
ogs_assert(message);
|
||||||
rsp = &message->delete_bearer_response;
|
rsp = &message->delete_bearer_response;
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
@ -1036,11 +1003,6 @@ void sgwc_s11_handle_delete_bearer_response(
|
||||||
************************/
|
************************/
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (!sgwc_ue) {
|
|
||||||
ogs_error("No Context in TEID");
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp->linked_eps_bearer_id.presence) {
|
if (rsp->linked_eps_bearer_id.presence) {
|
||||||
/*
|
/*
|
||||||
* << Linked EPS Bearer ID >>
|
* << Linked EPS Bearer ID >>
|
||||||
|
@ -1112,10 +1074,8 @@ void sgwc_s11_handle_delete_bearer_response(
|
||||||
ogs_error("No Cause");
|
ogs_error("No Cause");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sgwc_ue) {
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
||||||
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
|
||||||
}
|
|
||||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||||
|
|
||||||
|
@ -1514,6 +1474,7 @@ void sgwc_s11_handle_bearer_resource_command(
|
||||||
s5c_xact = ogs_gtp_xact_local_create(
|
s5c_xact = ogs_gtp_xact_local_create(
|
||||||
sess->gnode, &message->h, pkbuf, gtp_bearer_timeout, bearer);
|
sess->gnode, &message->h, pkbuf, gtp_bearer_timeout, bearer);
|
||||||
ogs_expect_or_return(s5c_xact);
|
ogs_expect_or_return(s5c_xact);
|
||||||
|
s5c_xact->local_teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,9 @@ 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;
|
||||||
|
@ -96,30 +99,10 @@ 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
|
|
||||||
************************/
|
|
||||||
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
|
||||||
*****************************************/
|
*****************************************/
|
||||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
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");
|
||||||
|
@ -282,108 +265,6 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_ACTIVATE));
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_ACTIVATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sgwc_s5c_handle_delete_session_response(
|
|
||||||
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
|
||||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
ogs_gtp2_cause_t *cause = NULL;
|
|
||||||
uint8_t cause_value;
|
|
||||||
|
|
||||||
sgwc_ue_t *sgwc_ue = NULL;
|
|
||||||
|
|
||||||
ogs_gtp_xact_t *s11_xact = NULL;
|
|
||||||
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
|
||||||
|
|
||||||
ogs_assert(message);
|
|
||||||
rsp = &message->delete_session_response;
|
|
||||||
ogs_assert(rsp);
|
|
||||||
|
|
||||||
ogs_debug("Delete Session Response");
|
|
||||||
|
|
||||||
/********************
|
|
||||||
* Check Transaction
|
|
||||||
********************/
|
|
||||||
ogs_assert(s5c_xact);
|
|
||||||
s11_xact = s5c_xact->assoc_xact;
|
|
||||||
ogs_assert(s11_xact);
|
|
||||||
|
|
||||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
||||||
ogs_expect(rv == OGS_OK);
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* Check Session Context
|
|
||||||
************************/
|
|
||||||
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
|
|
||||||
*****************************************/
|
|
||||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
||||||
|
|
||||||
if (rsp->cause.presence == 0) {
|
|
||||||
ogs_error("No Cause");
|
|
||||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Cause Value
|
|
||||||
********************/
|
|
||||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
||||||
|
|
||||||
cause = rsp->cause.data;
|
|
||||||
ogs_assert(cause);
|
|
||||||
cause_value = cause->value;
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
||||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
|
||||||
ogs_gtp_send_error_message(
|
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************
|
|
||||||
* Check ALL Context
|
|
||||||
********************/
|
|
||||||
ogs_assert(sess);
|
|
||||||
ogs_assert(sgwc_ue);
|
|
||||||
|
|
||||||
/* Remove a pgw session */
|
|
||||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
||||||
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
|
||||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
|
||||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 1. MME sends Delete Session Request to SGW/SMF.
|
|
||||||
* 2. SMF sends Delete Session Response to SGW/MME.
|
|
||||||
*/
|
|
||||||
ogs_assert(OGS_OK ==
|
|
||||||
sgwc_pfcp_send_session_deletion_request(sess, s11_xact, gtpbuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
void sgwc_s5c_handle_modify_bearer_response(
|
void sgwc_s5c_handle_modify_bearer_response(
|
||||||
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
||||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||||
|
@ -399,6 +280,9 @@ 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);
|
||||||
|
@ -416,35 +300,10 @@ 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
|
|
||||||
************************/
|
|
||||||
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
|
||||||
*****************************************/
|
*****************************************/
|
||||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
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");
|
||||||
|
@ -513,6 +372,91 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sgwc_s5c_handle_delete_session_response(
|
||||||
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
||||||
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
ogs_gtp2_cause_t *cause = NULL;
|
||||||
|
uint8_t cause_value;
|
||||||
|
|
||||||
|
sgwc_ue_t *sgwc_ue = NULL;
|
||||||
|
|
||||||
|
ogs_gtp_xact_t *s11_xact = NULL;
|
||||||
|
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
|
sgwc_ue = sess->sgwc_ue;
|
||||||
|
ogs_assert(sgwc_ue);
|
||||||
|
ogs_assert(message);
|
||||||
|
rsp = &message->delete_session_response;
|
||||||
|
ogs_assert(rsp);
|
||||||
|
|
||||||
|
ogs_debug("Delete Session Response");
|
||||||
|
|
||||||
|
/********************
|
||||||
|
* Check Transaction
|
||||||
|
********************/
|
||||||
|
ogs_assert(s5c_xact);
|
||||||
|
s11_xact = s5c_xact->assoc_xact;
|
||||||
|
ogs_assert(s11_xact);
|
||||||
|
|
||||||
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||||
|
ogs_expect(rv == OGS_OK);
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* Check Mandatory/Conditional IE Missing
|
||||||
|
*****************************************/
|
||||||
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
|
if (rsp->cause.presence == 0) {
|
||||||
|
ogs_error("No Cause");
|
||||||
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Cause Value
|
||||||
|
********************/
|
||||||
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||||
|
|
||||||
|
cause = rsp->cause.data;
|
||||||
|
ogs_assert(cause);
|
||||||
|
cause_value = cause->value;
|
||||||
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
|
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||||
|
ogs_gtp_send_error_message(
|
||||||
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
* Check ALL Context
|
||||||
|
********************/
|
||||||
|
ogs_assert(sess);
|
||||||
|
ogs_assert(sgwc_ue);
|
||||||
|
|
||||||
|
/* Remove a pgw session */
|
||||||
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||||
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
||||||
|
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||||
|
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. MME sends Delete Session Request to SGW/SMF.
|
||||||
|
* 2. SMF sends Delete Session Response to SGW/MME.
|
||||||
|
*/
|
||||||
|
ogs_assert(OGS_OK ==
|
||||||
|
sgwc_pfcp_send_session_deletion_request(sess, s11_xact, gtpbuf));
|
||||||
|
}
|
||||||
|
|
||||||
void sgwc_s5c_handle_create_bearer_request(
|
void sgwc_s5c_handle_create_bearer_request(
|
||||||
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
||||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||||
|
@ -725,6 +669,7 @@ void sgwc_s5c_handle_update_bearer_request(
|
||||||
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
||||||
ogs_expect_or_return(rv == OGS_OK);
|
ogs_expect_or_return(rv == OGS_OK);
|
||||||
}
|
}
|
||||||
|
s11_xact->local_teid = sgwc_ue->sgw_s11_teid;
|
||||||
|
|
||||||
rv = ogs_gtp_xact_commit(s11_xact);
|
rv = ogs_gtp_xact_commit(s11_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
ogs_expect(rv == OGS_OK);
|
||||||
|
@ -874,6 +819,7 @@ void sgwc_s5c_handle_delete_bearer_request(
|
||||||
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
||||||
ogs_expect_or_return(rv == OGS_OK);
|
ogs_expect_or_return(rv == OGS_OK);
|
||||||
}
|
}
|
||||||
|
s11_xact->local_teid = sgwc_ue->sgw_s11_teid;
|
||||||
|
|
||||||
rv = ogs_gtp_xact_commit(s11_xact);
|
rv = ogs_gtp_xact_commit(s11_xact);
|
||||||
ogs_expect(rv == OGS_OK);
|
ogs_expect(rv == OGS_OK);
|
||||||
|
@ -889,6 +835,9 @@ 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);
|
||||||
|
@ -902,17 +851,6 @@ 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
|
|
||||||
************************/
|
|
||||||
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
|
||||||
********************/
|
********************/
|
||||||
|
|
|
@ -157,7 +157,7 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
|
||||||
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
||||||
/* Cause is not "Context not found" */
|
/* Cause is not "Context not found" */
|
||||||
sgwc_ue = sgwc_ue_find_by_teid(gtp_message.h.teid);
|
sgwc_ue = sgwc_ue_find_by_teid(gtp_message.h.teid);
|
||||||
} else if (gtp_xact->local_teid) { /* rx no TEID or TEID=0 */
|
} else if (gtp_xact->local_teid) { /* rx no TEID or TEID=0 */
|
||||||
/* 3GPP TS 29.274 5.5.2: we receive TEID=0 under some
|
/* 3GPP TS 29.274 5.5.2: we receive TEID=0 under some
|
||||||
* conditions, such as cause "Session context not found". In those
|
* conditions, such as cause "Session context not found". In those
|
||||||
* cases, we still want to identify the local session which
|
* cases, we still want to identify the local session which
|
||||||
|
|
|
@ -157,6 +157,7 @@ void sgwc_sxa_handle_session_establishment_response(
|
||||||
|
|
||||||
ogs_debug("Session Establishment Response");
|
ogs_debug("Session Establishment Response");
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
ogs_assert(pfcp_xact);
|
ogs_assert(pfcp_xact);
|
||||||
ogs_assert(pfcp_rsp);
|
ogs_assert(pfcp_rsp);
|
||||||
ogs_assert(recv_message);
|
ogs_assert(recv_message);
|
||||||
|
@ -171,11 +172,6 @@ void sgwc_sxa_handle_session_establishment_response(
|
||||||
|
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("No Context");
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfcp_rsp->up_f_seid.presence == 0) {
|
if (pfcp_rsp->up_f_seid.presence == 0) {
|
||||||
ogs_error("No UP F-SEID");
|
ogs_error("No UP F-SEID");
|
||||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||||
|
@ -453,6 +449,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
|
|
||||||
ogs_debug("Session Modification Response");
|
ogs_debug("Session Modification Response");
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
ogs_assert(pfcp_xact);
|
ogs_assert(pfcp_xact);
|
||||||
ogs_assert(pfcp_rsp);
|
ogs_assert(pfcp_rsp);
|
||||||
|
|
||||||
|
@ -462,30 +459,12 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (flags & OGS_PFCP_MODIFY_SESSION) {
|
if (flags & OGS_PFCP_MODIFY_SESSION) {
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("No Context");
|
|
||||||
|
|
||||||
sess = pfcp_xact->data;
|
|
||||||
ogs_assert(sess);
|
|
||||||
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
sgwc_ue = sess->sgwc_ue;
|
sgwc_ue = sess->sgwc_ue;
|
||||||
ogs_assert(sgwc_ue);
|
ogs_assert(sgwc_ue);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bearer = pfcp_xact->data;
|
bearer = pfcp_xact->data;
|
||||||
ogs_assert(bearer);
|
ogs_assert(bearer);
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("No Context");
|
|
||||||
|
|
||||||
sess = bearer->sess;
|
|
||||||
ogs_assert(sess);
|
|
||||||
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
sgwc_ue = bearer->sgwc_ue;
|
sgwc_ue = bearer->sgwc_ue;
|
||||||
ogs_assert(sgwc_ue);
|
ogs_assert(sgwc_ue);
|
||||||
}
|
}
|
||||||
|
@ -1206,16 +1185,12 @@ void sgwc_sxa_handle_session_deletion_response(
|
||||||
|
|
||||||
ogs_debug("Session Deletion Response");
|
ogs_debug("Session Deletion Response");
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
ogs_assert(pfcp_xact);
|
ogs_assert(pfcp_xact);
|
||||||
ogs_assert(pfcp_rsp);
|
ogs_assert(pfcp_rsp);
|
||||||
|
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("No Context");
|
|
||||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfcp_rsp->cause.presence) {
|
if (pfcp_rsp->cause.presence) {
|
||||||
if (pfcp_rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
if (pfcp_rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_warn("PFCP Cause[%d] : Not Accepted", pfcp_rsp->cause.u8);
|
ogs_warn("PFCP Cause[%d] : Not Accepted", pfcp_rsp->cause.u8);
|
||||||
|
@ -1324,16 +1299,12 @@ 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;
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("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;
|
||||||
|
|
|
@ -57,7 +57,7 @@ static void timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed [%d] in %s",
|
ogs_error("ogs_queue_push() failed [%d] in %s",
|
||||||
(int)rv, sgwc_timer_get_name(e->timer_id));
|
(int)rv, sgwc_timer_get_name(e->timer_id));
|
||||||
sgwc_event_free(e);
|
sgwc_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ static void pfcp_recv_cb(short when, ogs_socket_t fd, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
sgwu_event_free(e);
|
sgwu_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,7 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
sgwu_event_free(e);
|
sgwu_event_free(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -45,7 +45,7 @@ static void timer_send_event(int timer_id, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
sgwu_event_free(e);
|
sgwu_event_free(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ static void _gtpv1v2_c_recv_cb(short when, ogs_socket_t fd, void *data)
|
||||||
|
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_pkbuf_free(e->pkbuf);
|
ogs_pkbuf_free(e->pkbuf);
|
||||||
smf_event_free(e);
|
smf_event_free(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1005,7 +1005,7 @@ out:
|
||||||
e->gtp_xact = xact;
|
e->gtp_xact = xact;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_session_data_free(&gx_message->session_data);
|
ogs_session_data_free(&gx_message->session_data);
|
||||||
ogs_free(gx_message);
|
ogs_free(gx_message);
|
||||||
smf_event_free(e);
|
smf_event_free(e);
|
||||||
|
@ -1248,7 +1248,7 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
|
||||||
e->gx_message = gx_message;
|
e->gx_message = gx_message;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_session_data_free(&gx_message->session_data);
|
ogs_session_data_free(&gx_message->session_data);
|
||||||
ogs_free(gx_message);
|
ogs_free(gx_message);
|
||||||
smf_event_free(e);
|
smf_event_free(e);
|
||||||
|
|
|
@ -1104,7 +1104,7 @@ out:
|
||||||
}
|
}
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_free(gy_message);
|
ogs_free(gy_message);
|
||||||
smf_event_free(e);
|
smf_event_free(e);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1233,7 +1233,7 @@ static int smf_gy_rar_cb( struct msg **msg, struct avp *avp,
|
||||||
e->gy_message = gy_message;
|
e->gy_message = gy_message;
|
||||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
ogs_free(gy_message);
|
ogs_free(gy_message);
|
||||||
smf_event_free(e);
|
smf_event_free(e);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -53,7 +53,7 @@ int smf_initialize()
|
||||||
rv = ogs_pfcp_context_parse_config("smf", "upf");
|
rv = ogs_pfcp_context_parse_config("smf", "upf");
|
||||||
if (rv != OGS_OK) return rv;
|
if (rv != OGS_OK) return rv;
|
||||||
|
|
||||||
rv = ogs_sbi_context_parse_config("smf", "nrf");
|
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();
|
||||||
|
|
|
@ -255,6 +255,7 @@ void smf_5gc_n4_handle_session_modification_response(
|
||||||
|
|
||||||
ogs_debug("Session Modification Response [5gc]");
|
ogs_debug("Session Modification Response [5gc]");
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
|
||||||
|
@ -279,11 +280,6 @@ void smf_5gc_n4_handle_session_modification_response(
|
||||||
|
|
||||||
status = OGS_SBI_HTTP_STATUS_OK;
|
status = OGS_SBI_HTTP_STATUS_OK;
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("No Context");
|
|
||||||
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp->cause.presence) {
|
if (rsp->cause.presence) {
|
||||||
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);
|
||||||
|
@ -624,10 +620,7 @@ int smf_5gc_n4_handle_session_deletion_response(
|
||||||
|
|
||||||
status = OGS_SBI_HTTP_STATUS_OK;
|
status = OGS_SBI_HTTP_STATUS_OK;
|
||||||
|
|
||||||
if (!sess) {
|
ogs_assert(sess);
|
||||||
ogs_warn("No Context");
|
|
||||||
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp->cause.presence) {
|
if (rsp->cause.presence) {
|
||||||
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||||
|
@ -669,8 +662,6 @@ int smf_5gc_n4_handle_session_deletion_response(
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,6 +794,7 @@ void smf_epc_n4_handle_session_modification_response(
|
||||||
|
|
||||||
OGS_LIST(pdr_to_create_list);
|
OGS_LIST(pdr_to_create_list);
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
ogs_assert(rsp);
|
ogs_assert(rsp);
|
||||||
|
|
||||||
|
@ -831,11 +823,6 @@ void smf_epc_n4_handle_session_modification_response(
|
||||||
|
|
||||||
ogs_pfcp_xact_commit(xact);
|
ogs_pfcp_xact_commit(xact);
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_error("No Context");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp->cause.presence) {
|
if (rsp->cause.presence) {
|
||||||
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
|
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
|
||||||
|
@ -1111,6 +1098,7 @@ void smf_n4_handle_session_report_request(
|
||||||
uint16_t pdr_id = 0;
|
uint16_t pdr_id = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
ogs_assert(pfcp_xact);
|
ogs_assert(pfcp_xact);
|
||||||
ogs_assert(pfcp_req);
|
ogs_assert(pfcp_req);
|
||||||
|
|
||||||
|
@ -1118,11 +1106,6 @@ void smf_n4_handle_session_report_request(
|
||||||
|
|
||||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||||
|
|
||||||
if (!sess) {
|
|
||||||
ogs_warn("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;
|
||||||
|
@ -1135,7 +1118,6 @@ void smf_n4_handle_session_report_request(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_assert(sess);
|
|
||||||
report_type.value = pfcp_req->report_type.u8;
|
report_type.value = pfcp_req->report_type.u8;
|
||||||
|
|
||||||
if (report_type.downlink_data_report) {
|
if (report_type.downlink_data_report) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue