forked from acouzens/open5gs
Added NRF
This commit is contained in:
parent
46f20cc979
commit
d0673e3066
|
@ -66,6 +66,23 @@ sgw:
|
|||
addr: 127.0.0.2
|
||||
|
||||
smf:
|
||||
sbi:
|
||||
- addr: 127.0.0.3
|
||||
port: 7777
|
||||
gtpc:
|
||||
- addr: 127.0.0.3
|
||||
- addr: ::1
|
||||
pfcp:
|
||||
- addr: 127.0.0.3
|
||||
pdn:
|
||||
- addr: 10.45.0.1/16
|
||||
- addr: cafe::1/64
|
||||
dns:
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4
|
||||
- 2001:4860:4860::8888
|
||||
- 2001:4860:4860::8844
|
||||
mtu: 1400
|
||||
freeDiameter:
|
||||
identity: pgw.open-ims.test
|
||||
realm: open-ims.test
|
||||
|
@ -82,28 +99,19 @@ smf:
|
|||
connect:
|
||||
- identity: pcrf.open-ims.test
|
||||
addr: 127.0.0.5
|
||||
|
||||
gtpc:
|
||||
- addr: 127.0.0.3
|
||||
- addr: ::1
|
||||
pfcp:
|
||||
- addr: 127.0.0.3
|
||||
pdn:
|
||||
- addr: 10.45.0.1/16
|
||||
- addr: cafe::1/64
|
||||
dns:
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4
|
||||
- 2001:4860:4860::8888
|
||||
- 2001:4860:4860::8844
|
||||
mtu: 1400
|
||||
nrf:
|
||||
sbi:
|
||||
addr:
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
port: 7777
|
||||
|
||||
upf:
|
||||
pfcp:
|
||||
addr: 127.0.0.2
|
||||
addr: 127.0.0.4
|
||||
gtpu:
|
||||
- addr:
|
||||
- 127.0.0.3
|
||||
- 127.0.0.4
|
||||
- ::1
|
||||
pdn:
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ hss:
|
|||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
|
@ -92,4 +91,5 @@ max:
|
|||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
|
|
@ -26,6 +26,7 @@ open5gs_conf = '''
|
|||
pgw.yaml
|
||||
pcrf.yaml
|
||||
|
||||
nrf.yaml
|
||||
smf.yaml
|
||||
upf.yaml
|
||||
'''.split()
|
||||
|
|
|
@ -336,7 +336,6 @@ pgw:
|
|||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
|
@ -381,6 +380,7 @@ max:
|
|||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
||||
#
|
||||
|
@ -395,4 +395,5 @@ pool:
|
|||
# o max_attempts : 4
|
||||
# o max_initial_timeout : 8000(8secs)
|
||||
# o usrsctp_udp_port : 9899
|
||||
#
|
||||
sctp:
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
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,fd,nrf,event,mem,sock
|
||||
#
|
||||
logger:
|
||||
file: @localstatedir@/log/open5gs/nrf.log
|
||||
|
||||
#
|
||||
# nrf:
|
||||
#
|
||||
# <SBI Server>
|
||||
#
|
||||
# o SBI Server(http://<all address available>:80)
|
||||
# sbi:
|
||||
#
|
||||
# o SBI Server(http://<any address>:7777)
|
||||
# sbi:
|
||||
# - addr:
|
||||
# - 0.0.0.0
|
||||
# - ::0
|
||||
# port: 7777
|
||||
#
|
||||
# o SBI Server(https://<all address avaiable>:443)
|
||||
# sbi:
|
||||
# tls:
|
||||
# key: nrf.key
|
||||
# pem: nrf.pem
|
||||
#
|
||||
# o SBI Server(https://127.0.0.1:443, http://[::1]:80)
|
||||
# sbi:
|
||||
# - addr: 127.0.0.1
|
||||
# tls:
|
||||
# key: nrf.key
|
||||
# pem: nrf.pem
|
||||
# - addr: ::1
|
||||
#
|
||||
# o SBI Server(http://nrf.open5gs.org:80)
|
||||
# sbi:
|
||||
# name: nrf.open5gs.org
|
||||
#
|
||||
# o SBI Server(http://127.0.0.1:7777)
|
||||
# sbi:
|
||||
# - addr: 127.0.0.1
|
||||
# port: 7777
|
||||
#
|
||||
# o SBI Server(http://<eth0 IP address>:80)
|
||||
# sbi:
|
||||
# dev: eth0
|
||||
#
|
||||
nrf:
|
||||
sbi:
|
||||
addr:
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
port: 7777
|
||||
|
||||
#
|
||||
# parameter:
|
||||
#
|
||||
# o Number of output streams per SCTP associations.
|
||||
# sctp_streams: 30
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# o Enable Multicast traffic to the UE
|
||||
# multicast: true
|
||||
#
|
||||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
# max:
|
||||
#
|
||||
# o Maximum Number of SGW per MME
|
||||
# sgw: 32
|
||||
# o Maximum Number of PGW per MME
|
||||
# pgw: 32
|
||||
# o Maximum Number of VLR per MME
|
||||
# vlr: 32
|
||||
# o Maximum Number of eNodeB per MME
|
||||
# enb: 32
|
||||
# o Maximum Number of UE per eNodeB
|
||||
# ue: 128
|
||||
#
|
||||
max:
|
||||
|
||||
#
|
||||
# pool:
|
||||
#
|
||||
# o The Number of Default Memory Pool Size
|
||||
#
|
||||
# - Pool-size 128 => 8192 Number
|
||||
# - Pool-size 256 => 4096 Number
|
||||
# - Pool-size 512 => 2048 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
# - Pool-size 8192 => 128 Number
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 8192
|
||||
# 256: 4096
|
||||
# 512: 2048
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
# 8192: 128
|
||||
# big: 8
|
||||
#
|
||||
# o Memory of Packet Buffering in SGW
|
||||
# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW
|
||||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
||||
#
|
||||
# time:
|
||||
#
|
||||
# o NF Instance Validity (Default : 3600 seconds = 1 hour)
|
||||
#
|
||||
# o NF Instance Validity (10 seconds)
|
||||
# nf_instance:
|
||||
# validity: 10
|
||||
#
|
||||
# o Subscription Validity (Default : 86400 seconds = 1 day)
|
||||
#
|
||||
# o Subscription Validity (Disabled)
|
||||
# subscription:
|
||||
# validity: 0
|
||||
#
|
||||
# o Subscription Validity (3600 seconds = 1 hour)
|
||||
# subscription:
|
||||
# validity: 3600
|
||||
#
|
||||
time:
|
|
@ -46,7 +46,6 @@ pcrf:
|
|||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
|
@ -91,4 +90,5 @@ max:
|
|||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
|
|
@ -186,7 +186,6 @@ pgw:
|
|||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
|
@ -231,4 +230,5 @@ max:
|
|||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
|
|
@ -82,7 +82,6 @@ sgw:
|
|||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
#
|
||||
parameter:
|
||||
no_ipv6: true
|
||||
|
||||
|
@ -128,4 +127,5 @@ max:
|
|||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
|
|
@ -23,6 +23,45 @@ logger:
|
|||
#
|
||||
# smf:
|
||||
#
|
||||
# <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: smf.key
|
||||
# pem: smf.pem
|
||||
#
|
||||
# o SBI Server(https://127.0.0.3:443, http://[::1]:80)
|
||||
# sbi:
|
||||
# - addr: 127.0.0.3
|
||||
# tls:
|
||||
# key: smf.key
|
||||
# pem: smf.pem
|
||||
# - addr: ::1
|
||||
#
|
||||
# o SBI Server(http://smf.open5gs.org:80)
|
||||
# sbi:
|
||||
# name: smf.open5gs.org
|
||||
#
|
||||
# o SBI Server(http://127.0.0.3:7777)
|
||||
# sbi:
|
||||
# - addr: 127.0.0.3
|
||||
# port: 7777
|
||||
#
|
||||
# o SBI Server(http://<eth0 IP address>:80)
|
||||
# sbi:
|
||||
# dev: eth0
|
||||
#
|
||||
# <PFCP Server>
|
||||
#
|
||||
# o PFCP Server(127.0.0.3:8805, ::1:8805)
|
||||
|
@ -141,7 +180,9 @@ logger:
|
|||
# - ::1
|
||||
#
|
||||
smf:
|
||||
freeDiameter: @sysconfdir@/freeDiameter/pgw.conf
|
||||
sbi:
|
||||
- addr: 127.0.0.3
|
||||
port: 7777
|
||||
gtpc:
|
||||
- addr: 127.0.0.3
|
||||
- addr: ::1
|
||||
|
@ -157,20 +198,54 @@ smf:
|
|||
- 2001:4860:4860::8888
|
||||
- 2001:4860:4860::8844
|
||||
mtu: 1400
|
||||
freeDiameter: @sysconfdir@/freeDiameter/pgw.conf
|
||||
|
||||
#
|
||||
# nrf:
|
||||
#
|
||||
# <SBI Client>>
|
||||
#
|
||||
# o SBI Client(http://127.0.0.1:7777)
|
||||
# sbi:
|
||||
# addr: 127.0.0.1
|
||||
# port: 7777
|
||||
#
|
||||
# o SBI Client(https://127.0.0.1:443, http://nrf.open5gs.org:80)
|
||||
# sbi:
|
||||
# - addr: 127.0.0.1
|
||||
# tls:
|
||||
# key: nrf.key
|
||||
# pem: nrf.pem
|
||||
# - name: nrf.open5gs.org
|
||||
#
|
||||
# o SBI Client(http://[fe80::1%@loopback_devname@]:80)
|
||||
# If prefer_ipv4 is true, http://127.0.0.1:80 is selected.
|
||||
#
|
||||
# sbi:
|
||||
# addr:
|
||||
# - 127.0.0.1
|
||||
# - fe80::1%@loopback_devname@
|
||||
#
|
||||
nrf:
|
||||
sbi:
|
||||
addr:
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
port: 7777
|
||||
|
||||
#
|
||||
# upf:
|
||||
#
|
||||
# <PFCP Client>>
|
||||
#
|
||||
# o PFCP Client(127.0.0.2:8805)
|
||||
# o PFCP Client(127.0.0.4:8805)
|
||||
#
|
||||
# pfcp:
|
||||
# addr: 127.0.0.2
|
||||
# addr: 127.0.0.4
|
||||
#
|
||||
upf:
|
||||
pfcp:
|
||||
addr: 127.0.0.2
|
||||
addr: 127.0.0.4
|
||||
|
||||
#
|
||||
# parameter:
|
||||
|
@ -193,7 +268,6 @@ upf:
|
|||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
|
@ -238,4 +312,19 @@ max:
|
|||
# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes
|
||||
#
|
||||
# packet: 65536
|
||||
#
|
||||
pool:
|
||||
|
||||
#
|
||||
# time:
|
||||
#
|
||||
# o NF Instance Heartbeat (Default : 3 seconds)
|
||||
#
|
||||
# o NF Instance Heartbeat (Disabled)
|
||||
# nf_instance:
|
||||
# heartbeat: 0
|
||||
#
|
||||
# o NF Instance Heartbeat (5 seconds)
|
||||
# nf_instance:
|
||||
# heartbeat: 5
|
||||
time:
|
||||
|
|
|
@ -26,32 +26,32 @@ logger:
|
|||
#
|
||||
# <PFCP Server>
|
||||
#
|
||||
# o PFCP Server(127.0.0.2:8805)
|
||||
# o PFCP Server(127.0.0.4:8805)
|
||||
# pfcp:
|
||||
# addr: 127.0.0.2
|
||||
# addr: 127.0.0.4
|
||||
#
|
||||
# <GTP-U Server>>
|
||||
#
|
||||
# o GTP-U Server(127.0.0.3:2152, [::1]:2152)
|
||||
# o GTP-U Server(127.0.0.4:2152, [::1]:2152)
|
||||
# gtpu:
|
||||
# - addr:
|
||||
# - 127.0.0.3
|
||||
# - 127.0.0.4
|
||||
# - ::1
|
||||
#
|
||||
# o Same configuration(127.0.0.3:2152, [::1]:2152) as below.
|
||||
# o Same configuration(127.0.0.4:2152, [::1]:2152) as below.
|
||||
# gtpu:
|
||||
# name: localhost
|
||||
#
|
||||
# o User Plane IP Resource information
|
||||
# gtpu:
|
||||
# - addr:
|
||||
# - 127.0.0.3
|
||||
# - 127.0.0.4
|
||||
# - ::1
|
||||
# teid_range_indication: 4
|
||||
# teid_range: 10
|
||||
# network_instance: internet
|
||||
# source_interface: 0
|
||||
# - addr: 127.0.0.4
|
||||
# - addr: 127.0.10.4
|
||||
# teid_range_indication: 4
|
||||
# teid_range: 5
|
||||
# network_instance: ims
|
||||
|
@ -59,10 +59,10 @@ logger:
|
|||
#
|
||||
upf:
|
||||
pfcp:
|
||||
addr: 127.0.0.2
|
||||
addr: 127.0.0.4
|
||||
gtpu:
|
||||
- addr:
|
||||
- 127.0.0.3
|
||||
- 127.0.0.4
|
||||
- ::1
|
||||
pdn:
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
open5gs (1.2.5) unstable; urgency=medium
|
||||
|
||||
* NRF is added
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 18 May 2020 13:14:54 -0400
|
||||
|
||||
open5gs (1.2.4~eoan) eoan; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
|
|
@ -17,6 +17,8 @@ Build-Depends: debhelper (>= 11),
|
|||
libbson-dev,
|
||||
libsctp-dev,
|
||||
libyaml-dev,
|
||||
libmicrohttpd-dev,
|
||||
libcurl4-gnutls-dev,
|
||||
Standards-Version: 4.3.0
|
||||
Rules-Requires-Root: no
|
||||
Homepage: https://open5gs.org
|
||||
|
|
|
@ -15,6 +15,7 @@ RUN yum -y install \
|
|||
flex \
|
||||
bison \
|
||||
git \
|
||||
meson \
|
||||
lksctp-tools-devel \
|
||||
libidn-devel \
|
||||
gnutls-devel \
|
||||
|
@ -22,7 +23,7 @@ RUN yum -y install \
|
|||
openssl-devel \
|
||||
cyrus-sasl-devel \
|
||||
libyaml-devel \
|
||||
iproute \
|
||||
mongo-c-driver-devel
|
||||
|
||||
RUN pip3 install --upgrade pip && pip install meson
|
||||
mongo-c-driver-devel \
|
||||
libmicrohttpd-devel \
|
||||
libcurl-devel \
|
||||
iproute
|
||||
|
|
|
@ -9,6 +9,11 @@ RUN dnf -y install epel-release && \
|
|||
dnf config-manager --set-enabled PowerTools && \
|
||||
dnf -y update
|
||||
|
||||
RUN dnf -y install \
|
||||
https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm && \
|
||||
dnf config-manager --set-enabled elrepo-testing && \
|
||||
dnf -y update
|
||||
|
||||
RUN dnf -y install \
|
||||
python3 \
|
||||
ninja-build \
|
||||
|
@ -23,7 +28,9 @@ RUN dnf -y install \
|
|||
openssl-devel \
|
||||
cyrus-sasl-devel \
|
||||
libyaml-devel \
|
||||
iproute \
|
||||
mongo-c-driver-devel
|
||||
mongo-c-driver-devel \
|
||||
libmicrohttpd-devel \
|
||||
libcurl-devel \
|
||||
iproute
|
||||
|
||||
RUN pip3 install --upgrade pip && pip install meson
|
||||
RUN dnf -y install meson
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
latest
|
|
@ -18,7 +18,9 @@ RUN dnf -y install \
|
|||
openssl-devel \
|
||||
cyrus-sasl-devel \
|
||||
libyaml-devel \
|
||||
iproute \
|
||||
mongo-c-driver-devel
|
||||
mongo-c-driver-devel \
|
||||
libmicrohttpd-devel \
|
||||
libcurl-devel \
|
||||
iproute
|
||||
|
||||
RUN pip3 install --upgrade pip && pip install meson
|
||||
RUN dnf -y install meson
|
||||
|
|
|
@ -6,6 +6,7 @@ FROM ${username}/${dist}-${tag}-open5gs-base
|
|||
MAINTAINER Sukchan Lee <acetcom@gmail.com>
|
||||
|
||||
RUN dnf -y install \
|
||||
findutils \
|
||||
cscope \
|
||||
vim \
|
||||
sudo \
|
||||
|
|
|
@ -25,6 +25,8 @@ RUN apt-get update && \
|
|||
libmongoc-dev \
|
||||
libbson-dev \
|
||||
libyaml-dev \
|
||||
libmicrohttpd-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
iproute2 \
|
||||
ca-certificates \
|
||||
netbase \
|
||||
|
|
|
@ -40,7 +40,7 @@ $ sudo ip link set ogstun up
|
|||
Install the dependencies for building the source code.
|
||||
|
||||
```bash
|
||||
$ sudo apt install python3-pip python3-setuptools python3-wheel ninja-build build-essential flex bison git libsctp-dev libgnutls28-dev libgcrypt-dev libssl-dev libidn11-dev libmongoc-dev libbson-dev libyaml-dev meson
|
||||
$ sudo apt install python3-pip python3-setuptools python3-wheel ninja-build build-essential flex bison git libsctp-dev libgnutls28-dev libgcrypt-dev libssl-dev libidn11-dev libmongoc-dev libbson-dev libyaml-dev libmicrohttpd-dev libcurl4-gnutls-dev meson
|
||||
```
|
||||
|
||||
Git clone.
|
||||
|
|
|
@ -23,8 +23,13 @@ EOF'
|
|||
|
||||
Install MongoDB with Package Manager.
|
||||
```bash
|
||||
sudo yum -y install mongodb-org
|
||||
sudo systemctl start mongod (if '/usr/bin/mongod' is not running)
|
||||
sudo dnf -y install mongodb-org
|
||||
```
|
||||
|
||||
Run MongoDB server.
|
||||
```bash
|
||||
$ mkdir -p ./data/db
|
||||
$ mongod --dbpath ./data/db
|
||||
```
|
||||
|
||||
### Setting up TUN device (No persistent after rebooting)
|
||||
|
@ -85,15 +90,21 @@ $ sudo dnf config-manager --set-enabled PowerTools
|
|||
$ sudo update
|
||||
```
|
||||
|
||||
Install the depedencies for building the source code.
|
||||
Configure ELRepo(with testing) package.
|
||||
```bash
|
||||
$ sudo dnf install python3 ninja-build gcc flex bison git lksctp-tools-devel libidn-devel gnutls-devel libgcrypt-devel openssl-devel cyrus-sasl-devel libyaml-devel iproute mongo-c-driver-devel
|
||||
$ sudo dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm
|
||||
$ sudo dnf config-manager --set-enabled elrepo-testing
|
||||
$ sudo dnf update
|
||||
```
|
||||
|
||||
Install Meson using Python.
|
||||
Install the depedencies for building the source code.
|
||||
```bash
|
||||
$ sudo pip3 install --upgrade pip
|
||||
$ sudo pip install meson
|
||||
$ sudo dnf install python3 ninja-build gcc flex bison git lksctp-tools-devel libidn-devel gnutls-devel libgcrypt-devel openssl-devel cyrus-sasl-devel libyaml-devel mongo-c-driver-devel libmicrohttpd-devel libcurl-devel iproute
|
||||
```
|
||||
|
||||
Install Meson
|
||||
```bash
|
||||
$ sudo dnf install meson
|
||||
```
|
||||
|
||||
Git clone.
|
||||
|
|
|
@ -67,13 +67,12 @@ $ ip link show
|
|||
|
||||
Install the depedencies for building the source code.
|
||||
```bash
|
||||
$ sudo dnf install python3 ninja-build gcc flex bison git lksctp-tools-devel libidn-devel gnutls-devel libgcrypt-devel openssl-devel cyrus-sasl-devel libyaml-devel iproute mongo-c-driver-devel
|
||||
$ sudo dnf install python3 ninja-build gcc flex bison git lksctp-tools-devel libidn-devel gnutls-devel libgcrypt-devel openssl-devel cyrus-sasl-devel libyaml-devel mongo-c-driver-devel libmicrohttpd-devel libcurl-devel iproute
|
||||
```
|
||||
|
||||
Install Meson using Python.
|
||||
Install Meson
|
||||
```bash
|
||||
$ sudo pip3 install --upgrade pip
|
||||
$ sudo pip install meson
|
||||
$ sudo dnf install meson
|
||||
```
|
||||
|
||||
Git clone.
|
||||
|
|
|
@ -45,7 +45,7 @@ $ sudo sysctl -w net.inet.ip.forwarding=1
|
|||
|
||||
Install the depedencies for building the source code.
|
||||
```bash
|
||||
$ sudo pkg install py36-pip ninja gcc bison gsed pkgconf git mongo-c-driver gnutls libgcrypt libidn libyaml
|
||||
$ sudo pkg install py36-pip ninja gcc bison gsed pkgconf git mongo-c-driver gnutls libgcrypt libidn libyaml libmicrohttpd curl
|
||||
```
|
||||
|
||||
Install Meson using Python.
|
||||
|
|
|
@ -63,7 +63,7 @@ $ sudo pfctl -e -f /etc/pf.anchors/org.open5gs
|
|||
|
||||
Install the depedencies for building the source code.
|
||||
```bash
|
||||
$ brew install mongo-c-driver gnutls libgcrypt libidn libyaml pkg-config
|
||||
$ brew install mongo-c-driver gnutls libgcrypt libidn libyaml libmicrohttpd curl pkg-config
|
||||
```
|
||||
|
||||
Install Meson using Homebrew.
|
||||
|
|
|
@ -57,6 +57,9 @@ void pgw_terminate(void);
|
|||
int pcrf_initialize(void);
|
||||
void pcrf_terminate(void);
|
||||
|
||||
int nrf_initialize(void);
|
||||
void nrf_terminate(void);
|
||||
|
||||
int smf_initialize(void);
|
||||
void smf_terminate(void);
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ static void recalculate_pool_size(void)
|
|||
|
||||
self.pool.ue = self.max.ue * self.max.enb;
|
||||
self.pool.pfcp = ogs_max(self.max.smf, self.max.upf);
|
||||
self.pool.sbi = self.pool.pfcp;
|
||||
self.pool.sess = self.pool.ue * OGS_MAX_NUM_OF_SESS;
|
||||
self.pool.bearer = self.pool.sess * MAX_NUM_OF_BEARER;
|
||||
self.pool.tunnel = self.pool.bearer * MAX_NUM_OF_TUNNEL;
|
||||
|
@ -175,6 +176,10 @@ static int config_prepare(void)
|
|||
|
||||
recalculate_pool_size();
|
||||
|
||||
self.time.nf_instance.heartbeat = 3; /* 3 second */
|
||||
self.time.nf_instance.validity = 3600; /* 3600 seconds = 1 hour */
|
||||
self.time.subscription.validity = 86400; /* 86400 seconds = 1 day */
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
|
@ -187,6 +192,15 @@ static int ogs_app_ctx_validation(void)
|
|||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
if (self.time.nf_instance.validity == 0) {
|
||||
ogs_error("NF Instance validity-time should not 0");
|
||||
ogs_error("time:");
|
||||
ogs_error(" nf_instance:");
|
||||
ogs_error(" validity: 0");
|
||||
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
int ogs_config_parse()
|
||||
|
@ -358,8 +372,49 @@ int ogs_config_parse()
|
|||
} else
|
||||
ogs_warn("unknown key `%s`", pool_key);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(root_key, "time")) {
|
||||
ogs_yaml_iter_t time_iter;
|
||||
ogs_yaml_iter_recurse(&root_iter, &time_iter);
|
||||
while (ogs_yaml_iter_next(&time_iter)) {
|
||||
const char *time_key = ogs_yaml_iter_key(&time_iter);
|
||||
ogs_assert(time_key);
|
||||
if (!strcmp(time_key, "nf_instance")) {
|
||||
ogs_yaml_iter_t sbi_iter;
|
||||
ogs_yaml_iter_recurse(&time_iter, &sbi_iter);
|
||||
|
||||
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, "heartbeat")) {
|
||||
const char *v = ogs_yaml_iter_value(&sbi_iter);
|
||||
if (v) self.time.nf_instance.heartbeat = atoi(v);
|
||||
} else if (!strcmp(sbi_key, "validity")) {
|
||||
const char *v = ogs_yaml_iter_value(&sbi_iter);
|
||||
if (v) self.time.nf_instance.validity = atoi(v);
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", sbi_key);
|
||||
}
|
||||
} else if (!strcmp(time_key, "subscription")) {
|
||||
ogs_yaml_iter_t sbi_iter;
|
||||
ogs_yaml_iter_recurse(&time_iter, &sbi_iter);
|
||||
|
||||
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, "validity")) {
|
||||
const char *v = ogs_yaml_iter_value(&sbi_iter);
|
||||
if (v) self.time.subscription.validity = atoi(v);
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", sbi_key);
|
||||
}
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", time_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = ogs_app_ctx_validation();
|
||||
|
|
|
@ -78,11 +78,22 @@ typedef struct ogs_config_s {
|
|||
|
||||
int ue;
|
||||
int pfcp;
|
||||
int sbi;
|
||||
int sess;
|
||||
int bearer;
|
||||
int tunnel;
|
||||
int pf;
|
||||
} pool;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
int heartbeat;
|
||||
int validity;
|
||||
} nf_instance;
|
||||
struct {
|
||||
int validity;
|
||||
} subscription;
|
||||
} time;
|
||||
} ogs_config_t;
|
||||
|
||||
int ogs_config_init(void);
|
||||
|
|
|
@ -235,6 +235,7 @@ libcore_sources = files('''
|
|||
ogs-rbtree.h
|
||||
ogs-timer.h
|
||||
ogs-rand.h
|
||||
ogs-uuid.h
|
||||
ogs-thread.h
|
||||
ogs-signal.h
|
||||
ogs-process.h
|
||||
|
@ -269,6 +270,7 @@ libcore_sources = files('''
|
|||
ogs-rbtree.c
|
||||
ogs-timer.c
|
||||
ogs-rand.c
|
||||
ogs-uuid.c
|
||||
ogs-thread.c
|
||||
ogs-signal.c
|
||||
ogs-process.c
|
||||
|
@ -295,6 +297,13 @@ libcore_sources = files('''
|
|||
abts.c
|
||||
'''.split())
|
||||
|
||||
if have_func_epoll_ctl
|
||||
libcore_sources += files('ogs-epoll.c')
|
||||
endif
|
||||
if have_func_kqueue
|
||||
libcore_sources += files('ogs-kqueue.c')
|
||||
endif
|
||||
|
||||
libcore_inc = include_directories('.')
|
||||
|
||||
libcore = library('ogscore',
|
||||
|
|
|
@ -131,3 +131,7 @@ void *ogs_buffer_to_bcd(uint8_t *in, int in_len, void *out)
|
|||
return out;
|
||||
}
|
||||
|
||||
char ogs_from_hex(char ch)
|
||||
{
|
||||
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ uint64_t ogs_buffer_to_uint64(void *buffer, int size);
|
|||
void *ogs_bcd_to_buffer(const char *in, void *out, int *out_len);
|
||||
void *ogs_buffer_to_bcd(uint8_t *in, int in_len, void *out);
|
||||
|
||||
char ogs_from_hex(char ch);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "core/ogs-pkbuf.h"
|
||||
#include "core/ogs-memory.h"
|
||||
#include "core/ogs-rand.h"
|
||||
#include "core/ogs-uuid.h"
|
||||
#include "core/ogs-rbtree.h"
|
||||
#include "core/ogs-timer.h"
|
||||
#include "core/ogs-thread.h"
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
static void epoll_init(ogs_pollset_t *pollset);
|
||||
static void epoll_cleanup(ogs_pollset_t *pollset);
|
||||
static int epoll_add(ogs_poll_t *poll, short when);
|
||||
static int epoll_add(ogs_poll_t *poll);
|
||||
static int epoll_remove(ogs_poll_t *poll);
|
||||
static int epoll_process(ogs_pollset_t *pollset, ogs_time_t timeout);
|
||||
|
||||
|
@ -45,9 +45,15 @@ const ogs_pollset_actions_t ogs_epoll_actions = {
|
|||
ogs_notify_pollset,
|
||||
};
|
||||
|
||||
struct epoll_map_s {
|
||||
ogs_poll_t *read;
|
||||
ogs_poll_t *write;
|
||||
};
|
||||
|
||||
struct epoll_context_s {
|
||||
int epfd;
|
||||
|
||||
ogs_hash_t *map_hash;
|
||||
struct epoll_event *event_list;
|
||||
};
|
||||
|
||||
|
@ -64,6 +70,9 @@ static void epoll_init(ogs_pollset_t *pollset)
|
|||
ogs_core()->socket.pool, sizeof(struct epoll_event));
|
||||
ogs_assert(context->event_list);
|
||||
|
||||
context->map_hash = ogs_hash_make();
|
||||
ogs_assert(context->map_hash);
|
||||
|
||||
context->epfd = epoll_create(ogs_core()->socket.pool);
|
||||
ogs_assert(context->epfd >= 0);
|
||||
|
||||
|
@ -81,15 +90,17 @@ static void epoll_cleanup(ogs_pollset_t *pollset)
|
|||
ogs_notify_final(pollset);
|
||||
close(context->epfd);
|
||||
ogs_free(context->event_list);
|
||||
ogs_hash_destroy(context->map_hash);
|
||||
|
||||
ogs_free(context);
|
||||
}
|
||||
|
||||
static int epoll_add(ogs_poll_t *poll, short when)
|
||||
static int epoll_add(ogs_poll_t *poll)
|
||||
{
|
||||
int rv, op;
|
||||
ogs_pollset_t *pollset = NULL;
|
||||
struct epoll_context_s *context = NULL;
|
||||
int rv;
|
||||
struct epoll_map_s *map = NULL;
|
||||
struct epoll_event ee;
|
||||
|
||||
ogs_assert(poll);
|
||||
|
@ -98,17 +109,33 @@ static int epoll_add(ogs_poll_t *poll, short when)
|
|||
context = pollset->context;
|
||||
ogs_assert(context);
|
||||
|
||||
map = ogs_hash_get(context->map_hash, &poll->fd, sizeof(poll->fd));
|
||||
if (!map) {
|
||||
map = ogs_calloc(1, sizeof(*map));
|
||||
ogs_assert(map);
|
||||
|
||||
op = EPOLL_CTL_ADD;
|
||||
ogs_hash_set(context->map_hash, &poll->fd, sizeof(poll->fd), map);
|
||||
} else {
|
||||
op = EPOLL_CTL_MOD;
|
||||
}
|
||||
|
||||
if (poll->when & OGS_POLLIN)
|
||||
map->read = poll;
|
||||
if (poll->when & OGS_POLLOUT)
|
||||
map->write = poll;
|
||||
|
||||
ee.events = 0;
|
||||
if (when == OGS_POLLIN)
|
||||
if (map->read)
|
||||
ee.events |= (EPOLLIN|EPOLLRDHUP);
|
||||
if (when == OGS_POLLOUT)
|
||||
if (map->write)
|
||||
ee.events |= EPOLLOUT;
|
||||
ee.data.ptr = map;
|
||||
|
||||
ee.data.ptr = poll;
|
||||
|
||||
rv = epoll_ctl(context->epfd, EPOLL_CTL_ADD, poll->fd, &ee);
|
||||
rv = epoll_ctl(context->epfd, op, poll->fd, &ee);
|
||||
if (rv < 0) {
|
||||
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "epoll_ctl failed");
|
||||
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
|
||||
"epoll_ctl[%d] failed", op);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -117,9 +144,10 @@ static int epoll_add(ogs_poll_t *poll, short when)
|
|||
|
||||
static int epoll_remove(ogs_poll_t *poll)
|
||||
{
|
||||
int rv;
|
||||
int rv, op;
|
||||
ogs_pollset_t *pollset = NULL;
|
||||
struct epoll_context_s *context = NULL;
|
||||
struct epoll_map_s *map = NULL;
|
||||
struct epoll_event ee;
|
||||
|
||||
ogs_assert(poll);
|
||||
|
@ -128,13 +156,35 @@ static int epoll_remove(ogs_poll_t *poll)
|
|||
context = pollset->context;
|
||||
ogs_assert(context);
|
||||
|
||||
map = ogs_hash_get(context->map_hash, &poll->fd, sizeof(poll->fd));
|
||||
ogs_assert(map);
|
||||
|
||||
if (poll->when & OGS_POLLIN)
|
||||
map->read = NULL;
|
||||
if (poll->when & OGS_POLLOUT)
|
||||
map->write = NULL;
|
||||
|
||||
ee.events = 0;
|
||||
if (map->read)
|
||||
ee.events |= (EPOLLIN|EPOLLRDHUP);
|
||||
if (map->write)
|
||||
ee.events |= EPOLLOUT;
|
||||
|
||||
if (map->read || map->write) {
|
||||
op = EPOLL_CTL_MOD;
|
||||
ee.data.ptr = map;
|
||||
} else {
|
||||
op = EPOLL_CTL_DEL;
|
||||
ee.data.ptr = NULL;
|
||||
|
||||
rv = epoll_ctl(context->epfd, EPOLL_CTL_DEL, poll->fd, &ee);
|
||||
ogs_free(map);
|
||||
ogs_hash_set(context->map_hash, &poll->fd, sizeof(poll->fd), NULL);
|
||||
}
|
||||
|
||||
rv = epoll_ctl(context->epfd, op, poll->fd, &ee);
|
||||
if (rv < 0) {
|
||||
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
|
||||
"epoll_remove failed");
|
||||
"epoll_remove[%d] failed", op);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -163,7 +213,7 @@ static int epoll_process(ogs_pollset_t *pollset, ogs_time_t timeout)
|
|||
}
|
||||
|
||||
for (i = 0; i < num_of_poll; i++) {
|
||||
ogs_poll_t *poll = NULL;
|
||||
struct epoll_map_s *map = NULL;
|
||||
uint32_t received;
|
||||
short when = 0;
|
||||
|
||||
|
@ -182,11 +232,16 @@ static int epoll_process(ogs_pollset_t *pollset, ogs_time_t timeout)
|
|||
if (!when)
|
||||
continue;
|
||||
|
||||
poll = context->event_list[i].data.ptr;
|
||||
ogs_assert(poll);
|
||||
map = context->event_list[i].data.ptr;
|
||||
ogs_assert(map);
|
||||
|
||||
if (poll->handler) {
|
||||
poll->handler(when, poll->fd, poll->data);
|
||||
if (map->read && map->write && map->read == map->write) {
|
||||
map->read->handler(when, map->read->fd, map->read->data);
|
||||
} else {
|
||||
if (map->read && (when & OGS_POLLIN))
|
||||
map->read->handler(when, map->read->fd, map->read->data);
|
||||
if (map->write && (when & OGS_POLLOUT))
|
||||
map->write->handler(when, map->write->fd, map->write->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
static void kqueue_init(ogs_pollset_t *pollset);
|
||||
static void kqueue_cleanup(ogs_pollset_t *pollset);
|
||||
static int kqueue_add(ogs_poll_t *poll, short when);
|
||||
static int kqueue_add(ogs_poll_t *poll);
|
||||
static int kqueue_remove(ogs_poll_t *poll);
|
||||
static int kqueue_process(ogs_pollset_t *pollset, ogs_time_t timeout);
|
||||
|
||||
|
@ -123,14 +123,14 @@ static int kqueue_set(ogs_poll_t *poll, int filter, int flags)
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
static int kqueue_add(ogs_poll_t *poll, short when)
|
||||
static int kqueue_add(ogs_poll_t *poll)
|
||||
{
|
||||
int filter = 0;
|
||||
|
||||
if (when & OGS_POLLIN) {
|
||||
if (poll->when & OGS_POLLIN) {
|
||||
filter = EVFILT_READ;
|
||||
}
|
||||
if (when & OGS_POLLOUT) {
|
||||
if (poll->when & OGS_POLLOUT) {
|
||||
filter = EVFILT_WRITE;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,19 @@ extern "C" {
|
|||
#define ogs_container_of(ptr, type, member) \
|
||||
(type *)((u_char *)ptr - offsetof(type, member))
|
||||
|
||||
#ifndef SWITCH_CASE_INIT
|
||||
#define SWITCH_CASE_INIT
|
||||
#define SWITCH(X) {char *__switch_p__, __switch_next__; \
|
||||
for (__switch_p__ = (char *)X, __switch_next__ = 1; \
|
||||
__switch_p__; \
|
||||
__switch_p__ = 0, __switch_next__ = 1) { {
|
||||
#define CASE(X) } if (!__switch_next__ || \
|
||||
!(__switch_next__ = \
|
||||
strcmp(__switch_p__, X))) {
|
||||
#define DEFAULT } {
|
||||
#define END }}}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct ogs_poll_s {
|
|||
ogs_lnode_t node;
|
||||
int index;
|
||||
|
||||
short when;
|
||||
ogs_socket_t fd;
|
||||
ogs_poll_handler_f handler;
|
||||
void *data;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "core-config-private.h"
|
||||
|
||||
#include "ogs-core.h"
|
||||
|
||||
#include "ogs-poll-private.h"
|
||||
|
@ -80,13 +82,14 @@ ogs_poll_t *ogs_pollset_add(ogs_pollset_t *pollset, short when,
|
|||
rc = ogs_closeonexec(fd);
|
||||
ogs_assert(rc == OGS_OK);
|
||||
|
||||
poll->when = when;
|
||||
poll->fd = fd;
|
||||
poll->handler = handler;
|
||||
poll->data = data;
|
||||
|
||||
poll->pollset = pollset;
|
||||
|
||||
rc = ogs_pollset_actions.add(poll, when);
|
||||
rc = ogs_pollset_actions.add(poll);
|
||||
if (rc != OGS_OK) {
|
||||
ogs_error("cannot add poll");
|
||||
ogs_pool_free(&pollset->pool, poll);
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct ogs_pollset_actions_s {
|
|||
void (*init)(ogs_pollset_t *pollset);
|
||||
void (*cleanup)(ogs_pollset_t *pollset);
|
||||
|
||||
int (*add)(ogs_poll_t *poll, short when);
|
||||
int (*add)(ogs_poll_t *poll);
|
||||
int (*remove)(ogs_poll_t *poll);
|
||||
|
||||
int (*poll)(ogs_pollset_t *pollset, ogs_time_t timeout);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
static void select_init(ogs_pollset_t *pollset);
|
||||
static void select_cleanup(ogs_pollset_t *pollset);
|
||||
static int select_add(ogs_poll_t *poll, short when);
|
||||
static int select_add(ogs_poll_t *poll);
|
||||
static int select_remove(ogs_poll_t *poll);
|
||||
static int select_process(ogs_pollset_t *pollset, ogs_time_t timeout);
|
||||
|
||||
|
@ -83,7 +83,7 @@ static void select_cleanup(ogs_pollset_t *pollset)
|
|||
ogs_free(context);
|
||||
}
|
||||
|
||||
static int select_add(ogs_poll_t *poll, short when)
|
||||
static int select_add(ogs_poll_t *poll)
|
||||
{
|
||||
ogs_pollset_t *pollset = NULL;
|
||||
struct select_context_s *context = NULL;
|
||||
|
@ -94,11 +94,11 @@ static int select_add(ogs_poll_t *poll, short when)
|
|||
context = pollset->context;
|
||||
ogs_assert(context);
|
||||
|
||||
if (when & OGS_POLLIN) {
|
||||
if (poll->when & OGS_POLLIN) {
|
||||
FD_SET(poll->fd, &context->master_read_fd_set);
|
||||
}
|
||||
|
||||
if (when & OGS_POLLOUT) {
|
||||
if (poll->when & OGS_POLLOUT) {
|
||||
FD_SET(poll->fd, &context->master_write_fd_set);
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,10 @@ static int select_remove(ogs_poll_t *poll)
|
|||
context = pollset->context;
|
||||
ogs_assert(context);
|
||||
|
||||
if (poll->when & OGS_POLLIN)
|
||||
FD_CLR(poll->fd, &context->master_read_fd_set);
|
||||
|
||||
if (poll->when & OGS_POLLOUT)
|
||||
FD_CLR(poll->fd, &context->master_write_fd_set);
|
||||
|
||||
if (context->max_fd == poll->fd) {
|
||||
|
|
|
@ -579,3 +579,32 @@ int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
|
|||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
char *ogs_gethostname(ogs_sockaddr_t *addr)
|
||||
{
|
||||
int rv;
|
||||
char hostname[OGS_MAX_FQDN_LEN];
|
||||
|
||||
ogs_assert(addr);
|
||||
|
||||
if (!addr->hostname)
|
||||
return NULL;
|
||||
|
||||
rv = ogs_getnameinfo(hostname, OGS_MAX_FQDN_LEN, addr, 0);
|
||||
if (rv == OGS_OK && strcmp(addr->hostname, hostname) == 0)
|
||||
return addr->hostname;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ogs_ipstrdup(ogs_sockaddr_t *addr)
|
||||
{
|
||||
char buf[OGS_ADDRSTRLEN + 1];
|
||||
|
||||
ogs_assert(addr);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
OGS_ADDR(addr, buf);
|
||||
|
||||
return ogs_strdup(buf);
|
||||
}
|
||||
|
|
|
@ -94,6 +94,9 @@ bool ogs_sockaddr_is_equal(void *p, void *q);
|
|||
int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
|
||||
const char *ipstr, const char *mask_or_numbits);
|
||||
|
||||
char *ogs_gethostname(ogs_sockaddr_t *addr);
|
||||
char *ogs_ipstrdup(ogs_sockaddr_t *addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -154,3 +154,77 @@ char *ogs_cpystrn(char *dst, const char *src, size_t dst_size)
|
|||
|
||||
return (d);
|
||||
}
|
||||
|
||||
/*
|
||||
* char *ogs_msprintf(const char *message, ...)
|
||||
* char *mstrcatf(char *source, const char *message, ...)
|
||||
*
|
||||
* Orcania library
|
||||
* Copyright 2015-2018 Nicolas Mora <mail@babelouest.org>
|
||||
* License: LGPL-2.1
|
||||
*
|
||||
* https://github.com/babelouest/orcania.git
|
||||
*/
|
||||
char *ogs_msprintf(const char *message, ...)
|
||||
{
|
||||
va_list argp, argp_cpy;
|
||||
size_t out_len = 0;
|
||||
char *out = NULL;
|
||||
if (message != NULL) {
|
||||
va_start(argp, message);
|
||||
va_copy(argp_cpy, argp); /* We make a copy because
|
||||
in some architectures,
|
||||
vsnprintf can modify argp */
|
||||
out_len = vsnprintf(NULL, 0, message, argp);
|
||||
out = ogs_malloc(out_len + sizeof(char));
|
||||
if (out == NULL) {
|
||||
va_end(argp);
|
||||
va_end(argp_cpy);
|
||||
return NULL;
|
||||
}
|
||||
vsnprintf(out, (out_len + sizeof(char)), message, argp_cpy);
|
||||
va_end(argp);
|
||||
va_end(argp_cpy);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
char *ogs_mstrcatf(char *source, const char *message, ...)
|
||||
{
|
||||
va_list argp, argp_cpy;
|
||||
char *out = NULL, *message_formatted = NULL;
|
||||
size_t message_formatted_len = 0, out_len = 0;
|
||||
|
||||
if (message != NULL) {
|
||||
if (source != NULL) {
|
||||
va_start(argp, message);
|
||||
va_copy(argp_cpy, argp); /* We make a copy because
|
||||
in some architectures,
|
||||
vsnprintf can modify argp */
|
||||
message_formatted_len = vsnprintf(NULL, 0, message, argp);
|
||||
message_formatted = ogs_malloc(message_formatted_len+sizeof(char));
|
||||
if (message_formatted != NULL) {
|
||||
vsnprintf(message_formatted,
|
||||
(message_formatted_len+sizeof(char)), message, argp_cpy);
|
||||
out = ogs_msprintf("%s%s", source, message_formatted);
|
||||
ogs_free(message_formatted);
|
||||
ogs_free(source);
|
||||
}
|
||||
va_end(argp);
|
||||
va_end(argp_cpy);
|
||||
} else {
|
||||
va_start(argp, message);
|
||||
va_copy(argp_cpy, argp); /* We make a copy because
|
||||
in some architectures,
|
||||
vsnprintf can modify argp */
|
||||
out_len = vsnprintf(NULL, 0, message, argp);
|
||||
out = ogs_malloc(out_len+sizeof(char));
|
||||
if (out != NULL) {
|
||||
vsnprintf(out, (out_len+sizeof(char)), message, argp_cpy);
|
||||
}
|
||||
va_end(argp);
|
||||
va_end(argp_cpy);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,11 @@ void *ogs_memdup(const void *m, size_t n);
|
|||
|
||||
char *ogs_cpystrn(char *dst, const char *src, size_t dst_size);
|
||||
|
||||
char *ogs_msprintf(const char *message, ...)
|
||||
OGS_GNUC_PRINTF(1, 2);
|
||||
char *ogs_mstrcatf(char *source, const char *message, ...)
|
||||
OGS_GNUC_PRINTF(2, 3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -67,6 +67,13 @@ void ogs_gmtime(time_t s, struct tm *tm);
|
|||
void ogs_msleep(time_t msec);
|
||||
void ogs_usleep(time_t usec);
|
||||
|
||||
#define OGS_TIME_ISO8601_FORMATTED_LENGTH 128
|
||||
#define OGS_TIME_ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S%z"
|
||||
|
||||
#define ogs_mktime mktime
|
||||
#define ogs_strptime strptime
|
||||
#define ogs_strftime strftime
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,6 @@ ogs_timer_t *ogs_timer_add(
|
|||
{
|
||||
ogs_timer_t *timer = NULL;
|
||||
ogs_assert(manager);
|
||||
ogs_assert(cb);
|
||||
|
||||
ogs_pool_alloc(&manager->pool, &timer);
|
||||
ogs_assert(timer);
|
||||
|
@ -117,7 +116,7 @@ void ogs_timer_start(ogs_timer_t *timer, ogs_time_t duration)
|
|||
{
|
||||
ogs_timer_mgr_t *manager = NULL;
|
||||
ogs_assert(timer);
|
||||
ogs_assert(duration > 0);
|
||||
ogs_assert(duration);
|
||||
|
||||
manager = timer->manager;
|
||||
ogs_assert(manager);
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "core-config-private.h"
|
||||
|
||||
#if HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "ogs-core.h"
|
||||
|
||||
#define NODE_LENGTH 6
|
||||
|
||||
static int uuid_state_seqnum;
|
||||
static unsigned char uuid_state_node[NODE_LENGTH] = { 0 };
|
||||
|
||||
static void get_random_info(unsigned char node[NODE_LENGTH])
|
||||
{
|
||||
ogs_random(node, NODE_LENGTH);
|
||||
}
|
||||
|
||||
/* This implementation generates a random node ID instead of a
|
||||
system-dependent call to get IEEE node ID. This is also more secure:
|
||||
we aren't passing out our MAC address. */
|
||||
static void get_pseudo_node_identifier(unsigned char *node)
|
||||
{
|
||||
get_random_info(node);
|
||||
node[0] |= 0x01; /* this designates a random multicast node ID */
|
||||
}
|
||||
|
||||
/* true_random -- generate a crypto-quality random number. */
|
||||
static int true_random(void)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
|
||||
ogs_random(buf, 2);
|
||||
return (buf[0] << 8) | buf[1];
|
||||
}
|
||||
|
||||
static void init_state(void)
|
||||
{
|
||||
uuid_state_seqnum = true_random();
|
||||
get_pseudo_node_identifier(uuid_state_node);
|
||||
}
|
||||
|
||||
static void get_system_time(uint64_t *uuid_time)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
/* ### fix this call to be more portable? */
|
||||
ogs_gettimeofday(&tv);
|
||||
*uuid_time = tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec;
|
||||
|
||||
/* Offset between UUID formatted times and Unix formatted times.
|
||||
UUID UTC base time is October 15, 1582.
|
||||
Unix base time is January 1, 1970. */
|
||||
*uuid_time = (*uuid_time * 10) + 0x01B21DD213814000;
|
||||
}
|
||||
|
||||
static void get_current_time(uint64_t *timestamp)
|
||||
{
|
||||
/* ### this needs to be made thread-safe! */
|
||||
|
||||
uint64_t time_now;
|
||||
static uint64_t time_last = 0;
|
||||
static uint64_t fudge = 0;
|
||||
|
||||
get_system_time(&time_now);
|
||||
|
||||
/* if clock reading changed since last UUID generated... */
|
||||
if (time_last != time_now) {
|
||||
/* The clock reading has changed since the last UUID was generated.
|
||||
Reset the fudge factor. if we are generating them too fast, then
|
||||
the fudge may need to be reset to something greater than zero. */
|
||||
if (time_last + fudge > time_now)
|
||||
fudge = time_last + fudge - time_now + 1;
|
||||
else
|
||||
fudge = 0;
|
||||
time_last = time_now;
|
||||
}
|
||||
else {
|
||||
/* We generated two really fast. Bump the fudge factor. */
|
||||
++fudge;
|
||||
}
|
||||
|
||||
*timestamp = time_now + fudge;
|
||||
}
|
||||
|
||||
void ogs_uuid_get(ogs_uuid_t *uuid)
|
||||
{
|
||||
uint64_t timestamp;
|
||||
unsigned char *d = NULL;
|
||||
int version = 4;
|
||||
|
||||
ogs_assert(uuid);
|
||||
d = uuid->data;
|
||||
|
||||
if (!uuid_state_node[0])
|
||||
init_state();
|
||||
|
||||
get_current_time(×tamp);
|
||||
|
||||
/* time_low, uint32 */
|
||||
d[3] = (unsigned char)timestamp;
|
||||
d[2] = (unsigned char)(timestamp >> 8);
|
||||
d[1] = (unsigned char)(timestamp >> 16);
|
||||
d[0] = (unsigned char)(timestamp >> 24);
|
||||
|
||||
/* time_mid, uint16 */
|
||||
d[5] = (unsigned char)(timestamp >> 32);
|
||||
d[4] = (unsigned char)(timestamp >> 40);
|
||||
|
||||
/* Set the four most significant bits (bits 12 through 15) of the
|
||||
* time_hi_and_version field to the 4-bit version number from
|
||||
* Section 4.1.3. */
|
||||
d[7] = (unsigned char)(timestamp >> 48);
|
||||
d[6] = (unsigned char)(((timestamp >> 56) & 0x0F) | (version << 4));
|
||||
|
||||
/* Set the two most significant bits (bits 6 and 7) of the
|
||||
* clock_seq_hi_and_reserved to zero and one, respectively. */
|
||||
d[8] = (unsigned char)(((uuid_state_seqnum >> 8) & 0x3F) | 0x80);
|
||||
|
||||
/* clock_seq_low, uint8 */
|
||||
d[9] = (unsigned char)uuid_state_seqnum;
|
||||
|
||||
/* node, byte[6] */
|
||||
memcpy(&d[10], uuid_state_node, NODE_LENGTH);
|
||||
}
|
||||
|
||||
void ogs_uuid_format(char *buffer, const ogs_uuid_t *uuid)
|
||||
{
|
||||
const unsigned char *d = uuid->data;
|
||||
|
||||
sprintf(buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x%02x%02x%02x%02x",
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||||
}
|
||||
|
||||
/* convert a pair of hex digits to an integer value [0,255] */
|
||||
#if 'A' == 65
|
||||
static unsigned char parse_hexpair(const char *s)
|
||||
{
|
||||
int result;
|
||||
int temp;
|
||||
|
||||
result = s[0] - '0';
|
||||
if (result > 48)
|
||||
result = (result - 39) << 4;
|
||||
else if (result > 16)
|
||||
result = (result - 7) << 4;
|
||||
else
|
||||
result = result << 4;
|
||||
|
||||
temp = s[1] - '0';
|
||||
if (temp > 48)
|
||||
result |= temp - 39;
|
||||
else if (temp > 16)
|
||||
result |= temp - 7;
|
||||
else
|
||||
result |= temp;
|
||||
|
||||
return (unsigned char)result;
|
||||
}
|
||||
#else
|
||||
static unsigned char parse_hexpair(const char *s)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (isdigit(*s)) {
|
||||
result = (*s - '0') << 4;
|
||||
}
|
||||
else {
|
||||
if (isupper(*s)) {
|
||||
result = (*s - 'A' + 10) << 4;
|
||||
}
|
||||
else {
|
||||
result = (*s - 'a' + 10) << 4;
|
||||
}
|
||||
}
|
||||
|
||||
++s;
|
||||
if (isdigit(*s)) {
|
||||
result |= (*s - '0');
|
||||
}
|
||||
else {
|
||||
if (isupper(*s)) {
|
||||
result |= (*s - 'A' + 10);
|
||||
}
|
||||
else {
|
||||
result |= (*s - 'a' + 10);
|
||||
}
|
||||
}
|
||||
|
||||
return (unsigned char)result;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ogs_uuid_parse(ogs_uuid_t *uuid, const char *uuid_str)
|
||||
{
|
||||
int i;
|
||||
unsigned char *d = uuid->data;
|
||||
|
||||
for (i = 0; i < 36; ++i) {
|
||||
char c = uuid_str[i];
|
||||
if (!isxdigit(c) &&
|
||||
!(c == '-' && (i == 8 || i == 13 || i == 18 || i == 23)))
|
||||
/* ### need a better value */
|
||||
return OGS_ERROR;
|
||||
}
|
||||
if (uuid_str[36] != '\0') {
|
||||
/* ### need a better value */
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
d[0] = parse_hexpair(&uuid_str[0]);
|
||||
d[1] = parse_hexpair(&uuid_str[2]);
|
||||
d[2] = parse_hexpair(&uuid_str[4]);
|
||||
d[3] = parse_hexpair(&uuid_str[6]);
|
||||
|
||||
d[4] = parse_hexpair(&uuid_str[9]);
|
||||
d[5] = parse_hexpair(&uuid_str[11]);
|
||||
|
||||
d[6] = parse_hexpair(&uuid_str[14]);
|
||||
d[7] = parse_hexpair(&uuid_str[16]);
|
||||
|
||||
d[8] = parse_hexpair(&uuid_str[19]);
|
||||
d[9] = parse_hexpair(&uuid_str[21]);
|
||||
|
||||
for (i = 6; i--;)
|
||||
d[10 + i] = parse_hexpair(&uuid_str[i*2+24]);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(OGS_CORE_INSIDE) && !defined(OGS_CORE_COMPILATION)
|
||||
#error "This header cannot be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef OGS_UUID_H
|
||||
#define OGS_UUID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OGS_UUID_FORMATTED_LENGTH 36
|
||||
|
||||
typedef struct {
|
||||
unsigned char data[16]; /**< the actual UUID */
|
||||
} ogs_uuid_t;
|
||||
|
||||
void ogs_uuid_get(ogs_uuid_t *uuid);
|
||||
void ogs_uuid_format(char *buffer, const ogs_uuid_t *uuid);
|
||||
int ogs_uuid_parse(ogs_uuid_t *uuid, const char *uuid_str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_UUID_H */
|
|
@ -29,3 +29,4 @@ subdir('s1ap')
|
|||
subdir('nas')
|
||||
subdir('gtp')
|
||||
subdir('pfcp')
|
||||
subdir('sbi')
|
||||
|
|
|
@ -35,12 +35,12 @@ static OGS_POOL(ogs_pfcp_bar_pool, ogs_pfcp_bar_t);
|
|||
static OGS_POOL(ogs_pfcp_dev_pool, ogs_pfcp_dev_t);
|
||||
static OGS_POOL(ogs_pfcp_subnet_pool, ogs_pfcp_subnet_t);
|
||||
|
||||
static int context_initiaized = 0;
|
||||
static int context_initialized = 0;
|
||||
|
||||
void ogs_pfcp_context_init(int num_of_gtpu_resource)
|
||||
{
|
||||
struct timeval tv;
|
||||
ogs_assert(context_initiaized == 0);
|
||||
ogs_assert(context_initialized == 0);
|
||||
|
||||
/* Initialize SMF context */
|
||||
memset(&self, 0, sizeof(ogs_pfcp_context_t));
|
||||
|
@ -88,12 +88,12 @@ void ogs_pfcp_context_init(int num_of_gtpu_resource)
|
|||
|
||||
self.pdr_hash = ogs_hash_make();
|
||||
|
||||
context_initiaized = 1;
|
||||
context_initialized = 1;
|
||||
}
|
||||
|
||||
void ogs_pfcp_context_final(void)
|
||||
{
|
||||
ogs_assert(context_initiaized == 1);
|
||||
ogs_assert(context_initialized == 1);
|
||||
|
||||
ogs_assert(self.pdr_hash);
|
||||
ogs_hash_destroy(self.pdr_hash);
|
||||
|
@ -116,7 +116,7 @@ void ogs_pfcp_context_final(void)
|
|||
ogs_pool_final(&ogs_pfcp_node_pool);
|
||||
ogs_pool_final(&ogs_pfcp_gtpu_resource_pool);
|
||||
|
||||
context_initiaized = 0;
|
||||
context_initialized = 0;
|
||||
}
|
||||
|
||||
ogs_pfcp_context_t *ogs_pfcp_self(void)
|
||||
|
|
|
@ -24,30 +24,29 @@ int ogs_pfcp_sockaddr_to_node_id(
|
|||
ogs_pfcp_node_id_t *node_id, int *len)
|
||||
{
|
||||
const int hdr_len = 1;
|
||||
int rv;
|
||||
char hostname[OGS_MAX_FQDN_LEN];
|
||||
char *hostname = NULL;
|
||||
|
||||
ogs_assert(node_id);
|
||||
|
||||
memset(node_id, 0, sizeof *node_id);
|
||||
|
||||
if (addr && addr->hostname) {
|
||||
rv = ogs_getnameinfo(hostname, OGS_MAX_FQDN_LEN, addr, 0);
|
||||
if (rv == OGS_OK && strcmp(addr->hostname, hostname) == 0) {
|
||||
if (addr) {
|
||||
hostname = ogs_gethostname(addr);
|
||||
if (hostname) {
|
||||
node_id->type = OGS_PFCP_NODE_ID_FQDN;
|
||||
*len = ogs_fqdn_build(node_id->fqdn,
|
||||
addr->hostname, strlen(addr->hostname)) + hdr_len;
|
||||
hostname, strlen(hostname)) + hdr_len;
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr6 && addr6->hostname) {
|
||||
rv = ogs_getnameinfo(hostname, OGS_MAX_FQDN_LEN, addr6, 0);
|
||||
if (rv == OGS_OK && strcmp(addr6->hostname, hostname) == 0) {
|
||||
if (addr6) {
|
||||
hostname = ogs_gethostname(addr6);
|
||||
if (hostname) {
|
||||
node_id->type = OGS_PFCP_NODE_ID_FQDN;
|
||||
*len = ogs_fqdn_build(node_id->fqdn,
|
||||
addr6->hostname, strlen(addr6->hostname)) + hdr_len;
|
||||
hostname, strlen(hostname)) + hdr_len;
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,674 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ogs-app.h"
|
||||
#include "ogs-sbi.h"
|
||||
|
||||
#include "sbi-private.h"
|
||||
#include "curl/curl.h"
|
||||
|
||||
typedef struct sockinfo_s {
|
||||
ogs_poll_t *poll;
|
||||
curl_socket_t sockfd;
|
||||
int action;
|
||||
CURL *easy;
|
||||
ogs_sbi_client_t *client;
|
||||
} sockinfo_t;
|
||||
|
||||
typedef struct connection_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
void *data;
|
||||
|
||||
char *method;
|
||||
|
||||
int num_of_header;
|
||||
char **headers;
|
||||
struct curl_slist *header_list;
|
||||
|
||||
char *memory;
|
||||
size_t size;
|
||||
|
||||
ogs_timer_t *timer;
|
||||
CURL *easy;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
|
||||
ogs_sbi_client_t *client;
|
||||
} connection_t;
|
||||
|
||||
static OGS_POOL(client_pool, ogs_sbi_client_t);
|
||||
static OGS_POOL(sockinfo_pool, sockinfo_t);
|
||||
static OGS_POOL(connection_pool, connection_t);
|
||||
|
||||
static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data);
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp);
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, void *cbp);
|
||||
static void multi_timer_expired(void *data);
|
||||
static void connection_timer_expired(void *data);
|
||||
static void connection_remove_all(ogs_sbi_client_t *client);
|
||||
|
||||
void ogs_sbi_client_init(int num_of_sockinfo_pool, int num_of_connection_pool)
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
ogs_list_init(&ogs_sbi_self()->client_list);
|
||||
ogs_pool_init(&client_pool, ogs_config()->pool.sbi);
|
||||
|
||||
ogs_pool_init(&sockinfo_pool, num_of_sockinfo_pool);
|
||||
ogs_pool_init(&connection_pool, num_of_connection_pool);
|
||||
|
||||
}
|
||||
void ogs_sbi_client_final(void)
|
||||
{
|
||||
ogs_sbi_client_remove_all();
|
||||
|
||||
ogs_pool_final(&client_pool);
|
||||
ogs_pool_final(&sockinfo_pool);
|
||||
ogs_pool_final(&connection_pool);
|
||||
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_client_add(ogs_sockaddr_t *addr)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
CURLM *multi = NULL;
|
||||
|
||||
ogs_assert(addr);
|
||||
|
||||
ogs_pool_alloc(&client_pool, &client);
|
||||
ogs_assert(client);
|
||||
memset(client, 0, sizeof(ogs_sbi_client_t));
|
||||
|
||||
ogs_copyaddrinfo(&client->addr, addr);
|
||||
|
||||
ogs_list_init(&client->connection_list);
|
||||
|
||||
client->t_curl = ogs_timer_add(
|
||||
ogs_sbi_self()->timer_mgr, multi_timer_expired, client);
|
||||
|
||||
multi = client->multi = curl_multi_init();
|
||||
ogs_assert(multi);
|
||||
curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, client);
|
||||
curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(multi, CURLMOPT_TIMERDATA, client);
|
||||
|
||||
ogs_list_add(&ogs_sbi_self()->client_list, client);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_client_find_or_add(char *url)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
struct yuarel yuarel;
|
||||
char *p = ogs_strdup(url);
|
||||
int port;
|
||||
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
|
||||
rv = yuarel_parse(&yuarel, p);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_free(p);
|
||||
ogs_error("yuarel_parse() failed [%s]", url);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!yuarel.scheme) {
|
||||
ogs_error("No http.scheme found [%s]", url);
|
||||
ogs_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(yuarel.scheme, "https") == 0) {
|
||||
port = OGS_SBI_HTTPS_PORT;
|
||||
} else if (strcmp(yuarel.scheme, "http") == 0) {
|
||||
port = OGS_SBI_HTTP_PORT;
|
||||
} else {
|
||||
ogs_error("Invalid http.scheme [%s:%s]", yuarel.scheme, url);
|
||||
ogs_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!yuarel.host) {
|
||||
ogs_error("No http.host found [%s]", url);
|
||||
ogs_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (yuarel.port) port = yuarel.port;
|
||||
|
||||
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, yuarel.host, port, 0);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("ogs_getaddrinfo() failed [%s]", url);
|
||||
ogs_free(p);
|
||||
}
|
||||
|
||||
client = ogs_sbi_client_find(addr);
|
||||
if (!client) {
|
||||
client = ogs_sbi_client_add(addr);
|
||||
ogs_assert(client);
|
||||
}
|
||||
|
||||
ogs_freeaddrinfo(addr);
|
||||
ogs_free(p);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
void ogs_sbi_client_remove(ogs_sbi_client_t *client)
|
||||
{
|
||||
ogs_assert(client);
|
||||
|
||||
ogs_list_remove(&ogs_sbi_self()->client_list, client);
|
||||
|
||||
connection_remove_all(client);
|
||||
|
||||
ogs_assert(client->t_curl);
|
||||
ogs_timer_delete(client->t_curl);
|
||||
|
||||
ogs_assert(client->multi);
|
||||
curl_multi_cleanup(client->multi);
|
||||
|
||||
ogs_assert(client->addr);
|
||||
ogs_freeaddrinfo(client->addr);
|
||||
|
||||
ogs_pool_free(&client_pool, client);
|
||||
}
|
||||
|
||||
void ogs_sbi_client_remove_all(void)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL, *next_client = NULL;
|
||||
|
||||
ogs_list_for_each_safe(&ogs_sbi_self()->client_list, next_client, client)
|
||||
ogs_sbi_client_remove(client);
|
||||
}
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_client_find(ogs_sockaddr_t *addr)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
|
||||
ogs_assert(addr);
|
||||
|
||||
ogs_list_for_each(&ogs_sbi_self()->client_list, client) {
|
||||
if (ogs_sockaddr_is_equal(client->addr, addr) == true)
|
||||
break;
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
#define mycase(code) \
|
||||
case code: s = __STRING(code)
|
||||
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if(CURLM_OK != code) {
|
||||
const char *s;
|
||||
switch(code) {
|
||||
mycase(CURLM_BAD_HANDLE); break;
|
||||
mycase(CURLM_BAD_EASY_HANDLE); break;
|
||||
mycase(CURLM_OUT_OF_MEMORY); break;
|
||||
mycase(CURLM_INTERNAL_ERROR); break;
|
||||
mycase(CURLM_UNKNOWN_OPTION); break;
|
||||
mycase(CURLM_LAST); break;
|
||||
default: s = "CURLM_unknown"; break;
|
||||
mycase(CURLM_BAD_SOCKET);
|
||||
ogs_error("ERROR: %s returns %s", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
ogs_fatal("ERROR: %s returns %s", where, s);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static char *add_params_to_url(CURL *easy, char *url, ogs_hash_t *params)
|
||||
{
|
||||
ogs_hash_index_t *hi;
|
||||
int has_params = 0;
|
||||
const char *fp = "?", *np = "&";
|
||||
|
||||
ogs_assert(easy);
|
||||
ogs_assert(url);
|
||||
ogs_assert(params);
|
||||
ogs_assert(ogs_hash_count(params));
|
||||
|
||||
has_params = (strchr(url, '?') != NULL);
|
||||
|
||||
for (hi = ogs_hash_first(params); hi; hi = ogs_hash_next(hi)) {
|
||||
const char *key = NULL;
|
||||
char *key_esc = NULL;
|
||||
char *val = NULL;
|
||||
char *val_esc = NULL;
|
||||
|
||||
key = ogs_hash_this_key(hi);
|
||||
ogs_assert(key);
|
||||
val = ogs_hash_this_val(hi);
|
||||
ogs_assert(val);
|
||||
|
||||
key_esc = curl_easy_escape(easy, key, 0);
|
||||
ogs_assert(key_esc);
|
||||
val_esc = curl_easy_escape(easy, val, 0);
|
||||
ogs_assert(val_esc);
|
||||
|
||||
if (!has_params) {
|
||||
url = ogs_mstrcatf(url, "%s%s=%s", fp, key_esc, val_esc);
|
||||
has_params = 1;
|
||||
} else {
|
||||
url = ogs_mstrcatf(url, "%s%s=%s", np, key_esc, val_esc);
|
||||
}
|
||||
|
||||
curl_free(val_esc);
|
||||
curl_free(key_esc);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
static connection_t *connection_add(ogs_sbi_client_t *client,
|
||||
ogs_sbi_request_t *request, void *data)
|
||||
{
|
||||
ogs_hash_index_t *hi;
|
||||
int i;
|
||||
connection_t *conn = NULL;
|
||||
CURLMcode rc;
|
||||
|
||||
ogs_assert(client);
|
||||
ogs_assert(request);
|
||||
|
||||
ogs_pool_alloc(&connection_pool, &conn);
|
||||
ogs_assert(conn);
|
||||
memset(conn, 0, sizeof(connection_t));
|
||||
|
||||
ogs_assert(request->h.method);
|
||||
conn->method = ogs_strdup(request->h.method);
|
||||
|
||||
conn->num_of_header = ogs_hash_count(request->http.headers);
|
||||
if (conn->num_of_header) {
|
||||
conn->headers = ogs_calloc(conn->num_of_header, sizeof(char *));
|
||||
ogs_assert(conn->headers);
|
||||
for (hi = ogs_hash_first(request->http.headers), i = 0;
|
||||
hi && i < conn->num_of_header; hi = ogs_hash_next(hi), i++) {
|
||||
const char *key = ogs_hash_this_key(hi);
|
||||
char *val = ogs_hash_this_val(hi);
|
||||
|
||||
conn->headers[i] = ogs_msprintf("%s: %s", key, val);
|
||||
ogs_assert(conn->headers[i]);
|
||||
conn->header_list = curl_slist_append(
|
||||
conn->header_list, conn->headers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
conn->timer = ogs_timer_add(
|
||||
ogs_sbi_self()->timer_mgr, connection_timer_expired, conn);
|
||||
ogs_assert(conn->timer);
|
||||
|
||||
/* If http response is not received within 1 second,
|
||||
* we will discard this request. */
|
||||
ogs_timer_start(conn->timer, ogs_time_from_sec(1));
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
ogs_assert(conn->easy);
|
||||
|
||||
/* HTTP Method */
|
||||
if (strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PUT) == 0 ||
|
||||
strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PATCH) == 0 ||
|
||||
strcmp(request->h.method, OGS_SBI_HTTP_METHOD_DELETE) == 0 ||
|
||||
strcmp(request->h.method, OGS_SBI_HTTP_METHOD_POST) == 0) {
|
||||
|
||||
curl_easy_setopt(conn->easy, CURLOPT_CUSTOMREQUEST, request->h.method);
|
||||
if (request->http.content) {
|
||||
curl_easy_setopt(conn->easy, CURLOPT_HTTPHEADER, conn->header_list);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_POSTFIELDS,
|
||||
request->http.content);
|
||||
}
|
||||
}
|
||||
|
||||
if (ogs_hash_count(request->http.params)) {
|
||||
request->h.url = add_params_to_url(conn->easy,
|
||||
request->h.url, request->http.params);
|
||||
}
|
||||
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, request->h.url);
|
||||
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
|
||||
ogs_assert(client->multi);
|
||||
rc = curl_multi_add_handle(client->multi, conn->easy);
|
||||
mcode_or_die("connection_add: curl_multi_add_handle", rc);
|
||||
|
||||
conn->client = client;
|
||||
conn->data = data;
|
||||
|
||||
ogs_list_add(&client->connection_list, conn);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
static void connection_remove(connection_t *conn)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
int i;
|
||||
|
||||
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->num_of_header) {
|
||||
for (i = 0; i < conn->num_of_header; i++)
|
||||
ogs_free(conn->headers[i]);
|
||||
ogs_free(conn->headers);
|
||||
}
|
||||
curl_slist_free_all(conn->header_list);
|
||||
|
||||
if (conn->memory)
|
||||
ogs_free(conn->memory);
|
||||
|
||||
ogs_pool_free(&connection_pool, conn);
|
||||
}
|
||||
|
||||
static void connection_remove_all(ogs_sbi_client_t *client)
|
||||
{
|
||||
connection_t *conn = NULL, *next_conn = NULL;
|
||||
|
||||
ogs_assert(client);
|
||||
|
||||
ogs_list_for_each_safe(&client->connection_list, next_conn, conn)
|
||||
connection_remove(conn);
|
||||
}
|
||||
|
||||
static void connection_timer_expired(void *data)
|
||||
{
|
||||
connection_t *conn = NULL;
|
||||
|
||||
conn = data;
|
||||
ogs_assert(conn);
|
||||
|
||||
connection_remove(conn);
|
||||
}
|
||||
|
||||
static void check_multi_info(ogs_sbi_client_t *client)
|
||||
{
|
||||
CURLM *multi = NULL;
|
||||
CURLMsg *resource;
|
||||
int pending;
|
||||
CURL *easy = NULL;
|
||||
CURLcode res;
|
||||
connection_t *conn = NULL;
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
ogs_assert(client);
|
||||
multi = client->multi;
|
||||
ogs_assert(multi);
|
||||
|
||||
while ((resource = curl_multi_info_read(multi, &pending))) {
|
||||
char *url;
|
||||
char *content_type = NULL;
|
||||
long res_status;
|
||||
ogs_assert(resource);
|
||||
|
||||
switch (resource->msg) {
|
||||
case CURLMSG_DONE:
|
||||
easy = resource->easy_handle;
|
||||
ogs_assert(easy);
|
||||
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
ogs_assert(conn);
|
||||
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &url);
|
||||
curl_easy_getinfo(easy, CURLINFO_RESPONSE_CODE, &res_status);
|
||||
curl_easy_getinfo(easy, CURLINFO_CONTENT_TYPE, &content_type);
|
||||
|
||||
res = resource->data.result;
|
||||
if (res == CURLE_OK) {
|
||||
response = ogs_sbi_response_new();
|
||||
ogs_assert(response);
|
||||
|
||||
response->status = res_status;
|
||||
|
||||
ogs_assert(conn->method);
|
||||
response->h.method = ogs_strdup(conn->method);
|
||||
|
||||
/* remove https://localhost:8000 */
|
||||
response->h.url = ogs_strdup(url);
|
||||
|
||||
response->http.content = ogs_strdup(conn->memory);
|
||||
response->http.content_length = conn->size;
|
||||
|
||||
if (content_type)
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
"Content-Type", content_type);
|
||||
|
||||
if (client->cb)
|
||||
client->cb(response, conn->data);
|
||||
else {
|
||||
ogs_fatal("client callback is not registered");
|
||||
ogs_sbi_response_free(response);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
} else
|
||||
ogs_warn("[%d] %s", res, conn->error);
|
||||
|
||||
connection_remove(conn);
|
||||
break;
|
||||
default:
|
||||
ogs_error("Unknown CURL resource[%d]", resource->msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ogs_sbi_client_send_request(
|
||||
ogs_sbi_client_t *client, ogs_sbi_request_t *request, void *data)
|
||||
{
|
||||
connection_t *conn = NULL;
|
||||
|
||||
ogs_assert(client);
|
||||
ogs_assert(request);
|
||||
|
||||
if (request->h.url == NULL) {
|
||||
request->h.url = ogs_sbi_client_uri(client,
|
||||
request->h.service.name, request->h.api.version,
|
||||
request->h.resource.name, request->h.resource.id);
|
||||
}
|
||||
|
||||
conn = connection_add(client, request, data);
|
||||
ogs_assert(conn);
|
||||
ogs_sbi_request_free(request);
|
||||
}
|
||||
|
||||
static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = 0;
|
||||
connection_t *conn = NULL;
|
||||
char *ptr = NULL;
|
||||
|
||||
conn = data;
|
||||
ogs_assert(conn);
|
||||
|
||||
realsize = size * nmemb;
|
||||
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
ogs_fatal("not enough memory (realloc returned NULL)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
conn->memory = ptr;
|
||||
memcpy(&(conn->memory[conn->size]), contents, realsize);
|
||||
conn->size += realsize;
|
||||
conn->memory[conn->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
static void event_cb(short when, ogs_socket_t fd, void *data)
|
||||
{
|
||||
sockinfo_t *sockinfo = NULL;
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
CURLM *multi = NULL;
|
||||
|
||||
CURLMcode rc;
|
||||
int action = ((when & OGS_POLLIN) ? CURL_CSELECT_IN : 0) |
|
||||
((when & OGS_POLLOUT) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
sockinfo = data;
|
||||
ogs_assert(sockinfo);
|
||||
client = sockinfo->client;
|
||||
ogs_assert(client);
|
||||
multi = client->multi;
|
||||
ogs_assert(multi);
|
||||
|
||||
rc = curl_multi_socket_action(multi, fd, action, &client->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(client);
|
||||
if (client->still_running <= 0) {
|
||||
ogs_timer_t *timer;
|
||||
|
||||
timer = client->t_curl;
|
||||
ogs_assert(timer);
|
||||
ogs_timer_stop(timer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign information to a sockinfo_t structure */
|
||||
static void sock_set(sockinfo_t *sockinfo, curl_socket_t s,
|
||||
CURL *e, int act, ogs_sbi_client_t *client)
|
||||
{
|
||||
int kind = ((act & CURL_POLL_IN) ? OGS_POLLIN : 0) |
|
||||
((act & CURL_POLL_OUT) ? OGS_POLLOUT : 0);
|
||||
|
||||
if (sockinfo->sockfd)
|
||||
ogs_pollset_remove(sockinfo->poll);
|
||||
|
||||
sockinfo->sockfd = s;
|
||||
sockinfo->action = act;
|
||||
sockinfo->easy = e;
|
||||
|
||||
sockinfo->poll = ogs_pollset_add(
|
||||
ogs_sbi_self()->pollset, kind, s, event_cb, sockinfo);
|
||||
}
|
||||
|
||||
/* Initialize a new sockinfo_t structure */
|
||||
static void sock_new(curl_socket_t s,
|
||||
CURL *easy, int action, ogs_sbi_client_t *client)
|
||||
{
|
||||
sockinfo_t *sockinfo = NULL;
|
||||
CURLM *multi = NULL;
|
||||
|
||||
ogs_assert(client);
|
||||
multi = client->multi;
|
||||
ogs_assert(multi);
|
||||
|
||||
ogs_pool_alloc(&sockinfo_pool, &sockinfo);
|
||||
ogs_assert(sockinfo);
|
||||
memset(sockinfo, 0, sizeof(sockinfo_t));
|
||||
|
||||
sockinfo->client = client;
|
||||
sock_set(sockinfo, s, easy, action, client);
|
||||
curl_multi_assign(multi, s, sockinfo);
|
||||
}
|
||||
|
||||
/* Clean up the sockinfo_t structure */
|
||||
static void sock_free(sockinfo_t *sockinfo, ogs_sbi_client_t *client)
|
||||
{
|
||||
ogs_assert(sockinfo);
|
||||
ogs_assert(sockinfo->poll);
|
||||
|
||||
ogs_pollset_remove(sockinfo->poll);
|
||||
ogs_pool_free(&sockinfo_pool, sockinfo);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
ogs_sbi_client_t *client = (ogs_sbi_client_t *)cbp;
|
||||
sockinfo_t *sockinfo = (sockinfo_t *) sockp;
|
||||
|
||||
if (what == CURL_POLL_REMOVE) {
|
||||
sock_free(sockinfo, client);
|
||||
} else {
|
||||
if (!sockinfo) {
|
||||
sock_new(s, e, what, client);
|
||||
} else {
|
||||
sock_set(sockinfo, s, e, what, client);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void multi_timer_expired(void *data)
|
||||
{
|
||||
CURLMcode rc;
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
CURLM *multi = NULL;
|
||||
|
||||
client = data;
|
||||
ogs_assert(client);
|
||||
multi = client->multi;
|
||||
ogs_assert(multi);
|
||||
|
||||
rc = curl_multi_socket_action(
|
||||
multi, CURL_SOCKET_TIMEOUT, 0, &client->still_running);
|
||||
mcode_or_die("multi_timer_expired: curl_multi_socket_action", rc);
|
||||
check_multi_info(client);
|
||||
}
|
||||
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, void *cbp)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
ogs_timer_t *timer = NULL;
|
||||
|
||||
client = cbp;
|
||||
ogs_assert(client);
|
||||
timer = client->t_curl;
|
||||
ogs_assert(timer);
|
||||
|
||||
if (timeout_ms > 0) {
|
||||
ogs_timer_start(timer, ogs_time_from_msec(timeout_ms));
|
||||
} else if (timeout_ms == 0) {
|
||||
/* libcurl wants us to timeout now.
|
||||
* The closest we can do is to schedule the timer to fire in 1 us. */
|
||||
ogs_timer_start(timer, 1);
|
||||
} else {
|
||||
ogs_timer_stop(timer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
|
||||
#error "This header cannot be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef OGS_SBI_CLIENT_H
|
||||
#define OGS_SBI_CLIENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OGS_SETUP_SBI_CLIENT(__cTX, __pCLIENT) \
|
||||
do { \
|
||||
ogs_assert((__cTX)); \
|
||||
ogs_assert((__pCLIENT)); \
|
||||
(__cTX)->client = __pCLIENT; \
|
||||
} while(0)
|
||||
typedef struct ogs_sbi_client_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
ogs_sockaddr_t *addr;
|
||||
|
||||
struct {
|
||||
const char *key;
|
||||
const char *pem;
|
||||
} tls;
|
||||
|
||||
int (*cb)(ogs_sbi_response_t *response, void *data);
|
||||
|
||||
ogs_timer_t *t_curl; /* timer for CURL */
|
||||
ogs_list_t connection_list; /* CURL connection list */
|
||||
|
||||
void *multi; /* CURL multi handle */
|
||||
int still_running; /* number of running CURL handle */
|
||||
} ogs_sbi_client_t;
|
||||
|
||||
void ogs_sbi_client_init(int num_of_sockinfo_pool, int num_of_connection_pool);
|
||||
void ogs_sbi_client_final(void);
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_client_add(ogs_sockaddr_t *addr);
|
||||
ogs_sbi_client_t *ogs_sbi_client_find_or_add(char *uri);
|
||||
void ogs_sbi_client_remove(ogs_sbi_client_t *client);
|
||||
void ogs_sbi_client_remove_all(void);
|
||||
ogs_sbi_client_t *ogs_sbi_client_find(ogs_sockaddr_t *addr);
|
||||
|
||||
void ogs_sbi_client_send_request(
|
||||
ogs_sbi_client_t *client, ogs_sbi_request_t *request, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_CLIENT_H */
|
|
@ -0,0 +1,903 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "app/ogs-app.h"
|
||||
#include "ogs-sbi.h"
|
||||
|
||||
int __ogs_sbi_domain;
|
||||
|
||||
static OGS_POOL(nf_instance_pool, ogs_sbi_nf_instance_t);
|
||||
static OGS_POOL(nf_service_pool, ogs_sbi_nf_service_t);
|
||||
static OGS_POOL(subscription_pool, ogs_sbi_subscription_t);
|
||||
|
||||
static ogs_sbi_context_t self;
|
||||
|
||||
static int context_initialized = 0;
|
||||
|
||||
void ogs_sbi_context_init(ogs_pollset_t *pollset, ogs_timer_mgr_t *timer_mgr)
|
||||
{
|
||||
ogs_assert(context_initialized == 0);
|
||||
|
||||
/* Initialize SMF context */
|
||||
memset(&self, 0, sizeof(ogs_sbi_context_t));
|
||||
|
||||
ogs_assert(pollset);
|
||||
self.pollset = pollset;
|
||||
ogs_assert(timer_mgr);
|
||||
self.timer_mgr = timer_mgr;
|
||||
|
||||
ogs_log_install_domain(&__ogs_sbi_domain, "sbi", ogs_core()->log.level);
|
||||
|
||||
/* FIXME : number of pool size */
|
||||
ogs_sbi_message_init(32, 32);
|
||||
ogs_sbi_server_init(32);
|
||||
ogs_sbi_client_init(512, 512);
|
||||
|
||||
ogs_list_init(&self.nf_instance_list);
|
||||
ogs_pool_init(&nf_instance_pool, ogs_config()->pool.sbi);
|
||||
ogs_pool_init(&nf_service_pool, ogs_config()->pool.sbi);
|
||||
|
||||
ogs_list_init(&self.subscription_list);
|
||||
ogs_pool_init(&subscription_pool, ogs_config()->pool.sbi);
|
||||
|
||||
ogs_uuid_get(&self.uuid);
|
||||
ogs_uuid_format(self.nf_instance_id, &self.uuid);
|
||||
|
||||
context_initialized = 1;
|
||||
}
|
||||
|
||||
void ogs_sbi_context_final(void)
|
||||
{
|
||||
ogs_assert(context_initialized == 1);
|
||||
|
||||
ogs_sbi_subscription_remove_all();
|
||||
ogs_pool_final(&subscription_pool);
|
||||
|
||||
ogs_sbi_nf_instance_remove_all();
|
||||
ogs_pool_final(&nf_instance_pool);
|
||||
ogs_pool_final(&nf_service_pool);
|
||||
|
||||
ogs_sbi_client_final();
|
||||
ogs_sbi_server_final();
|
||||
ogs_sbi_message_final();
|
||||
|
||||
context_initialized = 0;
|
||||
}
|
||||
|
||||
ogs_sbi_context_t *ogs_sbi_self(void)
|
||||
{
|
||||
return &self;
|
||||
}
|
||||
|
||||
static int ogs_sbi_context_prepare(void)
|
||||
{
|
||||
self.http_port = OGS_SBI_HTTP_PORT;
|
||||
self.https_port = OGS_SBI_HTTPS_PORT;
|
||||
|
||||
self.content_encoding = "gzip";
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
static int ogs_sbi_context_validation(const char *local)
|
||||
{
|
||||
if (ogs_list_first(&self.server_list) == NULL) {
|
||||
ogs_error("No %s.sbi: in '%s'", local, ogs_config()->file);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int ogs_sbi_context_parse_config(const char *local, const char *remote)
|
||||
{
|
||||
int rv;
|
||||
yaml_document_t *document = NULL;
|
||||
ogs_yaml_iter_t root_iter;
|
||||
|
||||
document = ogs_config()->document;
|
||||
ogs_assert(document);
|
||||
|
||||
rv = ogs_sbi_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 (local && !strcmp(root_key, local)) {
|
||||
ogs_yaml_iter_t local_iter;
|
||||
ogs_yaml_iter_recurse(&root_iter, &local_iter);
|
||||
while (ogs_yaml_iter_next(&local_iter)) {
|
||||
const char *local_key = ogs_yaml_iter_key(&local_iter);
|
||||
ogs_assert(local_key);
|
||||
if (!strcmp(local_key, "sbi")) {
|
||||
ogs_list_t list, list6;
|
||||
ogs_socknode_t *node = NULL, *node6 = NULL;
|
||||
|
||||
ogs_yaml_iter_t sbi_array, sbi_iter;
|
||||
ogs_yaml_iter_recurse(&local_iter, &sbi_array);
|
||||
do {
|
||||
int family = AF_UNSPEC;
|
||||
int i, num = 0;
|
||||
const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
|
||||
uint16_t port = self.http_port;
|
||||
const char *dev = NULL;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
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);
|
||||
self.http_port = port;
|
||||
}
|
||||
} else if (!strcmp(sbi_key, "dev")) {
|
||||
dev = ogs_yaml_iter_value(&sbi_iter);
|
||||
} 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
|
||||
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_list_init(&list);
|
||||
ogs_list_init(&list6);
|
||||
|
||||
if (addr) {
|
||||
if (ogs_config()->parameter.no_ipv4 == 0)
|
||||
ogs_socknode_add(&list, AF_INET, addr);
|
||||
if (ogs_config()->parameter.no_ipv6 == 0)
|
||||
ogs_socknode_add(&list6, AF_INET6, addr);
|
||||
ogs_freeaddrinfo(addr);
|
||||
}
|
||||
|
||||
if (dev) {
|
||||
rv = ogs_socknode_probe(
|
||||
ogs_config()->parameter.no_ipv4 ? NULL : &list,
|
||||
ogs_config()->parameter.no_ipv6 ? NULL : &list6,
|
||||
dev, port);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
}
|
||||
|
||||
node = ogs_list_first(&list);
|
||||
if (node) {
|
||||
ogs_sbi_server_t *server =
|
||||
ogs_sbi_server_add(node->addr);
|
||||
ogs_assert(server);
|
||||
|
||||
if (key) server->tls.key = key;
|
||||
if (pem) server->tls.pem = pem;
|
||||
}
|
||||
node6 = ogs_list_first(&list6);
|
||||
if (node6) {
|
||||
ogs_sbi_server_t *server =
|
||||
ogs_sbi_server_add(node6->addr);
|
||||
ogs_assert(server);
|
||||
|
||||
if (key) server->tls.key = key;
|
||||
if (pem) server->tls.pem = pem;
|
||||
}
|
||||
|
||||
ogs_socknode_remove_all(&list);
|
||||
ogs_socknode_remove_all(&list6);
|
||||
} while (ogs_yaml_iter_type(&sbi_array) ==
|
||||
YAML_SEQUENCE_NODE);
|
||||
|
||||
if (ogs_list_first(&self.server_list) == 0) {
|
||||
ogs_list_init(&list);
|
||||
ogs_list_init(&list6);
|
||||
|
||||
rv = ogs_socknode_probe(
|
||||
ogs_config()->parameter.no_ipv4 ? NULL : &list,
|
||||
ogs_config()->parameter.no_ipv6 ? NULL : &list6,
|
||||
NULL, self.http_port);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
node = ogs_list_first(&list);
|
||||
if (node) ogs_sbi_server_add(node->addr);
|
||||
node6 = ogs_list_first(&list6);
|
||||
if (node6) ogs_sbi_server_add(node6->addr);
|
||||
|
||||
ogs_socknode_remove_all(&list);
|
||||
ogs_socknode_remove_all(&list6);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (remote && !strcmp(root_key, remote)) {
|
||||
ogs_yaml_iter_t remote_iter;
|
||||
ogs_yaml_iter_recurse(&root_iter, &remote_iter);
|
||||
while (ogs_yaml_iter_next(&remote_iter)) {
|
||||
const char *remote_key = ogs_yaml_iter_key(&remote_iter);
|
||||
ogs_assert(remote_key);
|
||||
if (!strcmp(remote_key, "sbi")) {
|
||||
ogs_yaml_iter_t sbi_array, sbi_iter;
|
||||
ogs_yaml_iter_recurse(&remote_iter, &sbi_array);
|
||||
do {
|
||||
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.http_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
|
||||
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_config()->parameter.no_ipv4,
|
||||
ogs_config()->parameter.no_ipv6,
|
||||
ogs_config()->parameter.prefer_ipv4);
|
||||
client = ogs_sbi_client_add(addr);
|
||||
ogs_assert(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = ogs_sbi_context_validation(local);
|
||||
if (rv != OGS_OK) return rv;
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(char *id)
|
||||
{
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
|
||||
ogs_assert(id);
|
||||
|
||||
ogs_pool_alloc(&nf_instance_pool, &nf_instance);
|
||||
ogs_assert(nf_instance);
|
||||
memset(nf_instance, 0, sizeof(ogs_sbi_nf_instance_t));
|
||||
|
||||
nf_instance->id = ogs_strdup(id);
|
||||
ogs_assert(nf_instance->id);
|
||||
|
||||
nf_instance->time.heartbeat = ogs_config()->time.nf_instance.heartbeat;
|
||||
|
||||
ogs_list_add(&ogs_sbi_self()->nf_instance_list, nf_instance);
|
||||
|
||||
return nf_instance;
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_instance_clear(ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
int i;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
for (i = 0; i < nf_instance->num_of_ipv4; i++) {
|
||||
if (nf_instance->ipv4[i])
|
||||
ogs_freeaddrinfo(nf_instance->ipv4[i]);
|
||||
}
|
||||
for (i = 0; i < nf_instance->num_of_ipv6; i++) {
|
||||
if (nf_instance->ipv6[i])
|
||||
ogs_freeaddrinfo(nf_instance->ipv6[i]);
|
||||
}
|
||||
|
||||
|
||||
ogs_sbi_nf_service_remove_all(nf_instance);
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_instance_remove(ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
ogs_list_remove(&ogs_sbi_self()->nf_instance_list, nf_instance);
|
||||
|
||||
ogs_sbi_subscription_remove_all_by_nf_instance_id(nf_instance->id);
|
||||
|
||||
ogs_assert(nf_instance->id);
|
||||
ogs_free(nf_instance->id);
|
||||
|
||||
ogs_sbi_nf_instance_clear(nf_instance);
|
||||
|
||||
ogs_pool_free(&nf_instance_pool, nf_instance);
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_instance_remove_all(void)
|
||||
{
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL, *next_nf_instance = NULL;
|
||||
|
||||
ogs_list_for_each_safe(
|
||||
&ogs_sbi_self()->nf_instance_list, next_nf_instance, nf_instance)
|
||||
ogs_sbi_nf_instance_remove(nf_instance);
|
||||
}
|
||||
|
||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_find(char *id)
|
||||
{
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
|
||||
ogs_assert(id);
|
||||
|
||||
ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) {
|
||||
ogs_assert(nf_instance->id);
|
||||
if (strcmp(nf_instance->id, id) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return nf_instance;
|
||||
}
|
||||
|
||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_build_default(
|
||||
OpenAPI_nf_type_e nf_type, ogs_sbi_client_t *client)
|
||||
{
|
||||
ogs_sbi_server_t *server = NULL;
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
char *hostname = NULL;
|
||||
|
||||
nf_instance = ogs_sbi_nf_instance_add(ogs_sbi_self()->nf_instance_id);
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
nf_instance->nf_type = nf_type;
|
||||
nf_instance->nf_status = OpenAPI_nf_status_REGISTERED;
|
||||
OGS_SETUP_SBI_CLIENT(nf_instance, client);
|
||||
|
||||
hostname = NULL;
|
||||
ogs_list_for_each(&ogs_sbi_self()->server_list, server) {
|
||||
ogs_assert(server->addr);
|
||||
|
||||
/* First FQDN is selected */
|
||||
if (!hostname) {
|
||||
hostname = ogs_gethostname(server->addr);
|
||||
if (hostname)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
ogs_copyaddrinfo(&addr, server->addr);
|
||||
ogs_assert(addr);
|
||||
|
||||
if (addr->ogs_sa_family == AF_INET) {
|
||||
nf_instance->ipv4[nf_instance->num_of_ipv4] = addr;
|
||||
nf_instance->num_of_ipv4++;
|
||||
} else if (addr->ogs_sa_family == AF_INET6) {
|
||||
nf_instance->ipv6[nf_instance->num_of_ipv6] = addr;
|
||||
nf_instance->num_of_ipv6++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
}
|
||||
|
||||
if (hostname)
|
||||
strcpy(nf_instance->fqdn, hostname);
|
||||
|
||||
return nf_instance;
|
||||
}
|
||||
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_add(ogs_sbi_nf_instance_t *nf_instance,
|
||||
char *id, char *name, OpenAPI_uri_scheme_e scheme)
|
||||
{
|
||||
ogs_sbi_nf_service_t *nf_service = NULL;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(id);
|
||||
ogs_assert(name);
|
||||
|
||||
ogs_pool_alloc(&nf_service_pool, &nf_service);
|
||||
ogs_assert(nf_service);
|
||||
memset(nf_service, 0, sizeof(ogs_sbi_nf_service_t));
|
||||
|
||||
nf_service->id = ogs_strdup(id);
|
||||
ogs_assert(nf_service->id);
|
||||
nf_service->name = ogs_strdup(name);
|
||||
ogs_assert(nf_service->name);
|
||||
nf_service->scheme = scheme;
|
||||
|
||||
nf_service->status = OpenAPI_nf_service_status_REGISTERED;
|
||||
|
||||
nf_service->nf_instance = nf_instance;
|
||||
|
||||
ogs_list_add(&nf_instance->nf_service_list, nf_service);
|
||||
|
||||
return nf_service;
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_service_add_version(ogs_sbi_nf_service_t *nf_service,
|
||||
char *in_uri, char *full, char *expiry)
|
||||
{
|
||||
ogs_assert(nf_service);
|
||||
|
||||
ogs_assert(in_uri);
|
||||
ogs_assert(full);
|
||||
|
||||
if (nf_service->num_of_version < OGS_SBI_MAX_NUM_OF_SERVICE_VERSION) {
|
||||
nf_service->versions[nf_service->num_of_version].in_uri =
|
||||
ogs_strdup(in_uri);
|
||||
nf_service->versions[nf_service->num_of_version].full =
|
||||
ogs_strdup(full);
|
||||
if (expiry)
|
||||
nf_service->versions[nf_service->num_of_version].expiry =
|
||||
ogs_strdup(expiry);
|
||||
nf_service->num_of_version++;
|
||||
}
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_service_remove(ogs_sbi_nf_instance_t *nf_instance,
|
||||
ogs_sbi_nf_service_t *nf_service)
|
||||
{
|
||||
int i;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(nf_service);
|
||||
|
||||
ogs_list_remove(&nf_instance->nf_service_list, nf_service);
|
||||
|
||||
ogs_assert(nf_service->id);
|
||||
ogs_free(nf_service->id);
|
||||
|
||||
ogs_assert(nf_service->name);
|
||||
ogs_free(nf_service->name);
|
||||
|
||||
for (i = 0; i < nf_service->num_of_version; i++) {
|
||||
if (nf_service->versions[i].in_uri)
|
||||
ogs_free(nf_service->versions[i].in_uri);
|
||||
if (nf_service->versions[i].full)
|
||||
ogs_free(nf_service->versions[i].full);
|
||||
if (nf_service->versions[i].expiry)
|
||||
ogs_free(nf_service->versions[i].expiry);
|
||||
}
|
||||
|
||||
for (i = 0; i < nf_service->num_of_addr; i++) {
|
||||
if (nf_service->addr[i].ipv4)
|
||||
ogs_freeaddrinfo(nf_service->addr[i].ipv4);
|
||||
if (nf_service->addr[i].ipv6)
|
||||
ogs_freeaddrinfo(nf_service->addr[i].ipv6);
|
||||
}
|
||||
|
||||
ogs_pool_free(&nf_service_pool, nf_service);
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_service_remove_all(ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
ogs_sbi_nf_service_t *nf_service = NULL, *next_nf_service = NULL;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
ogs_list_for_each_safe(&nf_instance->nf_service_list,
|
||||
next_nf_service, nf_service)
|
||||
ogs_sbi_nf_service_remove(nf_instance, nf_service);
|
||||
}
|
||||
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_find(
|
||||
ogs_sbi_nf_instance_t *nf_instance, char *name)
|
||||
{
|
||||
ogs_sbi_nf_service_t *nf_service = NULL;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(name);
|
||||
|
||||
ogs_list_for_each(&nf_instance->nf_service_list, nf_service) {
|
||||
ogs_assert(nf_service->name);
|
||||
if (strcmp(nf_service->name, name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return nf_service;
|
||||
}
|
||||
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
|
||||
ogs_sbi_nf_instance_t *nf_instance,
|
||||
char *name, ogs_sbi_client_t *client)
|
||||
{
|
||||
ogs_sbi_server_t *server = NULL;
|
||||
ogs_sbi_nf_service_t *nf_service = NULL;
|
||||
ogs_uuid_t uuid;
|
||||
char id[OGS_UUID_FORMATTED_LENGTH + 1];
|
||||
char *hostname = NULL;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(name);
|
||||
ogs_assert(client);
|
||||
|
||||
ogs_uuid_get(&uuid);
|
||||
ogs_uuid_format(id, &uuid);
|
||||
|
||||
nf_service = ogs_sbi_nf_service_add(nf_instance, id, name,
|
||||
(client->tls.key && client->tls.pem) ?
|
||||
OpenAPI_uri_scheme_https : OpenAPI_uri_scheme_http);
|
||||
ogs_assert(nf_service);
|
||||
OGS_SETUP_SBI_CLIENT(nf_service, client);
|
||||
|
||||
hostname = NULL;
|
||||
ogs_list_for_each(&ogs_sbi_self()->server_list, server) {
|
||||
ogs_assert(server->addr);
|
||||
|
||||
/* First FQDN is selected */
|
||||
if (!hostname) {
|
||||
hostname = ogs_gethostname(server->addr);
|
||||
if (hostname)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
|
||||
int port = 0;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
ogs_copyaddrinfo(&addr, server->addr);
|
||||
ogs_assert(addr);
|
||||
|
||||
port = OGS_PORT(addr);
|
||||
if (nf_service->scheme == OpenAPI_uri_scheme_https) {
|
||||
if (port == OGS_SBI_HTTPS_PORT) port = 0;
|
||||
} else if (nf_service->scheme == OpenAPI_uri_scheme_http) {
|
||||
if (port == OGS_SBI_HTTP_PORT) port = 0;
|
||||
}
|
||||
|
||||
nf_service->addr[nf_service->num_of_addr].port = port;
|
||||
if (addr->ogs_sa_family == AF_INET) {
|
||||
nf_service->addr[nf_service->num_of_addr].ipv4 = addr;
|
||||
} else if (addr->ogs_sa_family == AF_INET6) {
|
||||
nf_service->addr[nf_service->num_of_addr].ipv6 = addr;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
nf_service->num_of_addr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (hostname)
|
||||
strcpy(nf_service->fqdn, hostname);
|
||||
|
||||
return nf_service;
|
||||
}
|
||||
|
||||
static ogs_sbi_client_t *find_client_by_fqdn(char *fqdn, int port)
|
||||
{
|
||||
int rv;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
|
||||
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, fqdn,
|
||||
port ? port : OGS_SBI_HTTPS_PORT, 0);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("Invalid NFProfile.fqdn");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
client = ogs_sbi_client_find(addr);
|
||||
if (!client) {
|
||||
client = ogs_sbi_client_add(addr);
|
||||
ogs_assert(client);
|
||||
}
|
||||
|
||||
ogs_freeaddrinfo(addr);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_nf_instance_find_client(
|
||||
ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
|
||||
if (strlen(nf_instance->fqdn))
|
||||
client = find_client_by_fqdn(nf_instance->fqdn, 0);
|
||||
|
||||
if (!client) {
|
||||
/* At this point, CLIENT selection method is very simple. */
|
||||
if (nf_instance->num_of_ipv4) addr = nf_instance->ipv4[0];
|
||||
if (nf_instance->num_of_ipv6) addr = nf_instance->ipv6[0];
|
||||
|
||||
if (addr) {
|
||||
client = ogs_sbi_client_find(addr);
|
||||
if (!client) {
|
||||
client = ogs_sbi_client_add(addr);
|
||||
ogs_assert(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ogs_sbi_nf_service_find_client_all(nf_instance);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_nf_service_find_client(
|
||||
ogs_sbi_nf_service_t *nf_service)
|
||||
{
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
|
||||
if (strlen(nf_service->fqdn))
|
||||
client = find_client_by_fqdn(nf_service->fqdn, 0);
|
||||
|
||||
if (!client) {
|
||||
/* At this point, CLIENT selection method is very simple. */
|
||||
if (nf_service->num_of_addr) {
|
||||
addr = nf_service->addr[0].ipv6;
|
||||
if (!addr)
|
||||
addr = nf_service->addr[0].ipv4;
|
||||
}
|
||||
|
||||
if (addr) {
|
||||
client = ogs_sbi_client_find(addr);
|
||||
if (!client) {
|
||||
client = ogs_sbi_client_add(addr);
|
||||
ogs_assert(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!client) {
|
||||
ogs_sbi_nf_instance_t *nf_instance = NULL;
|
||||
nf_instance = nf_service->nf_instance;
|
||||
ogs_assert(nf_instance);
|
||||
client = nf_instance->client;
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
void ogs_sbi_nf_service_find_client_all(ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
ogs_sbi_nf_service_t *nf_service = NULL;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
ogs_list_for_each(&nf_instance->nf_service_list, nf_service)
|
||||
ogs_sbi_nf_service_find_client(nf_service);
|
||||
}
|
||||
|
||||
ogs_sbi_subscription_t *ogs_sbi_subscription_add(void)
|
||||
{
|
||||
ogs_sbi_subscription_t *subscription = NULL;
|
||||
|
||||
ogs_pool_alloc(&subscription_pool, &subscription);
|
||||
ogs_assert(subscription);
|
||||
memset(subscription, 0, sizeof(ogs_sbi_subscription_t));
|
||||
|
||||
subscription->time.validity = ogs_config()->time.subscription.validity;
|
||||
|
||||
ogs_list_add(&ogs_sbi_self()->subscription_list, subscription);
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
void ogs_sbi_subscription_set_id(ogs_sbi_subscription_t *subscription, char *id)
|
||||
{
|
||||
ogs_assert(subscription);
|
||||
ogs_assert(id);
|
||||
|
||||
subscription->id = ogs_strdup(id);
|
||||
ogs_assert(subscription->id);
|
||||
}
|
||||
|
||||
void ogs_sbi_subscription_remove(ogs_sbi_subscription_t *subscription)
|
||||
{
|
||||
ogs_assert(subscription);
|
||||
|
||||
ogs_list_remove(&ogs_sbi_self()->subscription_list, subscription);
|
||||
|
||||
if (subscription->id)
|
||||
ogs_free(subscription->id);
|
||||
|
||||
if (subscription->notification_uri)
|
||||
ogs_free(subscription->notification_uri);
|
||||
|
||||
if (subscription->nf_instance_id)
|
||||
ogs_free(subscription->nf_instance_id);
|
||||
|
||||
if (subscription->t_validity)
|
||||
ogs_timer_delete(subscription->t_validity);
|
||||
|
||||
ogs_pool_free(&subscription_pool, subscription);
|
||||
}
|
||||
|
||||
void ogs_sbi_subscription_remove_all_by_nf_instance_id(char *nf_instance_id)
|
||||
{
|
||||
ogs_sbi_subscription_t *subscription = NULL, *next_subscription = NULL;
|
||||
|
||||
ogs_assert(nf_instance_id);
|
||||
|
||||
ogs_list_for_each_safe(&ogs_sbi_self()->subscription_list,
|
||||
next_subscription, subscription) {
|
||||
if (subscription->nf_instance_id &&
|
||||
strcmp(subscription->nf_instance_id, nf_instance_id) == 0) {
|
||||
ogs_sbi_subscription_remove(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ogs_sbi_subscription_remove_all(void)
|
||||
{
|
||||
ogs_sbi_subscription_t *subscription = NULL, *next_subscription = NULL;
|
||||
|
||||
ogs_list_for_each_safe(&ogs_sbi_self()->subscription_list,
|
||||
next_subscription, subscription)
|
||||
ogs_sbi_subscription_remove(subscription);
|
||||
}
|
||||
|
||||
ogs_sbi_subscription_t *ogs_sbi_subscription_find(char *id)
|
||||
{
|
||||
ogs_sbi_subscription_t *subscription = NULL;
|
||||
|
||||
ogs_assert(id);
|
||||
|
||||
ogs_list_for_each(&ogs_sbi_self()->subscription_list, subscription) {
|
||||
ogs_assert(subscription->id);
|
||||
if (strcmp(subscription->id, id) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return subscription;
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
|
||||
#error "This header cannot be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef OGS_SBI_CONTEXT_H
|
||||
#define OGS_SBI_CONTEXT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ogs_sbi_client_s ogs_sbi_client_t;
|
||||
typedef struct ogs_sbi_context_s {
|
||||
ogs_pollset_t *pollset; /* Poll Set for I/O Multiplexing */
|
||||
ogs_timer_mgr_t *timer_mgr; /* Timer Manager */
|
||||
|
||||
uint32_t http_port; /* SBI HTTP local port */
|
||||
uint32_t https_port; /* SBI HTTPS local port */
|
||||
|
||||
ogs_list_t server_list;
|
||||
ogs_list_t client_list;
|
||||
|
||||
ogs_uuid_t uuid;
|
||||
char nf_instance_id[OGS_UUID_FORMATTED_LENGTH + 1];
|
||||
|
||||
ogs_list_t nf_instance_list;
|
||||
ogs_list_t subscription_list;
|
||||
|
||||
const char *content_encoding;
|
||||
} ogs_sbi_context_t;
|
||||
|
||||
typedef struct ogs_sbi_nf_instance_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
ogs_fsm_t sm; /* A state machine */
|
||||
ogs_timer_t *t_registration_interval; /* timer to retry
|
||||
to register peer node */
|
||||
#define OGS_SBI_HEARTBEAT_RETRYCOUNT 4
|
||||
struct {
|
||||
int heartbeat;
|
||||
int validity;
|
||||
} time;
|
||||
|
||||
ogs_timer_t *t_heartbeat_interval; /* heartbeat interval */
|
||||
ogs_timer_t *t_heartbeat; /* check heartbeat */
|
||||
ogs_timer_t *t_validity; /* check validation */
|
||||
|
||||
#define NF_INSTANCE_IS_SELF(_iD) \
|
||||
strcmp((_iD), ogs_sbi_self()->nf_instance_id) == 0
|
||||
#define NF_INSTANCE_IS_OTHERS(_iD) \
|
||||
strcmp((_iD), ogs_sbi_self()->nf_instance_id) != 0
|
||||
|
||||
char *id; /* NFInstanceId */
|
||||
|
||||
OpenAPI_nf_type_e nf_type;
|
||||
OpenAPI_nf_status_e nf_status;
|
||||
|
||||
char fqdn[OGS_MAX_FQDN_LEN];
|
||||
|
||||
#define OGS_SBI_MAX_NUM_OF_IP_ADDRESS 8
|
||||
int num_of_ipv4;
|
||||
ogs_sockaddr_t *ipv4[OGS_SBI_MAX_NUM_OF_IP_ADDRESS];
|
||||
int num_of_ipv6;
|
||||
ogs_sockaddr_t *ipv6[OGS_SBI_MAX_NUM_OF_IP_ADDRESS];
|
||||
|
||||
ogs_list_t nf_service_list;
|
||||
|
||||
void *client; /* only used in CLIENT */
|
||||
} ogs_sbi_nf_instance_t;
|
||||
|
||||
typedef struct ogs_sbi_nf_service_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
char *id;
|
||||
char *name;
|
||||
OpenAPI_uri_scheme_e scheme;
|
||||
|
||||
OpenAPI_nf_service_status_e status;
|
||||
|
||||
#define OGS_SBI_MAX_NUM_OF_SERVICE_VERSION 8
|
||||
int num_of_version;
|
||||
struct {
|
||||
char *in_uri;
|
||||
char *full;
|
||||
char *expiry;
|
||||
} versions[OGS_SBI_MAX_NUM_OF_SERVICE_VERSION];
|
||||
|
||||
char fqdn[OGS_MAX_FQDN_LEN];
|
||||
int num_of_addr;
|
||||
struct {
|
||||
ogs_sockaddr_t *ipv4;
|
||||
ogs_sockaddr_t *ipv6;
|
||||
int port;
|
||||
} addr[OGS_SBI_MAX_NUM_OF_IP_ADDRESS];
|
||||
|
||||
/* Related Context */
|
||||
ogs_sbi_nf_instance_t *nf_instance;
|
||||
void *client;
|
||||
} ogs_sbi_nf_service_t;
|
||||
|
||||
typedef struct ogs_sbi_subscription_s {
|
||||
ogs_lnode_t lnode;
|
||||
|
||||
struct {
|
||||
int validity;
|
||||
} time;
|
||||
|
||||
ogs_timer_t *t_validity; /* check validation */
|
||||
|
||||
char *id; /* SubscriptionId */
|
||||
char *nf_instance_id; /* NFInstanceId */
|
||||
OpenAPI_nf_type_e nf_type;
|
||||
OpenAPI_nf_status_e nf_status;
|
||||
char *notification_uri;
|
||||
|
||||
void *client; /* only used in SERVER */
|
||||
} ogs_sbi_subscription_t;
|
||||
|
||||
void ogs_sbi_context_init(ogs_pollset_t *pollset, ogs_timer_mgr_t *timer_mgr);
|
||||
void ogs_sbi_context_final(void);
|
||||
ogs_sbi_context_t *ogs_sbi_self(void);
|
||||
int ogs_sbi_context_parse_config(const char *local, const char *remote);
|
||||
|
||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_add(char *id);
|
||||
void ogs_sbi_nf_instance_clear(ogs_sbi_nf_instance_t *nf_instance);
|
||||
void ogs_sbi_nf_instance_remove(ogs_sbi_nf_instance_t *nf_instance);
|
||||
void ogs_sbi_nf_instance_remove_all(void);
|
||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_find(char *id);
|
||||
|
||||
ogs_sbi_nf_instance_t *ogs_sbi_nf_instance_build_default(
|
||||
OpenAPI_nf_type_e nf_type, ogs_sbi_client_t *client);
|
||||
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_add(ogs_sbi_nf_instance_t *nf_instance,
|
||||
char *id, char *name, OpenAPI_uri_scheme_e scheme);
|
||||
void ogs_sbi_nf_service_add_version(ogs_sbi_nf_service_t *nf_service,
|
||||
char *in_uri, char *full, char *expiry);
|
||||
void ogs_sbi_nf_service_remove(ogs_sbi_nf_instance_t *nf_instance,
|
||||
ogs_sbi_nf_service_t *nf_service);
|
||||
void ogs_sbi_nf_service_remove_all(ogs_sbi_nf_instance_t *nf_instance);
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_find(
|
||||
ogs_sbi_nf_instance_t *nf_instance, char *name);
|
||||
ogs_sbi_nf_service_t *ogs_sbi_nf_service_build_default(
|
||||
ogs_sbi_nf_instance_t *nf_instance,
|
||||
char *name, ogs_sbi_client_t *client);
|
||||
|
||||
ogs_sbi_client_t *ogs_sbi_nf_instance_find_client(
|
||||
ogs_sbi_nf_instance_t *nf_instance);
|
||||
ogs_sbi_client_t *ogs_sbi_nf_service_find_client(
|
||||
ogs_sbi_nf_service_t *nf_service);
|
||||
void ogs_sbi_nf_service_find_client_all(ogs_sbi_nf_instance_t *nf_instance);
|
||||
|
||||
ogs_sbi_subscription_t *ogs_sbi_subscription_add(void);
|
||||
void ogs_sbi_subscription_set_id(
|
||||
ogs_sbi_subscription_t *subscription, char *id);
|
||||
void ogs_sbi_subscription_remove(ogs_sbi_subscription_t *subscription);
|
||||
void ogs_sbi_subscription_remove_all_by_nf_instance_id(char *nf_instance_id);
|
||||
void ogs_sbi_subscription_remove_all(void);
|
||||
ogs_sbi_subscription_t *ogs_sbi_subscription_find(char *id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_CONTEXT_H */
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ogs-sbi.h"
|
||||
|
||||
#include "sbi-private.h"
|
||||
|
||||
static char *ogs_uridup(bool https, ogs_sockaddr_t *addr,
|
||||
const char *service_name, const char *api_version,
|
||||
const char *resource_name, const char *resource_id)
|
||||
{
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
char url[OGS_HUGE_LEN];
|
||||
char *p, *last;
|
||||
|
||||
ogs_assert(addr);
|
||||
ogs_assert(service_name);
|
||||
ogs_assert(api_version);
|
||||
ogs_assert(resource_name);
|
||||
|
||||
p = url;
|
||||
last = url + OGS_HUGE_LEN;
|
||||
|
||||
/* HTTP scheme is selected based on TLS information */
|
||||
if (https == true)
|
||||
p = ogs_slprintf(p, last, "https://");
|
||||
else
|
||||
p = ogs_slprintf(p, last, "http://");
|
||||
|
||||
/* IP address */
|
||||
if (addr->ogs_sa_family == AF_INET6)
|
||||
p = ogs_slprintf(p, last, "[%s]", OGS_ADDR(addr, buf));
|
||||
else
|
||||
p = ogs_slprintf(p, last, "%s", OGS_ADDR(addr, buf));
|
||||
|
||||
/* Port number */
|
||||
if (OGS_PORT(addr) != OGS_SBI_HTTP_PORT) {
|
||||
p = ogs_slprintf(p, last, ":%d", OGS_PORT(addr));
|
||||
}
|
||||
|
||||
/* API */
|
||||
ogs_assert(service_name);
|
||||
p = ogs_slprintf(p, last, "/%s", service_name);
|
||||
ogs_assert(api_version);
|
||||
p = ogs_slprintf(p, last, "/%s", api_version);
|
||||
|
||||
/* Resource */
|
||||
ogs_assert(resource_name);
|
||||
p = ogs_slprintf(p, last, "/%s", resource_name);
|
||||
if (resource_id)
|
||||
p = ogs_slprintf(p, last, "/%s", resource_id);
|
||||
|
||||
return ogs_strdup(url);
|
||||
}
|
||||
|
||||
char *ogs_sbi_server_uri(ogs_sbi_server_t *server,
|
||||
const char *service_name, const char *api_version,
|
||||
const char *resource_name, const char *resource_id)
|
||||
{
|
||||
bool https = false;
|
||||
if (server->tls.key && server->tls.pem)
|
||||
https = true;
|
||||
|
||||
return ogs_uridup(https, server->addr, service_name, api_version,
|
||||
resource_name, resource_id);
|
||||
}
|
||||
|
||||
char *ogs_sbi_client_uri(ogs_sbi_client_t *client,
|
||||
const char *service_name, const char *api_version,
|
||||
const char *resource_name, const char *resource_id)
|
||||
{
|
||||
bool https = false;
|
||||
if (client->tls.key && client->tls.pem)
|
||||
https = true;
|
||||
|
||||
return ogs_uridup(https, client->addr, service_name, api_version,
|
||||
resource_name, resource_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a url-decoded version of str
|
||||
* IMPORTANT: be sure to free() the returned string after use
|
||||
* Thanks Geek Hideout!
|
||||
* http://www.geekhideout.com/urlcode.shtml
|
||||
*/
|
||||
static char *url_decode(const char *str)
|
||||
{
|
||||
if (str != NULL) {
|
||||
char *pstr = (char*)str;
|
||||
char *buf = ogs_malloc(strlen(str) + 1);
|
||||
char *pbuf = buf;
|
||||
while (*pstr) {
|
||||
if (*pstr == '%') {
|
||||
if (pstr[1] && pstr[2]) {
|
||||
*pbuf++ = ogs_from_hex(pstr[1]) << 4 |
|
||||
ogs_from_hex(pstr[2]);
|
||||
pstr += 2;
|
||||
}
|
||||
} else if (*pstr == '+') {
|
||||
*pbuf++ = ' ';
|
||||
} else {
|
||||
*pbuf++ = * pstr;
|
||||
}
|
||||
pstr++;
|
||||
}
|
||||
*pbuf = '\0';
|
||||
return buf;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *ogs_sbi_parse_url(char *url, const char *delim, char **saveptr)
|
||||
{
|
||||
char *item = NULL;
|
||||
|
||||
item = url_decode(strtok_r(url, delim, saveptr));
|
||||
if (!item) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
ogs_sockaddr_t *ogs_sbi_getaddr_from_uri(char *uri)
|
||||
{
|
||||
int rv;
|
||||
struct yuarel yuarel;
|
||||
char *p = NULL;
|
||||
int port;
|
||||
|
||||
ogs_sockaddr_t *addr = 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) {
|
||||
port = OGS_SBI_HTTPS_PORT;
|
||||
} else if (strcmp(yuarel.scheme, "http") == 0) {
|
||||
port = OGS_SBI_HTTP_PORT;
|
||||
} 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.port) port = yuarel.port;
|
||||
|
||||
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, yuarel.host, port, 0);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("ogs_getaddrinfo() failed [%s]", uri);
|
||||
ogs_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ogs_free(p);
|
||||
return addr;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
|
||||
#error "This header cannot be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef OGS_SBI_CONV_H
|
||||
#define OGS_SBI_CONV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ogs_sbi_server_s ogs_sbi_server_t;
|
||||
typedef struct ogs_sbi_client_s ogs_sbi_client_t;
|
||||
|
||||
char *ogs_sbi_server_uri(ogs_sbi_server_t *server,
|
||||
const char *service_name, const char *api_version,
|
||||
const char *resource_name, const char *resource_id);
|
||||
|
||||
char *ogs_sbi_client_uri(ogs_sbi_client_t *client,
|
||||
const char *service_name, const char *api_version,
|
||||
const char *resource_name, const char *resource_id);
|
||||
|
||||
char *ogs_sbi_parse_url(char *url, const char *delim, char **saveptr);
|
||||
ogs_sockaddr_t *ogs_sbi_getaddr_from_uri(char *uri);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_CONV_H */
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "links.h"
|
||||
|
||||
cJSON *ogs_sbi_links_convertToJSON(ogs_sbi_links_t *links)
|
||||
{
|
||||
cJSON *rootJSON = NULL;
|
||||
cJSON *linksJSON = NULL;
|
||||
cJSON *itemsJSON = NULL;
|
||||
cJSON *selfJSON = NULL;
|
||||
OpenAPI_lnode_t *node;
|
||||
|
||||
ogs_assert(links);
|
||||
ogs_assert(links->self);
|
||||
|
||||
rootJSON = cJSON_CreateObject();
|
||||
ogs_assert(rootJSON);
|
||||
|
||||
linksJSON = cJSON_AddObjectToObject(rootJSON, "_links");
|
||||
ogs_assert(linksJSON);
|
||||
|
||||
itemsJSON = cJSON_AddObjectToObject(linksJSON, "items");
|
||||
ogs_assert(itemsJSON);
|
||||
|
||||
OpenAPI_list_for_each(links->items, node) {
|
||||
if (!node->data) continue;
|
||||
cJSON_AddStringToObject(itemsJSON, "href", node->data);
|
||||
}
|
||||
|
||||
selfJSON = cJSON_AddObjectToObject(linksJSON, "self");
|
||||
ogs_assert(selfJSON);
|
||||
cJSON_AddStringToObject(selfJSON, "href", links->self);
|
||||
|
||||
return rootJSON;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* search_result.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPILinksH_
|
||||
#define _OpenAPILinksH_
|
||||
|
||||
#include <string.h>
|
||||
#include "../openapi/external/cJSON.h"
|
||||
#include "../openapi/include/list.h"
|
||||
#include "../openapi/include/keyValuePair.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ogs_sbi_links_s ogs_sbi_links_t;
|
||||
typedef struct ogs_sbi_links_s {
|
||||
OpenAPI_list_t *items;
|
||||
char *self;
|
||||
} ogs_sbi_links_t;
|
||||
|
||||
cJSON *ogs_sbi_links_convertToJSON(ogs_sbi_links_t *links);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPILinksH_ */
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
|
||||
# This file is part of Open5GS.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
subdir('openapi')
|
||||
|
||||
libsbi_sources = files('''
|
||||
custom/links.c
|
||||
|
||||
yuarel.c
|
||||
conv.c
|
||||
message.c
|
||||
|
||||
server.c
|
||||
client.c
|
||||
context.c
|
||||
|
||||
nnrf-build.c
|
||||
nnrf-handler.c
|
||||
'''.split())
|
||||
|
||||
libsbi_inc = include_directories('.')
|
||||
|
||||
sbi_cc_flags = ['-DOGS_SBI_COMPILATION']
|
||||
|
||||
libgnutls_dep = cc.find_library('gnutls', required : true)
|
||||
libmicrohttpd_dep = dependency('libmicrohttpd')
|
||||
libcurl_dep = dependency('libcurl')
|
||||
|
||||
libsbi = library('ogssbi',
|
||||
sources : libsbi_sources,
|
||||
version : libogslib_version,
|
||||
c_args : sbi_cc_flags,
|
||||
include_directories : [libsbi_inc, libinc],
|
||||
dependencies : [libcore_dep,
|
||||
libapp_dep,
|
||||
libsbi_openapi_dep,
|
||||
libgnutls_dep,
|
||||
libmicrohttpd_dep,
|
||||
libcurl_dep],
|
||||
install : true)
|
||||
|
||||
libsbi_dep = declare_dependency(
|
||||
link_with : libsbi,
|
||||
include_directories : [libsbi_inc, libinc],
|
||||
dependencies : [libcore_dep,
|
||||
libapp_dep,
|
||||
libsbi_openapi_dep,
|
||||
libgnutls_dep,
|
||||
libmicrohttpd_dep,
|
||||
libcurl_dep])
|
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ogs-sbi.h"
|
||||
|
||||
#include "sbi-private.h"
|
||||
|
||||
static OGS_POOL(request_pool, ogs_sbi_request_t);
|
||||
static OGS_POOL(response_pool, ogs_sbi_response_t);
|
||||
|
||||
void ogs_sbi_message_init(int num_of_request_pool, int num_of_response_pool)
|
||||
{
|
||||
ogs_pool_init(&request_pool, num_of_request_pool);
|
||||
ogs_pool_init(&response_pool, num_of_response_pool);
|
||||
}
|
||||
|
||||
void ogs_sbi_message_final(void)
|
||||
{
|
||||
ogs_pool_final(&request_pool);
|
||||
ogs_pool_final(&response_pool);
|
||||
}
|
||||
|
||||
void ogs_sbi_message_free(ogs_sbi_message_t *message)
|
||||
{
|
||||
ogs_assert(message);
|
||||
|
||||
if (message->NFProfile)
|
||||
OpenAPI_nf_profile_free(message->NFProfile);
|
||||
if (message->ProblemDetails)
|
||||
OpenAPI_problem_details_free(message->ProblemDetails);
|
||||
if (message->PatchItemList) {
|
||||
OpenAPI_lnode_t *node = NULL;
|
||||
OpenAPI_list_for_each(message->PatchItemList, node)
|
||||
OpenAPI_patch_item_free(node->data);
|
||||
OpenAPI_list_free(message->PatchItemList);
|
||||
}
|
||||
|
||||
if (message->SubscriptionData)
|
||||
OpenAPI_subscription_data_free(message->SubscriptionData);
|
||||
if (message->NotificationData)
|
||||
OpenAPI_notification_data_free(message->NotificationData);
|
||||
if (message->SearchResult)
|
||||
OpenAPI_search_result_free(message->SearchResult);
|
||||
}
|
||||
|
||||
ogs_sbi_request_t *ogs_sbi_request_new(void)
|
||||
{
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
|
||||
ogs_pool_alloc(&request_pool, &request);
|
||||
|
||||
ogs_assert(request);
|
||||
memset(request, 0, sizeof(ogs_sbi_request_t));
|
||||
|
||||
request->http.params = ogs_hash_make();
|
||||
request->http.headers = ogs_hash_make();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
ogs_sbi_response_t *ogs_sbi_response_new(void)
|
||||
{
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
ogs_pool_alloc(&response_pool, &response);
|
||||
ogs_assert(response);
|
||||
memset(response, 0, sizeof(ogs_sbi_response_t));
|
||||
|
||||
response->http.params = ogs_hash_make();
|
||||
response->http.headers = ogs_hash_make();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
static void sbi_header_free(ogs_sbi_header_t *h);
|
||||
static void http_message_free(http_message_t *http);
|
||||
|
||||
void ogs_sbi_request_free(ogs_sbi_request_t *request)
|
||||
{
|
||||
ogs_assert(request);
|
||||
|
||||
if (request->h.url)
|
||||
ogs_free(request->h.url);
|
||||
|
||||
sbi_header_free(&request->h);
|
||||
http_message_free(&request->http);
|
||||
|
||||
ogs_pool_free(&request_pool, request);
|
||||
}
|
||||
|
||||
void ogs_sbi_response_free(ogs_sbi_response_t *response)
|
||||
{
|
||||
ogs_assert(response);
|
||||
|
||||
if (response->h.url)
|
||||
ogs_free(response->h.url);
|
||||
|
||||
sbi_header_free(&response->h);
|
||||
http_message_free(&response->http);
|
||||
|
||||
ogs_pool_free(&response_pool, response);
|
||||
}
|
||||
|
||||
static void sbi_header_free(ogs_sbi_header_t *h)
|
||||
{
|
||||
ogs_assert(h);
|
||||
|
||||
if (h->method) ogs_free(h->method);
|
||||
if (h->service.name) ogs_free(h->service.name);
|
||||
if (h->api.version) ogs_free(h->api.version);
|
||||
if (h->resource.name) ogs_free(h->resource.name);
|
||||
if (h->resource.id) ogs_free(h->resource.id);
|
||||
}
|
||||
|
||||
static void http_message_free(http_message_t *http)
|
||||
{
|
||||
ogs_assert(http);
|
||||
|
||||
if (http->params) {
|
||||
ogs_hash_index_t *hi;
|
||||
for (hi = ogs_hash_first(http->params); hi; hi = ogs_hash_next(hi)) {
|
||||
char *val = ogs_hash_this_val(hi);
|
||||
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 *val = ogs_hash_this_val(hi);
|
||||
ogs_free(val);
|
||||
}
|
||||
ogs_hash_destroy(http->headers);
|
||||
}
|
||||
if (http->content) ogs_free(http->content);
|
||||
}
|
||||
|
||||
static char *build_content(ogs_sbi_message_t *message);
|
||||
|
||||
ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
||||
{
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
|
||||
ogs_assert(message);
|
||||
|
||||
request = ogs_sbi_request_new();
|
||||
ogs_assert(request);
|
||||
|
||||
ogs_assert(message->h.method);
|
||||
request->h.method = ogs_strdup(message->h.method);
|
||||
if (message->h.url) {
|
||||
request->h.url = ogs_strdup(message->h.url);
|
||||
} else {
|
||||
ogs_assert(message->h.service.name);
|
||||
request->h.service.name = ogs_strdup(message->h.service.name);
|
||||
ogs_assert(message->h.api.version);
|
||||
request->h.api.version = ogs_strdup(message->h.api.version);
|
||||
ogs_assert(message->h.resource.name);
|
||||
request->h.resource.name = ogs_strdup(message->h.resource.name);
|
||||
if (message->h.resource.id)
|
||||
request->h.resource.id = ogs_strdup(message->h.resource.id);
|
||||
}
|
||||
|
||||
/* URL Param */
|
||||
if (message->param.nf_type) {
|
||||
char *v = OpenAPI_nf_type_ToString(message->param.nf_type);
|
||||
ogs_assert(v);
|
||||
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_NF_TYPE, v);
|
||||
}
|
||||
if (message->param.requester_nf_type) {
|
||||
char *v = OpenAPI_nf_type_ToString(message->param.requester_nf_type);
|
||||
ogs_assert(v);
|
||||
ogs_sbi_header_set(request->http.params,
|
||||
OGS_SBI_PARAM_REQUESTER_NF_TYPE, v);
|
||||
}
|
||||
if (message->param.target_nf_type) {
|
||||
char *v = OpenAPI_nf_type_ToString(message->param.target_nf_type);
|
||||
ogs_assert(v);
|
||||
ogs_sbi_header_set(request->http.params,
|
||||
OGS_SBI_PARAM_TARGET_NF_TYPE, v);
|
||||
}
|
||||
if (message->param.limit) {
|
||||
char *v = ogs_msprintf("%d", message->param.limit);
|
||||
ogs_assert(v);
|
||||
ogs_sbi_header_set(request->http.params, OGS_SBI_PARAM_LIMIT, v);
|
||||
}
|
||||
|
||||
/* HTTP Message */
|
||||
request->http.content = build_content(message);
|
||||
if (request->http.content) {
|
||||
if (message->http.content_type)
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CONTENT_TYPE, message->http.content_type);
|
||||
else
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_CONTENT_TYPE, OGS_SBI_CONTENT_JSON_TYPE);
|
||||
}
|
||||
|
||||
if (message->http.content_encoding)
|
||||
ogs_sbi_header_set(request->http.headers,
|
||||
OGS_SBI_ACCEPT_ENCODING, message->http.content_encoding);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
ogs_sbi_response_t *ogs_sbi_build_response(ogs_sbi_message_t *message)
|
||||
{
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
ogs_assert(message);
|
||||
|
||||
response = ogs_sbi_response_new();
|
||||
ogs_assert(response);
|
||||
|
||||
/* HTTP Message */
|
||||
response->http.content = build_content(message);
|
||||
if (response->http.content) {
|
||||
if (message->http.content_type)
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
OGS_SBI_CONTENT_TYPE, message->http.content_type);
|
||||
else
|
||||
ogs_sbi_header_set(response->http.headers,
|
||||
OGS_SBI_CONTENT_TYPE, OGS_SBI_CONTENT_JSON_TYPE);
|
||||
}
|
||||
|
||||
if (message->http.location == true)
|
||||
ogs_sbi_header_set(response->http.headers, "Location", message->h.url);
|
||||
if (message->http.cache_control)
|
||||
ogs_sbi_header_set(response->http.headers, "Cache-Control",
|
||||
message->http.cache_control);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
static char *build_content(ogs_sbi_message_t *message)
|
||||
{
|
||||
char *content = NULL;
|
||||
cJSON *item = NULL;
|
||||
ogs_assert(message);
|
||||
|
||||
if (message->ProblemDetails) {
|
||||
item = OpenAPI_problem_details_convertToJSON(message->ProblemDetails);
|
||||
ogs_assert(item);
|
||||
} else if (message->NFProfile) {
|
||||
item = OpenAPI_nf_profile_convertToJSON(message->NFProfile);
|
||||
ogs_assert(item);
|
||||
} else if (message->PatchItemList) {
|
||||
OpenAPI_lnode_t *node = NULL;
|
||||
|
||||
item = cJSON_CreateArray();
|
||||
ogs_assert(item);
|
||||
|
||||
OpenAPI_list_for_each(message->PatchItemList, node) {
|
||||
cJSON *patchItem = OpenAPI_patch_item_convertToJSON(node->data);
|
||||
ogs_assert(patchItem);
|
||||
cJSON_AddItemToArray(item, patchItem);
|
||||
}
|
||||
} else if (message->SubscriptionData) {
|
||||
item = OpenAPI_subscription_data_convertToJSON(
|
||||
message->SubscriptionData);
|
||||
ogs_assert(item);
|
||||
} else if (message->NotificationData) {
|
||||
item = OpenAPI_notification_data_convertToJSON(
|
||||
message->NotificationData);
|
||||
ogs_assert(item);
|
||||
} else if (message->SearchResult) {
|
||||
item = OpenAPI_search_result_convertToJSON(message->SearchResult);
|
||||
ogs_assert(item);
|
||||
} else if (message->links) {
|
||||
item = ogs_sbi_links_convertToJSON(message->links);
|
||||
ogs_assert(item);
|
||||
}
|
||||
|
||||
if (item) {
|
||||
content = cJSON_Print(item);
|
||||
ogs_assert(content);
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
static int parse_sbi_header(
|
||||
ogs_sbi_message_t *message, ogs_sbi_header_t *header);
|
||||
static int parse_content(ogs_sbi_message_t *message, char *content);
|
||||
|
||||
int ogs_sbi_parse_request(
|
||||
ogs_sbi_message_t *message, ogs_sbi_request_t *request)
|
||||
{
|
||||
int rv;
|
||||
ogs_hash_index_t *hi;
|
||||
|
||||
ogs_assert(request);
|
||||
ogs_assert(message);
|
||||
|
||||
rv = parse_sbi_header(message, &request->h);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("sbi_parse_header() failed");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
for (hi = ogs_hash_first(request->http.params);
|
||||
hi; hi = ogs_hash_next(hi)) {
|
||||
if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_NF_TYPE)) {
|
||||
message->param.nf_type =
|
||||
OpenAPI_nf_type_FromString(ogs_hash_this_val(hi));
|
||||
} else if (!strcmp(ogs_hash_this_key(hi),
|
||||
OGS_SBI_PARAM_TARGET_NF_TYPE)) {
|
||||
message->param.target_nf_type =
|
||||
OpenAPI_nf_type_FromString(ogs_hash_this_val(hi));
|
||||
} else if (!strcmp(ogs_hash_this_key(hi),
|
||||
OGS_SBI_PARAM_REQUESTER_NF_TYPE)) {
|
||||
message->param.requester_nf_type =
|
||||
OpenAPI_nf_type_FromString(ogs_hash_this_val(hi));
|
||||
} else if (!strcmp(ogs_hash_this_key(hi),
|
||||
OGS_SBI_PARAM_LIMIT)) {
|
||||
message->param.limit = atoi(ogs_hash_this_val(hi));
|
||||
}
|
||||
}
|
||||
|
||||
for (hi = ogs_hash_first(request->http.headers);
|
||||
hi; hi = ogs_hash_next(hi)) {
|
||||
if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_ACCEPT_ENCODING)) {
|
||||
message->http.content_encoding = ogs_hash_this_val(hi);
|
||||
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_CONTENT_TYPE)) {
|
||||
message->http.content_type = ogs_hash_this_val(hi);
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_content(message, request->http.content) != OGS_OK) {
|
||||
ogs_error("parse_content() failed");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int ogs_sbi_parse_response(
|
||||
ogs_sbi_message_t *message, ogs_sbi_response_t *response)
|
||||
{
|
||||
int rv;
|
||||
ogs_hash_index_t *hi;
|
||||
|
||||
ogs_assert(response);
|
||||
ogs_assert(message);
|
||||
|
||||
rv = parse_sbi_header(message, &response->h);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("sbi_parse_header() failed");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
for (hi = ogs_hash_first(response->http.headers);
|
||||
hi; hi = ogs_hash_next(hi)) {
|
||||
if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_CONTENT_TYPE)) {
|
||||
message->http.content_type = ogs_hash_this_val(hi);
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_content(message, response->http.content) != OGS_OK) {
|
||||
ogs_error("parse_content() failed");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
message->res_status = response->status;
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
static int parse_sbi_header(
|
||||
ogs_sbi_message_t *message, ogs_sbi_header_t *header)
|
||||
{
|
||||
struct yuarel yuarel;
|
||||
char *saveptr = NULL;
|
||||
char *url = NULL, *p = NULL;;
|
||||
|
||||
ogs_assert(message);
|
||||
ogs_assert(header);
|
||||
|
||||
memset(message, 0, sizeof(*message));
|
||||
|
||||
message->h.method = header->method;
|
||||
ogs_assert(message->h.method);
|
||||
message->h.url = header->url;
|
||||
ogs_assert(message->h.url);
|
||||
|
||||
url = ogs_strdup(header->url);
|
||||
ogs_assert(url);
|
||||
p = url;
|
||||
|
||||
if (p[0] != '/') {
|
||||
int rv = yuarel_parse(&yuarel, p);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("yuarel_parse() failed");
|
||||
ogs_free(url);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
p = yuarel.path;
|
||||
}
|
||||
|
||||
header->service.name = ogs_sbi_parse_url(p, "/", &saveptr);
|
||||
if (!header->service.name) {
|
||||
ogs_error("ogs_sbi_parse_url() failed");
|
||||
ogs_free(url);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
message->h.service.name = header->service.name;
|
||||
|
||||
header->api.version = ogs_sbi_parse_url(NULL, "/", &saveptr);
|
||||
if (!header->api.version) {
|
||||
ogs_error("ogs_sbi_parse_url() failed");
|
||||
ogs_free(url);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
message->h.api.version = header->api.version;
|
||||
|
||||
header->resource.name = ogs_sbi_parse_url(NULL, "/", &saveptr);
|
||||
if (!header->resource.name) {
|
||||
ogs_error("ogs_sbi_parse_url() failed");
|
||||
ogs_free(url);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
message->h.resource.name = header->resource.name;
|
||||
|
||||
header->resource.id = ogs_sbi_parse_url(NULL, "/", &saveptr);
|
||||
message->h.resource.id = header->resource.id;
|
||||
|
||||
ogs_free(url);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
static int parse_content(ogs_sbi_message_t *message, char *content)
|
||||
{
|
||||
int rv = OGS_OK;
|
||||
cJSON *item = NULL;
|
||||
|
||||
ogs_assert(message);
|
||||
|
||||
if (!content)
|
||||
return OGS_OK;
|
||||
|
||||
if (strcmp(message->h.api.version, OGS_SBI_API_VERSION) != 0) {
|
||||
ogs_error("Not supported version - %s", message->h.api.version);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
item = cJSON_Parse(content);
|
||||
if (!item) {
|
||||
ogs_error("JSON parse error");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
if (message->http.content_type) {
|
||||
if (!strncmp(message->http.content_type,
|
||||
OGS_SBI_CONTENT_PROBLEM_TYPE,
|
||||
strlen(OGS_SBI_CONTENT_PROBLEM_TYPE))) {
|
||||
message->ProblemDetails =
|
||||
OpenAPI_problem_details_parseFromJSON(item);
|
||||
} else if (!strncmp(message->http.content_type,
|
||||
OGS_SBI_CONTENT_PATCH_TYPE,
|
||||
strlen(OGS_SBI_CONTENT_PATCH_TYPE))) {
|
||||
if (item) {
|
||||
OpenAPI_patch_item_t *patch_item = NULL;
|
||||
cJSON *patchJSON = NULL;
|
||||
message->PatchItemList = OpenAPI_list_create();
|
||||
cJSON_ArrayForEach(patchJSON, item) {
|
||||
if (!cJSON_IsObject(patchJSON)) {
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("Unknown JSON");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
patch_item = OpenAPI_patch_item_parseFromJSON(patchJSON);
|
||||
OpenAPI_list_add(message->PatchItemList, patch_item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SWITCH(message->h.service.name)
|
||||
CASE(OGS_SBI_SERVICE_NAME_NRF_NFM)
|
||||
|
||||
SWITCH(message->h.resource.name)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
message->NFProfile =
|
||||
OpenAPI_nf_profile_parseFromJSON(item);
|
||||
if (!message->NFProfile) {
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("JSON parse error");
|
||||
}
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
|
||||
message->SubscriptionData =
|
||||
OpenAPI_subscription_data_parseFromJSON(item);
|
||||
if (!message->SubscriptionData) {
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("JSON parse error");
|
||||
}
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
|
||||
message->NotificationData =
|
||||
OpenAPI_notification_data_parseFromJSON(item);
|
||||
if (!message->NotificationData) {
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("JSON parse error");
|
||||
}
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("Unknown resource name [%s]",
|
||||
message->h.resource.name);
|
||||
END
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_SERVICE_NAME_NRF_DISC)
|
||||
SWITCH(message->h.resource.name)
|
||||
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
|
||||
message->SearchResult =
|
||||
OpenAPI_search_result_parseFromJSON(item);
|
||||
if (!message->SearchResult) {
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("JSON parse error");
|
||||
}
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("Unknown resource name [%s]",
|
||||
message->h.resource.name);
|
||||
END
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("Not implemented API name [%s]",
|
||||
message->h.service.name);
|
||||
END
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
cJSON_Delete(item);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void ogs_sbi_header_set(ogs_hash_t *ht, const void *key, const void *val)
|
||||
{
|
||||
ogs_hash_set(ht, key, strlen(key), ogs_strdup(val));
|
||||
}
|
||||
|
||||
void *ogs_sbi_header_get(ogs_hash_t *ht, const void *key)
|
||||
{
|
||||
return ogs_hash_get(ht, key, strlen(key));
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(OGS_SBI_INSIDE) && !defined(OGS_SBI_COMPILATION)
|
||||
#error "This header cannot be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef OGS_SBI_MESSAGE_H
|
||||
#define OGS_SBI_MESSAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OGS_SBI_HTTP_PORT 80
|
||||
#define OGS_SBI_HTTPS_PORT 443
|
||||
|
||||
#define OGS_SBI_HTTP_SCHEME "http"
|
||||
#define OGS_SBI_HTTPS_SCHEME "https"
|
||||
|
||||
#define OGS_SBI_HTTP_STATUS_OK 200
|
||||
#define OGS_SBI_HTTP_STATUS_CREATED 201 /* POST PUT */
|
||||
#define OGS_SBI_HTTP_STATUS_ACCEPTED 202 /* DELETE PATCH
|
||||
POST PUT */
|
||||
#define OGS_SBI_HTTP_STATUS_NO_CONTENT 204 /* DELETE PATCH
|
||||
POST PUT OPTIONS */
|
||||
#define OGS_SBI_HTTP_STATUS_SEE_OTHER 303 /* DELETE GET
|
||||
POST PUT */
|
||||
#define OGS_SBI_HTTP_STATUS_TEMPORARY_REDIRECT 307 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_PERMANENT_REDIRECT 308 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_BAD_REQUEST 400 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_UNAUTHORIZED 401 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_FORBIDDEN 403 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_NOT_FOUND 404 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_MEHTOD_NOT_ALLOWED 405 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_NOT_ACCEPTABLE 406 /* GET OPTIONS */
|
||||
#define OGS_SBI_HTTP_STATUS_REQUEST_TIMEOUT 408 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_CONFLICT 409 /* PATCH POST PUT */
|
||||
#define OGS_SBI_HTTP_STATUS_GONE 410 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_LENGTH_REQUIRED 411 /* PATCH POST
|
||||
PUT OPTIONS */
|
||||
#define OGS_SBI_HTTP_STATUS_PRECONDITION_FAILED 412 /* DELETE GET PATCH
|
||||
POST PUT */
|
||||
#define OGS_SBI_HTTP_STATUS_PAYLOAD_TOO_LARGE 413 /* PATCH POST
|
||||
PUT OPTIONS */
|
||||
#define OGS_SBI_HTTP_STATUS_URI_TOO_LONG 414 /* GET PUT */
|
||||
#define OGS_SBI_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE 415 /* PATCH POST
|
||||
PUT OPTIONS */
|
||||
#define OGS_SBI_HTTP_STATUS_TOO_MANY_REQUESTS 429 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR 500 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_NOT_IMPLEMENTED 501 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE 503 /* ALL */
|
||||
#define OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT 504 /* ALL */
|
||||
|
||||
#define OGS_SBI_HTTP_METHOD_DELETE "DELETE"
|
||||
#define OGS_SBI_HTTP_METHOD_GET "GET"
|
||||
#define OGS_SBI_HTTP_METHOD_PATCH "PATCH"
|
||||
#define OGS_SBI_HTTP_METHOD_POST "POST"
|
||||
#define OGS_SBI_HTTP_METHOD_PUT "PUT"
|
||||
#define OGS_SBI_HTTP_METHOD_OPTIONS "OPTIONS"
|
||||
|
||||
#define OGS_SBI_API_VERSION "v1"
|
||||
#define OGS_SBI_API_FULL_VERSION "1.0.0"
|
||||
#define OGS_SBI_SERVICE_NAME_NRF_NFM "nnrf-nfm"
|
||||
#define OGS_SBI_SERVICE_NAME_NRF_DISC "nnrf-disc"
|
||||
#define OGS_SBI_SERVICE_NAME_SMF_PDUSESSION "nsmf-pdusession"
|
||||
#define OGS_SBI_SERVICE_NAME_SMF_EVENT_EXPOSURE "nsmf-event-exposure"
|
||||
|
||||
#define OGS_SBI_RESOURCE_NAME_NF_INSTANCES "nf-instances"
|
||||
#define OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS "subscriptions"
|
||||
#define OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY "nf-status-notify"
|
||||
|
||||
#define OGS_SBI_PARAM_NF_TYPE "nf-type"
|
||||
#define OGS_SBI_PARAM_TARGET_NF_TYPE "target-nf-type"
|
||||
#define OGS_SBI_PARAM_REQUESTER_NF_TYPE "requester-nf-type"
|
||||
#define OGS_SBI_PARAM_LIMIT "limit"
|
||||
|
||||
#define OGS_SBI_ACCEPT_ENCODING "Accept-Encoding"
|
||||
#define OGS_SBI_CONTENT_TYPE "Content-Type"
|
||||
#define OGS_SBI_CONTENT_JSON_TYPE "application/json"
|
||||
#define OGS_SBI_CONTENT_PROBLEM_TYPE "application/problem+json"
|
||||
#define OGS_SBI_CONTENT_PATCH_TYPE \
|
||||
"application/json-patch+json"
|
||||
#define OGS_SBI_CONTENT_3GPPHAL_TYPE "application/3gppHal+json"
|
||||
|
||||
typedef struct ogs_sbi_request_s ogs_sbi_request_t;
|
||||
typedef struct ogs_sbi_response_s ogs_sbi_response_t;
|
||||
|
||||
typedef struct ogs_sbi_header_s {
|
||||
char *method;
|
||||
char *url;
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
} service;
|
||||
|
||||
struct {
|
||||
char *version;
|
||||
} api;
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
char *id;
|
||||
} resource;
|
||||
} ogs_sbi_header_t;
|
||||
|
||||
typedef struct ogs_sbi_message_s {
|
||||
ogs_sbi_header_t h;
|
||||
|
||||
struct {
|
||||
char *content_encoding;
|
||||
char *content_type;
|
||||
bool location;
|
||||
char *cache_control;
|
||||
} http;
|
||||
|
||||
struct {
|
||||
OpenAPI_nf_type_e target_nf_type;
|
||||
OpenAPI_nf_type_e requester_nf_type;
|
||||
OpenAPI_nf_type_e nf_type;
|
||||
int limit;
|
||||
} param;
|
||||
|
||||
int res_status;
|
||||
|
||||
OpenAPI_nf_profile_t *NFProfile;
|
||||
OpenAPI_problem_details_t *ProblemDetails;
|
||||
OpenAPI_list_t *PatchItemList;
|
||||
|
||||
OpenAPI_subscription_data_t *SubscriptionData;
|
||||
OpenAPI_notification_data_t *NotificationData;
|
||||
OpenAPI_search_result_t *SearchResult;
|
||||
|
||||
ogs_sbi_links_t *links;
|
||||
} ogs_sbi_message_t;
|
||||
|
||||
void ogs_sbi_message_init(int num_of_request_pool, int num_of_response_pool);
|
||||
void ogs_sbi_message_final(void);
|
||||
|
||||
void ogs_sbi_message_free(ogs_sbi_message_t *message);
|
||||
|
||||
ogs_sbi_request_t *ogs_sbi_request_new(void);
|
||||
void ogs_sbi_request_free(ogs_sbi_request_t *request);
|
||||
ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message);
|
||||
int ogs_sbi_parse_request(
|
||||
ogs_sbi_message_t *message, ogs_sbi_request_t *request);
|
||||
|
||||
ogs_sbi_response_t *ogs_sbi_response_new(void);
|
||||
void ogs_sbi_response_free(ogs_sbi_response_t *response);
|
||||
ogs_sbi_response_t *ogs_sbi_build_response(ogs_sbi_message_t *message);
|
||||
int ogs_sbi_parse_response(
|
||||
ogs_sbi_message_t *message, ogs_sbi_response_t *response);
|
||||
|
||||
void ogs_sbi_header_set(ogs_hash_t *ht, const void *key, const void *val);
|
||||
void *ogs_sbi_header_get(ogs_hash_t *ht, const void *key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_MESSAGE_H */
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nnrf-build.h"
|
||||
|
||||
OpenAPI_nf_profile_t *ogs_sbi_nnrf_build_nf_profile(
|
||||
ogs_sbi_nf_instance_t *nf_instance)
|
||||
{
|
||||
ogs_sbi_nf_service_t *nf_service = NULL;
|
||||
|
||||
OpenAPI_nf_profile_t *NFProfile = NULL;
|
||||
OpenAPI_list_t *Ipv4AddrList = NULL;
|
||||
OpenAPI_list_t *Ipv6AddrList = NULL;
|
||||
OpenAPI_list_t *NFServiceList = NULL;
|
||||
|
||||
int i = 0;
|
||||
int fqdn_len;
|
||||
char fqdn[OGS_MAX_FQDN_LEN+1];
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
|
||||
NFProfile = ogs_calloc(1, sizeof(*NFProfile));
|
||||
ogs_assert(NFProfile);
|
||||
|
||||
NFProfile->nf_instance_id = nf_instance->id;
|
||||
NFProfile->nf_type = nf_instance->nf_type;
|
||||
NFProfile->nf_status = nf_instance->nf_status;
|
||||
|
||||
if (strlen(nf_instance->fqdn)) {
|
||||
memset(fqdn, 0, sizeof(fqdn));
|
||||
fqdn_len = ogs_fqdn_build(fqdn,
|
||||
nf_instance->fqdn, strlen(nf_instance->fqdn));
|
||||
NFProfile->fqdn = ogs_memdup(fqdn, fqdn_len);
|
||||
}
|
||||
|
||||
Ipv4AddrList = OpenAPI_list_create();
|
||||
ogs_assert(Ipv4AddrList);
|
||||
Ipv6AddrList = OpenAPI_list_create();
|
||||
ogs_assert(Ipv6AddrList);
|
||||
|
||||
for (i = 0; i < nf_instance->num_of_ipv4; i++) {
|
||||
if (nf_instance->ipv4[i])
|
||||
OpenAPI_list_add(Ipv4AddrList, ogs_ipstrdup(nf_instance->ipv4[i]));
|
||||
}
|
||||
for (i = 0; i < nf_instance->num_of_ipv6; i++) {
|
||||
if (nf_instance->ipv6[i])
|
||||
OpenAPI_list_add(Ipv6AddrList, ogs_ipstrdup(nf_instance->ipv6[i]));
|
||||
}
|
||||
|
||||
if (Ipv4AddrList->count)
|
||||
NFProfile->ipv4_addresses = Ipv4AddrList;
|
||||
else
|
||||
OpenAPI_list_free(Ipv4AddrList);
|
||||
if (Ipv6AddrList->count)
|
||||
NFProfile->ipv6_addresses = Ipv6AddrList;
|
||||
else
|
||||
OpenAPI_list_free(Ipv6AddrList);
|
||||
|
||||
NFServiceList = OpenAPI_list_create();
|
||||
ogs_assert(NFServiceList);
|
||||
|
||||
ogs_list_for_each(&nf_instance->nf_service_list, nf_service) {
|
||||
OpenAPI_nf_service_t *NFService = NULL;
|
||||
OpenAPI_list_t *VersionList = NULL;
|
||||
OpenAPI_list_t *IpEndPointList = NULL;
|
||||
|
||||
NFService = ogs_calloc(1, sizeof(*NFService));
|
||||
ogs_assert(NFService);
|
||||
NFService->service_instance_id = ogs_strdup(nf_service->id);
|
||||
NFService->service_name = ogs_strdup(nf_service->name);
|
||||
|
||||
VersionList = OpenAPI_list_create();
|
||||
ogs_assert(VersionList);
|
||||
|
||||
for (i = 0; i < nf_service->num_of_version; i++) {
|
||||
OpenAPI_nf_service_version_t *NFServiceVersion = NULL;
|
||||
|
||||
NFServiceVersion = ogs_calloc(1, sizeof(*NFServiceVersion));
|
||||
ogs_assert(NFServiceVersion);
|
||||
if (nf_service->versions[i].in_uri)
|
||||
NFServiceVersion->api_version_in_uri =
|
||||
ogs_strdup(nf_service->versions[i].in_uri);
|
||||
if (nf_service->versions[i].full)
|
||||
NFServiceVersion->api_full_version =
|
||||
ogs_strdup(nf_service->versions[i].full);
|
||||
if (nf_service->versions[i].expiry)
|
||||
NFServiceVersion->expiry =
|
||||
ogs_strdup(nf_service->versions[i].expiry);
|
||||
|
||||
OpenAPI_list_add(VersionList, NFServiceVersion);
|
||||
}
|
||||
|
||||
ogs_assert(VersionList->count);
|
||||
NFService->versions = VersionList;
|
||||
|
||||
NFService->scheme = nf_service->scheme;
|
||||
NFService->nf_service_status = nf_service->status;
|
||||
|
||||
if (strlen(nf_service->fqdn)) {
|
||||
memset(fqdn, 0, sizeof(fqdn));
|
||||
fqdn_len = ogs_fqdn_build(fqdn,
|
||||
nf_service->fqdn, strlen(nf_service->fqdn));
|
||||
NFService->fqdn = ogs_memdup(fqdn, fqdn_len);
|
||||
}
|
||||
|
||||
IpEndPointList = OpenAPI_list_create();
|
||||
ogs_assert(IpEndPointList);
|
||||
|
||||
for (i = 0; i < nf_service->num_of_addr; i++) {
|
||||
ogs_sockaddr_t *ipv4 = NULL;
|
||||
ogs_sockaddr_t *ipv6 = NULL;
|
||||
|
||||
OpenAPI_ip_end_point_t *IpEndPoint = NULL;
|
||||
|
||||
ipv4 = nf_service->addr[i].ipv4;
|
||||
ipv6 = nf_service->addr[i].ipv6;
|
||||
|
||||
if (ipv4 || ipv6) {
|
||||
IpEndPoint = ogs_calloc(1, sizeof(*IpEndPoint));
|
||||
ogs_assert(IpEndPoint);
|
||||
if (ipv4) IpEndPoint->ipv4_address = ogs_ipstrdup(ipv4);
|
||||
if (ipv6) IpEndPoint->ipv6_address = ogs_ipstrdup(ipv6);
|
||||
IpEndPoint->port = nf_service->addr[i].port;
|
||||
OpenAPI_list_add(IpEndPointList, IpEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (IpEndPointList->count)
|
||||
NFService->ip_end_points = IpEndPointList;
|
||||
else
|
||||
OpenAPI_list_free(IpEndPointList);
|
||||
|
||||
OpenAPI_list_add(NFServiceList, NFService);
|
||||
}
|
||||
|
||||
if (NFServiceList->count)
|
||||
NFProfile->nf_services = NFServiceList;
|
||||
else
|
||||
OpenAPI_list_free(NFServiceList);
|
||||
|
||||
return NFProfile;
|
||||
}
|
||||
|
||||
void ogs_sbi_nnrf_free_nf_profile(OpenAPI_nf_profile_t *NFProfile)
|
||||
{
|
||||
OpenAPI_lnode_t *node = NULL;
|
||||
|
||||
ogs_assert(NFProfile);
|
||||
|
||||
OpenAPI_list_for_each(NFProfile->ipv4_addresses, node)
|
||||
ogs_free(node->data);
|
||||
OpenAPI_list_free(NFProfile->ipv4_addresses);
|
||||
OpenAPI_list_for_each(NFProfile->ipv6_addresses, node)
|
||||
ogs_free(node->data);
|
||||
OpenAPI_list_free(NFProfile->ipv6_addresses);
|
||||
|
||||
OpenAPI_list_for_each(NFProfile->nf_services, node) {
|
||||
OpenAPI_lnode_t *node2;
|
||||
OpenAPI_nf_service_t *NFService = node->data;
|
||||
ogs_assert(NFService);
|
||||
|
||||
ogs_free(NFService->service_instance_id);
|
||||
ogs_free(NFService->service_name);
|
||||
|
||||
OpenAPI_list_for_each(NFService->versions, node2) {
|
||||
OpenAPI_nf_service_version_t *NFServiceVersion = node2->data;
|
||||
ogs_assert(NFServiceVersion);
|
||||
ogs_free(NFServiceVersion->api_version_in_uri);
|
||||
ogs_free(NFServiceVersion->api_full_version);
|
||||
if (NFServiceVersion->expiry)
|
||||
ogs_free(NFServiceVersion->expiry);
|
||||
ogs_free(NFServiceVersion);
|
||||
}
|
||||
OpenAPI_list_free(NFService->versions);
|
||||
|
||||
OpenAPI_list_for_each(NFService->ip_end_points, node2) {
|
||||
OpenAPI_ip_end_point_t *IpEndPoint = node2->data;
|
||||
ogs_assert(IpEndPoint);
|
||||
if (IpEndPoint->ipv4_address)
|
||||
ogs_free(IpEndPoint->ipv4_address);
|
||||
if (IpEndPoint->ipv6_address)
|
||||
ogs_free(IpEndPoint->ipv6_address);
|
||||
ogs_free(IpEndPoint);
|
||||
}
|
||||
OpenAPI_list_free(NFService->ip_end_points);
|
||||
|
||||
if (NFService->fqdn)
|
||||
ogs_free(NFService->fqdn);
|
||||
|
||||
ogs_free(NFService);
|
||||
}
|
||||
OpenAPI_list_free(NFProfile->nf_services);
|
||||
|
||||
if (NFProfile->fqdn)
|
||||
ogs_free(NFProfile->fqdn);
|
||||
|
||||
ogs_free(NFProfile);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGS_NNRF_BUILD_H
|
||||
#define OGS_NNRF_BUILD_H
|
||||
|
||||
#include "ogs-sbi.h"
|
||||
#include "context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
OpenAPI_nf_profile_t *ogs_sbi_nnrf_build_nf_profile(
|
||||
ogs_sbi_nf_instance_t *nf_instance);
|
||||
void ogs_sbi_nnrf_free_nf_profile(OpenAPI_nf_profile_t *NFProfile);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_NNRF_BUILD_H */
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nnrf-handler.h"
|
||||
|
||||
bool ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance,
|
||||
OpenAPI_nf_profile_t *NFProfile,
|
||||
ogs_sbi_session_t *session, ogs_sbi_message_t *message)
|
||||
{
|
||||
int rv;
|
||||
|
||||
OpenAPI_lnode_t *node;
|
||||
|
||||
ogs_assert(nf_instance);
|
||||
ogs_assert(NFProfile);
|
||||
|
||||
if (!NFProfile) {
|
||||
ogs_error("No NFProfile");
|
||||
if (session)
|
||||
ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
message, "No NFProfile", NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NFProfile->nf_instance_id) {
|
||||
ogs_error("No NFProfile.NFInstanceId");
|
||||
if (session)
|
||||
ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
message, "NFProfile", "No NFInstanceId");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NFProfile->nf_type) {
|
||||
ogs_error("No NFProfile.NFType");
|
||||
if (session)
|
||||
ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
message, "NFProfile", "No NFType");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NFProfile->nf_status) {
|
||||
ogs_error("No NFProfile.NFStatus");
|
||||
if (session)
|
||||
ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
message, "NFProfile", "No NFStatus");
|
||||
return false;
|
||||
}
|
||||
|
||||
ogs_sbi_nf_instance_clear(nf_instance);
|
||||
|
||||
nf_instance->nf_type = NFProfile->nf_type;
|
||||
nf_instance->nf_status = NFProfile->nf_status;
|
||||
nf_instance->time.heartbeat = NFProfile->heart_beat_timer;
|
||||
|
||||
if (NFProfile->fqdn)
|
||||
ogs_fqdn_parse(nf_instance->fqdn,
|
||||
NFProfile->fqdn, strlen(NFProfile->fqdn));
|
||||
|
||||
/* Only one time handles RegisterNFInstance operation */
|
||||
OpenAPI_list_for_each(NFProfile->ipv4_addresses, node) {
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
|
||||
if (!node->data) continue;
|
||||
|
||||
if (nf_instance->num_of_ipv4 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
|
||||
|
||||
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
|
||||
node->data, OGS_SBI_HTTPS_PORT, 0);
|
||||
if (rv != OGS_OK) continue;
|
||||
|
||||
nf_instance->ipv4[nf_instance->num_of_ipv4] = addr;
|
||||
nf_instance->num_of_ipv4++;
|
||||
}
|
||||
}
|
||||
OpenAPI_list_for_each(NFProfile->ipv6_addresses, node) {
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
|
||||
if (!node->data) continue;
|
||||
|
||||
if (nf_instance->num_of_ipv6 < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
|
||||
|
||||
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
|
||||
node->data, OGS_SBI_HTTPS_PORT, 0);
|
||||
if (rv != OGS_OK) continue;
|
||||
|
||||
nf_instance->ipv6[nf_instance->num_of_ipv6] = addr;
|
||||
nf_instance->num_of_ipv6++;
|
||||
}
|
||||
}
|
||||
|
||||
OpenAPI_list_for_each(NFProfile->nf_services, node) {
|
||||
OpenAPI_nf_service_t *NFService = node->data;
|
||||
OpenAPI_list_t *VersionList = NULL;
|
||||
OpenAPI_list_t *IpEndPointList = NULL;
|
||||
OpenAPI_lnode_t *node2 = NULL;
|
||||
|
||||
ogs_sbi_nf_service_t *nf_service = NULL;
|
||||
|
||||
if (!NFService) continue;
|
||||
|
||||
VersionList = NFService->versions;
|
||||
IpEndPointList = NFService->ip_end_points;
|
||||
|
||||
nf_service = ogs_sbi_nf_service_add(nf_instance,
|
||||
NFService->service_instance_id,
|
||||
NFService->service_name, NFService->scheme);
|
||||
ogs_assert(nf_service);
|
||||
|
||||
OpenAPI_list_for_each(VersionList, node2) {
|
||||
OpenAPI_nf_service_version_t *NFServiceVersion = node2->data;
|
||||
|
||||
if (!NFServiceVersion) continue;
|
||||
|
||||
ogs_sbi_nf_service_add_version(nf_service,
|
||||
NFServiceVersion->api_version_in_uri,
|
||||
NFServiceVersion->api_full_version,
|
||||
NFServiceVersion->expiry);
|
||||
}
|
||||
|
||||
if (NFService->fqdn)
|
||||
ogs_fqdn_parse(nf_service->fqdn,
|
||||
NFService->fqdn, strlen(NFService->fqdn));
|
||||
|
||||
nf_service->num_of_addr = 0;
|
||||
OpenAPI_list_for_each(IpEndPointList, node2) {
|
||||
OpenAPI_ip_end_point_t *IpEndPoint = node2->data;
|
||||
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
|
||||
int port = 0;
|
||||
|
||||
if (!IpEndPoint) continue;
|
||||
|
||||
if (nf_service->num_of_addr < OGS_SBI_MAX_NUM_OF_IP_ADDRESS) {
|
||||
port = IpEndPoint->port;
|
||||
if (!port) {
|
||||
if (nf_service->scheme == OpenAPI_uri_scheme_http)
|
||||
port = OGS_SBI_HTTP_PORT;
|
||||
else if (nf_service->scheme == OpenAPI_uri_scheme_https)
|
||||
port = OGS_SBI_HTTPS_PORT;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IpEndPoint->ipv4_address) {
|
||||
rv = ogs_getaddrinfo(&addr, AF_UNSPEC,
|
||||
IpEndPoint->ipv4_address, port, 0);
|
||||
if (rv != OGS_OK) continue;
|
||||
}
|
||||
if (IpEndPoint->ipv6_address) {
|
||||
rv = ogs_getaddrinfo(&addr6, AF_UNSPEC,
|
||||
IpEndPoint->ipv6_address, port, 0);
|
||||
if (rv != OGS_OK) continue;
|
||||
}
|
||||
|
||||
if (addr || addr6) {
|
||||
nf_service->addr[nf_service->num_of_addr].
|
||||
port = port;
|
||||
nf_service->addr[nf_service->num_of_addr].
|
||||
ipv4 = addr;
|
||||
nf_service->addr[nf_service->num_of_addr].
|
||||
ipv6 = addr6;
|
||||
}
|
||||
nf_service->num_of_addr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGS_NNRF_HANDLER_H
|
||||
#define OGS_NNRF_HANDLER_H
|
||||
|
||||
#include "ogs-sbi.h"
|
||||
#include "context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance,
|
||||
OpenAPI_nf_profile_t *NFProfile,
|
||||
ogs_sbi_session_t *session, ogs_sbi_message_t *message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_NNRF_HANDLER_H */
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGS_SBI_H
|
||||
#define OGS_SBI_H
|
||||
|
||||
#include "ogs-core.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||
#endif
|
||||
|
||||
#include "model/nf_profile.h"
|
||||
#include "model/nf_group_cond.h"
|
||||
#include "model/smf_info.h"
|
||||
#include "model/problem_details.h"
|
||||
#include "model/patch_item.h"
|
||||
#include "model/subscription_data.h"
|
||||
#include "model/notification_data.h"
|
||||
#include "model/search_result.h"
|
||||
|
||||
#include "custom/links.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#define OGS_SBI_INSIDE
|
||||
|
||||
#include "sbi/conv.h"
|
||||
#include "sbi/message.h"
|
||||
|
||||
#include "sbi/server.h"
|
||||
#include "sbi/client.h"
|
||||
#include "sbi/context.h"
|
||||
|
||||
#include "sbi/nnrf-build.h"
|
||||
#include "sbi/nnrf-handler.h"
|
||||
|
||||
#undef OGS_SBI_INSIDE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int __ogs_sbi_domain;
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
#define OGS_LOG_DOMAIN __ogs_sbi_domain
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_H */
|
|
@ -0,0 +1,16 @@
|
|||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
api/**
|
||||
|
||||
include/apiClient.h
|
||||
|
||||
src/apiClient.c
|
||||
src/binary.c
|
||||
|
||||
unit-test/**
|
||||
|
||||
README.md
|
||||
libcurl.licence
|
||||
uncrustify-rules.cfg
|
||||
CMakeLists.txt
|
|
@ -0,0 +1 @@
|
|||
4.3.1-SNAPSHOT
|
|
@ -0,0 +1,6 @@
|
|||
enablePostProcessFile: true
|
||||
templateDir: "../openapi/.openapi-generator/templates"
|
||||
reservedWordMappings:
|
||||
3GPP_ACCESS: "3GPP_ACCESS"
|
||||
5G_EIR: "5G_EIR"
|
||||
5GMM: "5GMM"
|
|
@ -0,0 +1,23 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../include/keyValuePair.h"
|
||||
|
||||
OpenAPI_map_t *OpenAPI_map_create(char *key, void *value)
|
||||
{
|
||||
OpenAPI_map_t *OpenAPI_map = ogs_malloc(sizeof(OpenAPI_map_t));
|
||||
OpenAPI_map->key = key;
|
||||
OpenAPI_map->value = value;
|
||||
return OpenAPI_map;
|
||||
}
|
||||
|
||||
OpenAPI_map_t *OpenAPI_map_create_allocate(char *key, double value)
|
||||
{
|
||||
double* boolpointer = ogs_malloc(sizeof(value));
|
||||
memcpy(boolpointer, &value, sizeof(value));
|
||||
return OpenAPI_map_create(key, boolpointer);
|
||||
}
|
||||
|
||||
void OpenAPI_map_free(OpenAPI_map_t *OpenAPI_map)
|
||||
{
|
||||
ogs_free(OpenAPI_map);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../include/binary.h"
|
||||
#ifdef OPENSSL
|
||||
#include "openssl/pem.h"
|
||||
#endif
|
||||
|
||||
OpenAPI_binary_t *OpenAPI_instantiate_binary_t(char *data, int len)
|
||||
{
|
||||
binary_t* ret = malloc(sizeof(struct binary_t));
|
||||
|
||||
ret->len=len;
|
||||
ret->data = malloc(len);
|
||||
memcpy(ret->data, data, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *OpenAPI_base64encode(const void *b64_encode_this,
|
||||
int encode_this_many_bytes)
|
||||
{
|
||||
#ifdef OPENSSL
|
||||
BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
|
||||
BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data.
|
||||
b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO.
|
||||
mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO.
|
||||
BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain.
|
||||
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less.
|
||||
BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data.
|
||||
BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters.
|
||||
BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure.
|
||||
BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed.
|
||||
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
|
||||
BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null.
|
||||
(*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail.
|
||||
return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct).
|
||||
#else // OPENSSL
|
||||
#warning Data will not be encoded. If you want to use function "base64encode", please define "-DOPENSSL" when building the library.
|
||||
return NULL;
|
||||
#endif // OPENSSL
|
||||
}
|
||||
|
||||
char *OpenAPI_base64decode(const void *b64_decode_this,
|
||||
int decode_this_many_bytes, int *decoded_bytes)
|
||||
{
|
||||
#ifdef OPENSSL
|
||||
BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
|
||||
char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null.
|
||||
b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO.
|
||||
mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO.
|
||||
BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source.
|
||||
BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain.
|
||||
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines.
|
||||
int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written.
|
||||
while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte.
|
||||
decoded_byte_index++; //Increment the index until read of BIO decoded data is complete.
|
||||
} //Once we're done reading decoded data, BIO_read returns -1 even though there's no error.
|
||||
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
|
||||
*decoded_bytes = decoded_byte_index;
|
||||
return base64_decoded; //Returns base-64 decoded data with trailing null terminator.
|
||||
#else // OPENSSL
|
||||
#warning Data will not be decoded. If you want to use function "base64decode", please define "-DOPENSSL" when building the library.
|
||||
return NULL;
|
||||
#endif // OPENSSL
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef OGS_SBI_BINARY_H
|
||||
#define OGS_SBI_BINARY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_binary_s {
|
||||
uint8_t* data;
|
||||
unsigned int len;
|
||||
} OpenAPI_binary_t;
|
||||
|
||||
OpenAPI_binary_t *OpenAPI_instantiate_binary_t(char *data, int len);
|
||||
|
||||
char *OpenAPI_base64encode(const void *b64_encode_this,
|
||||
int encode_this_many_bytes);
|
||||
|
||||
char *OpenAPI_base64decode(const void *b64_decode_this,
|
||||
int decode_this_many_bytes, int *decoded_bytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OGS_SBI_BINARY_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 7
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type __stdcall
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
|
||||
#endif
|
||||
#else /* !WIN32 */
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef OGS_SBI_MAP_H
|
||||
#define OGS_SBI_MAP_H
|
||||
|
||||
#include "ogs-core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_map_s {
|
||||
char *key;
|
||||
void *value;
|
||||
} OpenAPI_map_t;
|
||||
|
||||
OpenAPI_map_t *OpenAPI_map_create(char *key, void *value);
|
||||
|
||||
OpenAPI_map_t *OpenAPI_map_create_allocate(char *key, double value);
|
||||
|
||||
void OpenAPI_map_free(OpenAPI_map_t *OpenAPI_map);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_MAP_H */
|
|
@ -0,0 +1,169 @@
|
|||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../include/list.h"
|
||||
static OpenAPI_lnode_t *listEntry_create(void *data)
|
||||
{
|
||||
OpenAPI_lnode_t *created = ogs_malloc(sizeof(OpenAPI_lnode_t));
|
||||
|
||||
if (created == NULL) {
|
||||
// TODO Malloc Failure
|
||||
return NULL;
|
||||
}
|
||||
created->data = data;
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
void OpenAPI_lnode_free(OpenAPI_lnode_t *listEntry, void *additionalData)
|
||||
{
|
||||
ogs_free(listEntry);
|
||||
}
|
||||
|
||||
void OpenAPI_lnode_print(OpenAPI_lnode_t *listEntry, void *additionalData)
|
||||
{
|
||||
printf("%i\n", *((int *) (listEntry->data)));
|
||||
}
|
||||
|
||||
OpenAPI_list_t *OpenAPI_list_create(void)
|
||||
{
|
||||
OpenAPI_list_t *createdList = ogs_malloc(sizeof(OpenAPI_list_t));
|
||||
|
||||
if (createdList == NULL) {
|
||||
// TODO Malloc Failure
|
||||
return NULL;
|
||||
}
|
||||
createdList->first = NULL;
|
||||
createdList->last = NULL;
|
||||
createdList->count = 0;
|
||||
|
||||
return createdList;
|
||||
}
|
||||
|
||||
void OpenAPI_list_iterate_forward(OpenAPI_list_t *list,
|
||||
void (*operationToPerform)(
|
||||
OpenAPI_lnode_t *, void *callbackFunctionUsedData),
|
||||
void *additionalDataNeededForCallbackFunction)
|
||||
{
|
||||
OpenAPI_lnode_t *current = list->first;
|
||||
OpenAPI_lnode_t *next;
|
||||
|
||||
if (current == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
next = current->next;
|
||||
|
||||
operationToPerform(current, additionalDataNeededForCallbackFunction);
|
||||
current = next;
|
||||
|
||||
while (current != NULL) {
|
||||
next = current->next;
|
||||
operationToPerform(current, additionalDataNeededForCallbackFunction);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenAPI_list_iterate_backward(OpenAPI_list_t *list,
|
||||
void (*operationToPerform)(
|
||||
OpenAPI_lnode_t *, void *callbackFunctionUsedData),
|
||||
void *additionalDataNeededForCallbackFunction)
|
||||
{
|
||||
OpenAPI_lnode_t *current = list->last;
|
||||
OpenAPI_lnode_t *next = current->prev;
|
||||
|
||||
if (current == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
operationToPerform(current, additionalDataNeededForCallbackFunction);
|
||||
current = next;
|
||||
|
||||
while (current != NULL) {
|
||||
next = current->prev;
|
||||
operationToPerform(current, additionalDataNeededForCallbackFunction);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenAPI_list_free(OpenAPI_list_t *list)
|
||||
{
|
||||
if (list){
|
||||
OpenAPI_list_iterate_forward(list, OpenAPI_lnode_free, NULL);
|
||||
ogs_free(list);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenAPI_list_add(OpenAPI_list_t *list, void *dataToAddInList)
|
||||
{
|
||||
OpenAPI_lnode_t *newListEntry = listEntry_create(dataToAddInList);
|
||||
if (newListEntry == NULL) {
|
||||
// TODO Malloc Failure
|
||||
return;
|
||||
}
|
||||
if (list->first == NULL) {
|
||||
list->first = newListEntry;
|
||||
list->last = newListEntry;
|
||||
|
||||
newListEntry->prev = NULL;
|
||||
newListEntry->next = NULL;
|
||||
|
||||
list->count++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list->last->next = newListEntry;
|
||||
newListEntry->prev = list->last;
|
||||
newListEntry->next = NULL;
|
||||
list->last = newListEntry;
|
||||
|
||||
list->count++;
|
||||
}
|
||||
|
||||
void OpenAPI_list_remove(OpenAPI_list_t *list, OpenAPI_lnode_t *elementToRemove)
|
||||
{
|
||||
OpenAPI_lnode_t *elementBeforeElementToRemove = elementToRemove->prev;
|
||||
OpenAPI_lnode_t *elementAfterElementToRemove = elementToRemove->next;
|
||||
|
||||
if (elementBeforeElementToRemove != NULL) {
|
||||
elementBeforeElementToRemove->next = elementAfterElementToRemove;
|
||||
} else {
|
||||
list->first = elementAfterElementToRemove;
|
||||
}
|
||||
|
||||
if (elementAfterElementToRemove != NULL) {
|
||||
elementAfterElementToRemove->prev = elementBeforeElementToRemove;
|
||||
} else {
|
||||
list->last = elementBeforeElementToRemove;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_free(elementToRemove, NULL);
|
||||
|
||||
list->count--;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *OpenAPI_list_find(OpenAPI_list_t *list, long indexOfElement)
|
||||
{
|
||||
OpenAPI_lnode_t *current;
|
||||
int i;
|
||||
|
||||
if ((list->count / 2) > indexOfElement) {
|
||||
current = list->first;
|
||||
|
||||
for(i = 0; i < indexOfElement; i++) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current;
|
||||
} else {
|
||||
current = list->last;
|
||||
|
||||
for(i = 1; i < (list->count - indexOfElement); i++) {
|
||||
current = current->prev;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef OGS_SBI_LIST_H
|
||||
#define OGS_SBI_LIST_H
|
||||
|
||||
#include "../external/cJSON.h"
|
||||
#include "ogs-core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OpenAPI_malloc(__sIZE) __sIZE == 0 ? NULL : ogs_malloc(__sIZE)
|
||||
|
||||
typedef struct OpenAPI_list_s OpenAPI_list_t;
|
||||
|
||||
typedef struct OpenAPI_lnode_s OpenAPI_lnode_t;
|
||||
|
||||
struct OpenAPI_lnode_s {
|
||||
OpenAPI_lnode_t *next;
|
||||
OpenAPI_lnode_t *prev;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef struct OpenAPI_list_s {
|
||||
OpenAPI_lnode_t *first;
|
||||
OpenAPI_lnode_t *last;
|
||||
|
||||
long count;
|
||||
} OpenAPI_list_t;
|
||||
|
||||
#define OpenAPI_list_for_each(list, element) for(element = (list != NULL) ? (list)->first : NULL; element != NULL; element = element->next)
|
||||
|
||||
OpenAPI_list_t *OpenAPI_list_create(void);
|
||||
void OpenAPI_list_free(OpenAPI_list_t *listToFree);
|
||||
|
||||
void OpenAPI_list_add(OpenAPI_list_t *list, void *dataToAddInList);
|
||||
OpenAPI_lnode_t *OpenAPI_list_find(OpenAPI_list_t *list, long indexOfElement);
|
||||
void OpenAPI_list_remove(
|
||||
OpenAPI_list_t *list, OpenAPI_lnode_t *elementToRemove);
|
||||
|
||||
void OpenAPI_list_iterate_forward(OpenAPI_list_t *list,
|
||||
void (*operationToPerform)(OpenAPI_lnode_t*, void*),
|
||||
void *additionalDataNeededForCallbackFunction);
|
||||
void OpenAPI_list_iterate_backward(OpenAPI_list_t *list,
|
||||
void (*operationToPerform)(OpenAPI_lnode_t*, void*),
|
||||
void *additionalDataNeededForCallbackFunction);
|
||||
|
||||
void OpenAPI_lnode_print(OpenAPI_lnode_t *listEntry, void *additionalData);
|
||||
void OpenAPI_lnode_free(OpenAPI_lnode_t *listEntry, void *additionalData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OGS_SBI_LIST_H
|
|
@ -0,0 +1,776 @@
|
|||
{{#models}}{{#model}}
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "{{classname}}.h"
|
||||
|
||||
{{#isEnum}}
|
||||
char* OpenAPI_{{classname}}_ToString(OpenAPI_{{classVarName}}_e {{classname}})
|
||||
{
|
||||
const char *{{classname}}Array[] = { "NULL"{{#allowableValues}}{{#enumVars}}, "{{{value}}}"{{/enumVars}}{{/allowableValues}} };
|
||||
size_t sizeofArray = sizeof({{classname}}Array) / sizeof({{classname}}Array[0]);
|
||||
if ({{classname}} < sizeofArray)
|
||||
return (char *){{classname}}Array[{{classname}}];
|
||||
else
|
||||
return (char *)"Unknown";
|
||||
}
|
||||
|
||||
OpenAPI_{{classVarName}}_e OpenAPI_{{classname}}_FromString(char* {{classname}})
|
||||
{
|
||||
int stringToReturn = 0;
|
||||
const char *{{classname}}Array[] = { "NULL"{{#allowableValues}}{{#enumVars}}, "{{{value}}}"{{/enumVars}}{{/allowableValues}} };
|
||||
size_t sizeofArray = sizeof({{classname}}Array) / sizeof({{classname}}Array[0]);
|
||||
while (stringToReturn < sizeofArray) {
|
||||
if (strcmp({{classname}}, {{classname}}Array[stringToReturn]) == 0) {
|
||||
return stringToReturn;
|
||||
}
|
||||
stringToReturn++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
char *OpenAPI_{{name}}{{classname}}_ToString(OpenAPI_{{classVarName}}_{{name}}_e {{name}})
|
||||
{
|
||||
const char *{{name}}Array[] = { "NULL"{{#allowableValues}}{{#enumVars}}, "{{{value}}}"{{/enumVars}}{{/allowableValues}} };
|
||||
size_t sizeofArray = sizeof({{name}}Array) / sizeof({{name}}Array[0]);
|
||||
if ({{name}} < sizeofArray)
|
||||
return (char *){{name}}Array[{{name}}];
|
||||
else
|
||||
return (char *)"Unknown";
|
||||
}
|
||||
|
||||
OpenAPI_{{classVarName}}_{{name}}_e OpenAPI_{{name}}{{classname}}_FromString(char* {{name}})
|
||||
{
|
||||
int stringToReturn = 0;
|
||||
const char *{{name}}Array[] = { "NULL"{{#allowableValues}}{{#enumVars}}, "{{{value}}}"{{/enumVars}}{{/allowableValues}} };
|
||||
size_t sizeofArray = sizeof({{name}}Array) / sizeof({{name}}Array[0]);
|
||||
while (stringToReturn < sizeofArray) {
|
||||
if (strcmp({{name}}, {{name}}Array[stringToReturn]) == 0) {
|
||||
return stringToReturn;
|
||||
}
|
||||
stringToReturn++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{/vars}}
|
||||
OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_create(
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{^isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{datatype}}_e {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
OpenAPI_{{datatype}}_t *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
OpenAPI_{{datatype}}_t *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{classVarName}}_{{name}}_e {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isNumeric}}
|
||||
{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isBoolean}}
|
||||
{{#isString}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isByteArray}}
|
||||
{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isByteArray}}
|
||||
{{#isBinary}}
|
||||
OpenAPI_{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
OpenAPI_{{datatype}}_t *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
OpenAPI_{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{/vars}})
|
||||
{
|
||||
OpenAPI_{{classname}}_t *{{classname}}_local_var = OpenAPI_malloc(sizeof(OpenAPI_{{classname}}_t));
|
||||
if (!{{classname}}_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
{{#vars}}
|
||||
{{classname}}_local_var->{{{name}}} = {{{name}}};
|
||||
{{/vars}}
|
||||
|
||||
return {{classname}}_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_{{classname}}_free(OpenAPI_{{classname}}_t *{{classname}})
|
||||
{
|
||||
if (NULL == {{classname}}) {
|
||||
return ;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{^isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
OpenAPI_{{{complexType}}}_free({{{classname}}}->{{{name}}});
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
ogs_free({{{classname}}}->{{{name}}});
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
ogs_free({{{classname}}}->{{{name}}});
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
OpenAPI_object_free({{{classname}}}->{{{name}}});
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{#isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
{{#isString}}
|
||||
ogs_free({{{classname}}}->{{{name}}});
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isBinary}}
|
||||
ogs_free({{{classname}}}->{{{name}}}->data);
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
ogs_free({{{classname}}}->{{{name}}});
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
ogs_free({{{classname}}}->{{{name}}});
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
OpenAPI_list_for_each({{classname}}->{{name}}, node) {
|
||||
ogs_free(node->data);
|
||||
}
|
||||
{{/isEnum}}
|
||||
OpenAPI_list_free({{classname}}->{{name}});
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
OpenAPI_list_for_each({{classname}}->{{name}}, node) {
|
||||
OpenAPI_{{complexType}}_free(node->data);
|
||||
}
|
||||
{{/isEnum}}
|
||||
OpenAPI_list_free({{classname}}->{{name}});
|
||||
{{/isPrimitiveType}}
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
OpenAPI_list_for_each({{classname}}->{{name}}, node) {
|
||||
OpenAPI_map_t *localKeyValue = (OpenAPI_map_t*)node->data;
|
||||
OpenAPI_{{complexType}}_free(localKeyValue->value);
|
||||
ogs_free(localKeyValue);
|
||||
}
|
||||
OpenAPI_list_free({{classname}}->{{name}});
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{/vars}}
|
||||
ogs_free({{classname}});
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_{{classname}}_convertToJSON(OpenAPI_{{classname}}_t *{{classname}})
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if ({{classname}} == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
{{#vars}}
|
||||
{{#required}}
|
||||
if (!{{{classname}}}->{{{name}}}) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if ({{{classname}}}->{{{name}}}) {
|
||||
{{/required}}
|
||||
{{^isContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", OpenAPI_{{{name}}}{{classname}}_ToString({{{classname}}}->{{{name}}})) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isNumeric}}
|
||||
if (cJSON_AddNumberToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
if (cJSON_AddBoolToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isBoolean}}
|
||||
{{#isString}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isByteArray}}
|
||||
if (cJSON_AddNumberToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isByteArray}}
|
||||
{{#isBinary}}
|
||||
char* encoded_str_{{{name}}} = OpenAPI_base64encode({{{classname}}}->{{{name}}}->data,{{{classname}}}->{{{name}}}->len);
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", encoded_str_{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
ogs_free(encoded_str_{{{name}}});
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", OpenAPI_{{{complexType}}}_ToString({{{classname}}}->{{{name}}})) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
cJSON *{{{name}}}_local_JSON = OpenAPI_{{complexType}}{{#isFreeFormObject}}object{{/isFreeFormObject}}_convertToJSON({{{classname}}}->{{{name}}});
|
||||
if ({{{name}}}_local_JSON == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToObject(item, "{{{baseName}}}", {{{name}}}_local_JSON);
|
||||
if (item->child == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
cJSON *{{{name}}}_object = OpenAPI_object_convertToJSON({{{classname}}}->{{{name}}});
|
||||
if ({{{name}}}_object == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToObject(item, "{{{baseName}}}", {{{name}}}_object);
|
||||
if (item->child == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
cJSON *{{{name}}} = cJSON_AddArrayToObject(item, "{{{baseName}}}");
|
||||
if ({{{name}}} == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *{{{name}}}_node;
|
||||
OpenAPI_list_for_each({{{classname}}}->{{{name}}}, {{{name}}}_node) {
|
||||
{{#items}}
|
||||
{{#isString}}
|
||||
if (cJSON_AddStringToObject({{{name}}}, "", (char*){{{name}}}_node->data) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isString}}
|
||||
{{#isBoolean}}
|
||||
if (cJSON_AddBoolToObject({{{name}}}, "", *(cJSON_bool *){{{name}}}_node->data) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isBoolean}}
|
||||
{{#isNumeric}}
|
||||
if (cJSON_AddNumberToObject({{{name}}}, "", *(double *){{{name}}}_node->data) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isNumeric}}
|
||||
{{/items}}
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
cJSON *{{{name}}}List = cJSON_AddArrayToObject(item, "{{{baseName}}}");
|
||||
if ({{{name}}}List == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *{{{name}}}_node;
|
||||
if ({{{classname}}}->{{{name}}}) {
|
||||
OpenAPI_list_for_each({{classname}}->{{{name}}}, {{{name}}}_node) {
|
||||
cJSON *itemLocal = OpenAPI_{{complexType}}_convertToJSON({{#isEnum}}{{#items}}(OpenAPI_{{classVarName}}_{{name}}_e){{/items}}{{/isEnum}}{{{name}}}_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray({{{name}}}List, itemLocal);
|
||||
}
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{#isEnum}}
|
||||
cJSON *{{{name}}} = cJSON_AddArrayToObject(item, "{{{baseName}}}");
|
||||
if ({{{name}}} == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_lnode_t *{{{name}}}_node;
|
||||
OpenAPI_list_for_each({{classname}}->{{{name}}}, {{{name}}}_node) {
|
||||
if (cJSON_AddStringToObject({{{name}}}, "", OpenAPI_{{{complexType}}}_ToString((OpenAPI_{{{complexType}}}_e){{{name}}}_node->data)) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
cJSON *{{{name}}} = cJSON_AddObjectToObject(item, "{{{baseName}}}");
|
||||
if ({{{name}}} == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
cJSON *localMapObject = {{{name}}};
|
||||
OpenAPI_lnode_t *{{{name}}}_node;
|
||||
if ({{{classname}}}->{{{name}}}) {
|
||||
OpenAPI_list_for_each({{{classname}}}->{{{name}}}, {{{name}}}_node) {
|
||||
OpenAPI_map_t *localKeyValue = (OpenAPI_map_t*){{{name}}}_node->data;
|
||||
{{#isPrimitiveType}}
|
||||
{{#isString}}
|
||||
if (cJSON_AddStringToObject(localMapObject, localKeyValue->key, (char*)localKeyValue->value) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isString}}
|
||||
{{#isNumeric}}
|
||||
if (cJSON_AddNumberToObject(localMapObject, localKeyValue->key, *(double *)localKeyValue->value) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
if (cJSON_AddBoolToObject(localMapObject, localKeyValue->key, *(cJSON_bool *)localKeyValue->value) == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isBoolean}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
cJSON *itemLocal = OpenAPI_{{complexType}}_convertToJSON(localKeyValue->value);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToObject({{{name}}}, localKeyValue->key, itemLocal);
|
||||
{{/isPrimitiveType}}
|
||||
}
|
||||
}
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
|
||||
{{/vars}}
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_parseFromJSON(cJSON *{{classname}}JSON)
|
||||
{
|
||||
OpenAPI_{{classname}}_t *{{classname}}_local_var = NULL;
|
||||
{{#vars}}
|
||||
cJSON *{{{name}}} = cJSON_GetObjectItemCaseSensitive({{classname}}JSON, "{{{baseName}}}");
|
||||
{{#required}}
|
||||
if (!{{{name}}}) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/required}}
|
||||
|
||||
{{^isContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{classVarName}}_{{name}}_e {{name}}Variable;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{name}}Variable = OpenAPI_{{name}}{{classname}}_FromString({{{name}}}->valuestring);
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isNumeric}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsNumber({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsBool({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isBoolean}}
|
||||
{{#isString}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isByteArray}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsNumber({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isByteArray}}
|
||||
{{#isBinary}}
|
||||
OpenAPI_binary_t* decoded_str_{{{name}}} = OpenAPI_malloc(sizeof(struct binary_t));
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
decoded_str_{{{name}}}->data = OpenAPI_base64decode({{{name}}}->valuestring, strlen({{{name}}}->valuestring), &decoded_str_{{{name}}}->len);
|
||||
if (!decoded_str_{{{name}}}->data) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{complexType}}_e {{name}}Variable;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{name}}Variable = OpenAPI_{{complexType}}_FromString({{{name}}}->valuestring);
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
{{^isFreeFormObject}}OpenAPI_{{complexType}}{{/isFreeFormObject}}{{#isFreeFormObject}}OpenAPI_object{{/isFreeFormObject}}_t *{{name}}_local_nonprim = NULL;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
{{{name}}}_local_nonprim = OpenAPI_{{complexType}}{{#isFreeFormObject}}object{{/isFreeFormObject}}_parseFromJSON({{{name}}});
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
if (!cJSON_IsString({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
OpenAPI_object_t *{{name}}_local_object = NULL;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
{{{name}}}_local_object = OpenAPI_object_parseFromJSON({{{name}}});
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
OpenAPI_list_t *{{{name}}}List;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
cJSON *{{{name}}}_local;
|
||||
if (!cJSON_IsArray({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{{name}}}List = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach({{{name}}}_local, {{{name}}}) {
|
||||
{{#items}}
|
||||
{{#isString}}
|
||||
if (!cJSON_IsString({{{name}}}_local)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_list_add({{{name}}}List , ogs_strdup({{{name}}}_local->valuestring));
|
||||
{{/isString}}
|
||||
{{#isNumeric}}
|
||||
if (!cJSON_IsNumber({{{name}}}_local)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_list_add({{{name}}}List , &{{{name}}}_local->valuedouble);
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
if (!cJSON_IsBool({{{name}}}_local)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_list_add({{{name}}}List , {{{name}}}_local->valueint);
|
||||
{{/isBoolean}}
|
||||
{{/items}}
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
{{^isEnum}}
|
||||
OpenAPI_list_t *{{{name}}}List;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
cJSON *{{{name}}}_local_nonprimitive;
|
||||
if (!cJSON_IsArray({{{name}}})){
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
{{{name}}}List = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach({{{name}}}_local_nonprimitive, {{{name}}} ) {
|
||||
if (!cJSON_IsObject({{{name}}}_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{#isEnum}}{{#items}}{{datatypeWithEnum}}_e {{/items}}{{/isEnum}}{{^isEnum}}OpenAPI_{{complexType}}_t *{{/isEnum}}{{{name}}}Item = OpenAPI_{{complexType}}_parseFromJSON({{{name}}}_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add({{{name}}}List, {{#isEnum}}{{#items}}(void *){{/items}}{{/isEnum}}{{{name}}}Item);
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_list_t *{{{name}}}List;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
cJSON *{{{name}}}_local_nonprimitive;
|
||||
if (!cJSON_IsArray({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
{{{name}}}List = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach({{{name}}}_local_nonprimitive, {{{name}}} ) {
|
||||
if (!cJSON_IsString({{{name}}}_local_nonprimitive)){
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_list_add({{{name}}}List, (void *)OpenAPI_{{{complexType}}}_FromString({{{name}}}_local_nonprimitive->valuestring));
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
OpenAPI_list_t *{{{name}}}List;
|
||||
{{^required}}if ({{{name}}}) { {{/required}}
|
||||
cJSON *{{{name}}}_local_map;
|
||||
if (!cJSON_IsObject({{{name}}})) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
{{{name}}}List = OpenAPI_list_create();
|
||||
OpenAPI_map_t *localMapKeyPair = NULL;
|
||||
cJSON_ArrayForEach({{{name}}}_local_map, {{{name}}}) {
|
||||
cJSON *localMapObject = {{{name}}}_local_map;
|
||||
{{#isPrimitiveType}}
|
||||
{{#isString}}
|
||||
if (!cJSON_IsString(localMapObject)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string),ogs_strdup(localMapObject->valuestring));
|
||||
{{/isString}}
|
||||
{{#isBoolean}}
|
||||
if (!cJSON_IsBool(localMapObject)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), &localMapObject->valueint);
|
||||
{{/isBoolean}}
|
||||
{{#isNumeric}}
|
||||
if (!cJSON_IsNumber(localMapObject)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string),&localMapObject->valuedouble );
|
||||
{{/isNumeric}}
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
if (!cJSON_IsObject({{{name}}}_local_map)) {
|
||||
ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
|
||||
goto end;
|
||||
}
|
||||
localMapKeyPair = OpenAPI_map_create(
|
||||
localMapObject->string, OpenAPI_{{complexType}}_parseFromJSON(localMapObject));
|
||||
{{/isPrimitiveType}}
|
||||
OpenAPI_list_add({{{name}}}List , localMapKeyPair);
|
||||
}
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
|
||||
{{/vars}}
|
||||
{{classname}}_local_var = OpenAPI_{{classname}}_create (
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{^isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}Variable{{^required}} : 0{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}_local_nonprim{{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
{{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
{{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}_local_object{{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{name}}Variable{{^required}} : 0{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isNumeric}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}->valuedouble{{^required}} : 0{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}->valueint{{^required}} : 0{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isBoolean}}
|
||||
{{#isString}}
|
||||
{{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isByteArray}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}->valueint{{^required}} : 0{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isByteArray}}
|
||||
{{#isBinary}}
|
||||
{{^required}}{{{name}}} ? {{/required}}decoded_str_{{{name}}}{{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
{{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
{{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}List{{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
{{^required}}{{{name}}} ? {{/required}}{{{name}}}List{{^required}} : NULL{{/required}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{/vars}}
|
||||
);
|
||||
|
||||
return {{classname}}_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{/model}}{{/models}}
|
|
@ -0,0 +1,181 @@
|
|||
{{#models}}{{#model}}/*
|
||||
* {{classname}}.h
|
||||
*
|
||||
* {{description}}
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_{{classname}}_H_
|
||||
#define _OpenAPI_{{classname}}_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
{{#imports}}
|
||||
#include "{{{.}}}.h"
|
||||
{{/imports}}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
{{#isEnum}}
|
||||
{{#allowableValues}}
|
||||
typedef enum { OpenAPI_{{classVarName}}_NULL = 0{{#enumVars}}, OpenAPI_{{classVarName}}_{{{value}}}{{/enumVars}} } OpenAPI_{{classVarName}}_e;
|
||||
{{/allowableValues}}
|
||||
|
||||
char* OpenAPI_{{classname}}_ToString(OpenAPI_{{classVarName}}_e {{classname}});
|
||||
|
||||
OpenAPI_{{classVarName}}_e OpenAPI_{{classname}}_FromString(char* {{classname}});
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
typedef struct OpenAPI_{{classname}}_s OpenAPI_{{classname}}_t;
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
{{#allowableValues}}
|
||||
typedef enum { OpenAPI_{{classVarName}}_{{enumName}}_NULL = 0{{#enumVars}}, OpenAPI_{{classVarName}}_{{enumName}}_{{{value}}}{{/enumVars}} } OpenAPI_{{classVarName}}_{{name}}_e;
|
||||
{{/allowableValues}}
|
||||
|
||||
char* OpenAPI_{{classVarName}}_{{name}}_ToString(OpenAPI_{{classVarName}}_{{name}}_e {{name}});
|
||||
|
||||
OpenAPI_{{classVarName}}_{{name}}_e OpenAPI_{{classVarName}}_{{name}}_FromString(char* {{name}});
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{/vars}}
|
||||
typedef struct OpenAPI_{{classname}}_s {
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{^isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{datatype}}_e {{name}};
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
struct OpenAPI_{{datatype}}_s *{{name}};
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
{{datatype}} *{{name}};
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
{{datatype}} *{{name}};
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
OpenAPI_{{datatype}}_t *{{name}};
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{classVarName}}_{{name}}_e {{name}};
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isNumeric}}
|
||||
{{datatype}} {{name}};
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
{{datatype}} {{name}};
|
||||
{{/isBoolean}}
|
||||
{{#isString}}
|
||||
{{datatype}} *{{name}};
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isByteArray}}
|
||||
{{datatype}} {{name}};
|
||||
{{/isByteArray}}
|
||||
{{#isBinary}}
|
||||
OpenAPI_{{datatype}} {{name}};
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
{{datatype}} *{{name}};
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
{{datatype}} *{{name}};
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
OpenAPI_{{datatype}}_t *{{name}};
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
OpenAPI_{{datatype}} {{name}};
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{/vars}}
|
||||
} OpenAPI_{{classname}}_t;
|
||||
|
||||
OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_create(
|
||||
{{#vars}}
|
||||
{{^isContainer}}
|
||||
{{^isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{datatype}}_e {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isModel}}
|
||||
OpenAPI_{{datatype}}_t *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isModel}}
|
||||
{{#isUuid}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isUuid}}
|
||||
{{#isEmail}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEmail}}
|
||||
{{#isFreeFormObject}}
|
||||
OpenAPI_{{datatype}}_t *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isFreeFormObject}}
|
||||
{{/isEnum}}
|
||||
{{/isPrimitiveType}}
|
||||
{{#isPrimitiveType}}
|
||||
{{#isEnum}}
|
||||
OpenAPI_{{classVarName}}_{{name}}_e {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isEnum}}
|
||||
{{^isEnum}}
|
||||
{{#isNumeric}}
|
||||
{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isNumeric}}
|
||||
{{#isBoolean}}
|
||||
{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isBoolean}}
|
||||
{{#isString}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isString}}
|
||||
{{/isEnum}}
|
||||
{{#isByteArray}}
|
||||
{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isByteArray}}
|
||||
{{#isBinary}}
|
||||
OpenAPI_{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isBinary}}
|
||||
{{#isDate}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isDate}}
|
||||
{{#isDateTime}}
|
||||
{{datatype}} *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isDateTime}}
|
||||
{{/isPrimitiveType}}
|
||||
{{/isContainer}}
|
||||
{{#isContainer}}
|
||||
{{#isListContainer}}
|
||||
OpenAPI_{{datatype}}_t *{{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isListContainer}}
|
||||
{{#isMapContainer}}
|
||||
OpenAPI_{{datatype}} {{name}}{{#hasMore}},{{/hasMore}}
|
||||
{{/isMapContainer}}
|
||||
{{/isContainer}}
|
||||
{{/vars}});
|
||||
void OpenAPI_{{classname}}_free(OpenAPI_{{classname}}_t *{{classname}});
|
||||
OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_parseFromJSON(cJSON *{{classname}}JSON);
|
||||
cJSON *OpenAPI_{{classname}}_convertToJSON(OpenAPI_{{classname}}_t *{{classname}});
|
||||
{{/isEnum}}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_{{classname}}_H_ */
|
||||
{{/model}}{{/models}}
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "object.h"
|
||||
|
||||
OpenAPI_object_t *OpenAPI_object_create(void)
|
||||
{
|
||||
OpenAPI_object_t *object = ogs_malloc(sizeof(OpenAPI_object_t));
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void OpenAPI_object_free(OpenAPI_object_t *object)
|
||||
{
|
||||
ogs_free (object);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_object_convertToJSON(OpenAPI_object_t *object)
|
||||
{
|
||||
cJSON *item = cJSON_CreateObject();
|
||||
|
||||
return item;
|
||||
fail:
|
||||
cJSON_Delete(item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OpenAPI_object_t *OpenAPI_object_parseFromJSON(cJSON *objectJSON)
|
||||
{
|
||||
OpenAPI_object_t *object = NULL;
|
||||
|
||||
return object;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef OGS_SBI_OBJECT_H
|
||||
#define OGS_SBI_OBJECT_H
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_object_s {
|
||||
void *temporary;
|
||||
} OpenAPI_object_t;
|
||||
|
||||
OpenAPI_object_t *OpenAPI_object_create(void);
|
||||
|
||||
void OpenAPI_object_free(OpenAPI_object_t *object);
|
||||
|
||||
OpenAPI_object_t *OpenAPI_object_parseFromJSON(cJSON *objectJSON);
|
||||
|
||||
cJSON *OpenAPI_object_convertToJSON(OpenAPI_object_t *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_OBJECT_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 7
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type __stdcall
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
|
||||
#endif
|
||||
#else /* !WIN32 */
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef OGS_SBI_BINARY_H
|
||||
#define OGS_SBI_BINARY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_binary_s {
|
||||
uint8_t* data;
|
||||
unsigned int len;
|
||||
} OpenAPI_binary_t;
|
||||
|
||||
OpenAPI_binary_t *OpenAPI_instantiate_binary_t(char *data, int len);
|
||||
|
||||
char *OpenAPI_base64encode(const void *b64_encode_this,
|
||||
int encode_this_many_bytes);
|
||||
|
||||
char *OpenAPI_base64decode(const void *b64_decode_this,
|
||||
int decode_this_many_bytes, int *decoded_bytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OGS_SBI_BINARY_H
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef OGS_SBI_MAP_H
|
||||
#define OGS_SBI_MAP_H
|
||||
|
||||
#include "ogs-core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_map_s {
|
||||
char *key;
|
||||
void *value;
|
||||
} OpenAPI_map_t;
|
||||
|
||||
OpenAPI_map_t *OpenAPI_map_create(char *key, void *value);
|
||||
|
||||
OpenAPI_map_t *OpenAPI_map_create_allocate(char *key, double value);
|
||||
|
||||
void OpenAPI_map_free(OpenAPI_map_t *OpenAPI_map);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OGS_SBI_MAP_H */
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef OGS_SBI_LIST_H
|
||||
#define OGS_SBI_LIST_H
|
||||
|
||||
#include "../external/cJSON.h"
|
||||
#include "ogs-core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OpenAPI_malloc(__sIZE) __sIZE == 0 ? NULL : ogs_malloc(__sIZE)
|
||||
|
||||
typedef struct OpenAPI_list_s OpenAPI_list_t;
|
||||
|
||||
typedef struct OpenAPI_lnode_s OpenAPI_lnode_t;
|
||||
|
||||
struct OpenAPI_lnode_s {
|
||||
OpenAPI_lnode_t *next;
|
||||
OpenAPI_lnode_t *prev;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef struct OpenAPI_list_s {
|
||||
OpenAPI_lnode_t *first;
|
||||
OpenAPI_lnode_t *last;
|
||||
|
||||
long count;
|
||||
} OpenAPI_list_t;
|
||||
|
||||
#define OpenAPI_list_for_each(list, element) for(element = (list != NULL) ? (list)->first : NULL; element != NULL; element = element->next)
|
||||
|
||||
OpenAPI_list_t *OpenAPI_list_create(void);
|
||||
void OpenAPI_list_free(OpenAPI_list_t *listToFree);
|
||||
|
||||
void OpenAPI_list_add(OpenAPI_list_t *list, void *dataToAddInList);
|
||||
OpenAPI_lnode_t *OpenAPI_list_find(OpenAPI_list_t *list, long indexOfElement);
|
||||
void OpenAPI_list_remove(
|
||||
OpenAPI_list_t *list, OpenAPI_lnode_t *elementToRemove);
|
||||
|
||||
void OpenAPI_list_iterate_forward(OpenAPI_list_t *list,
|
||||
void (*operationToPerform)(OpenAPI_lnode_t*, void*),
|
||||
void *additionalDataNeededForCallbackFunction);
|
||||
void OpenAPI_list_iterate_backward(OpenAPI_list_t *list,
|
||||
void (*operationToPerform)(OpenAPI_lnode_t*, void*),
|
||||
void *additionalDataNeededForCallbackFunction);
|
||||
|
||||
void OpenAPI_lnode_print(OpenAPI_lnode_t *listEntry, void *additionalData);
|
||||
void OpenAPI_lnode_free(OpenAPI_lnode_t *listEntry, void *additionalData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OGS_SBI_LIST_H
|
|
@ -0,0 +1,131 @@
|
|||
# Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
|
||||
# This file is part of Open5GS.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
libsbi_openapi_sources = files('''
|
||||
src/list.c
|
||||
src/apiKey.c
|
||||
external/cJSON.c
|
||||
model/object.c
|
||||
model/access_type.c
|
||||
model/amf_cond.c
|
||||
model/amf_info.c
|
||||
model/atsss_capability.c
|
||||
model/ausf_info.c
|
||||
model/bsf_info.c
|
||||
model/change_item.c
|
||||
model/change_type.c
|
||||
model/chf_info.c
|
||||
model/chf_service_info.c
|
||||
model/data_set_id.c
|
||||
model/default_notification_subscription.c
|
||||
model/dnn_smf_info_item.c
|
||||
model/dnn_upf_info_item.c
|
||||
model/event_id.c
|
||||
model/guami.c
|
||||
model/guami_list_cond.c
|
||||
model/identity_range.c
|
||||
model/inline_response_200.c
|
||||
model/interface_upf_info_item.c
|
||||
model/invalid_param.c
|
||||
model/ip_end_point.c
|
||||
model/ipv4_address_range.c
|
||||
model/ipv6_prefix_range.c
|
||||
model/link.c
|
||||
model/links_value_schema.c
|
||||
model/n1_message_class.c
|
||||
model/n2_information_class.c
|
||||
model/n2_interface_amf_info.c
|
||||
model/network_slice_cond.c
|
||||
model/nf_group_cond.c
|
||||
model/nf_instance_id_cond.c
|
||||
model/nf_profile.c
|
||||
model/nf_service.c
|
||||
model/nf_service_status.c
|
||||
model/nf_service_version.c
|
||||
model/nf_status.c
|
||||
model/nf_type.c
|
||||
model/nf_type_cond.c
|
||||
model/notif_condition.c
|
||||
model/notification_data.c
|
||||
model/notification_event_type.c
|
||||
model/notification_type.c
|
||||
model/nrf_info.c
|
||||
model/nwdaf_event.c
|
||||
model/nwdaf_info.c
|
||||
model/patch_item.c
|
||||
model/patch_operation.c
|
||||
model/pcf_info.c
|
||||
model/pdu_session_type.c
|
||||
model/plmn_id.c
|
||||
model/plmn_range.c
|
||||
model/plmn_snssai.c
|
||||
model/problem_details.c
|
||||
model/service_name_cond.c
|
||||
model/smf_info.c
|
||||
model/snssai.c
|
||||
model/snssai_smf_info_item.c
|
||||
model/snssai_upf_info_item.c
|
||||
model/subscription_data.c
|
||||
model/supi_range.c
|
||||
model/tac_range.c
|
||||
model/tai.c
|
||||
model/tai_range.c
|
||||
model/transport_protocol.c
|
||||
model/udm_info.c
|
||||
model/udr_info.c
|
||||
model/up_interface_type.c
|
||||
model/upf_info.c
|
||||
model/uri_scheme.c
|
||||
|
||||
model/atom.c
|
||||
model/cnf.c
|
||||
model/cnf_unit.c
|
||||
model/complex_query.c
|
||||
model/dnf.c
|
||||
model/dnf_unit.c
|
||||
model/search_result.c
|
||||
model/stored_search_result.c
|
||||
|
||||
'''.split())
|
||||
|
||||
libsbi_openapi_inc = include_directories('.')
|
||||
|
||||
sbi_openapi_cc_flags = ['-DOGS_SBI_COMPILATION']
|
||||
|
||||
if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
|
||||
sbi_openapi_cc_flags += cc.get_supported_arguments([
|
||||
'-Wno-strict-prototypes',
|
||||
'-Wno-missing-prototypes',
|
||||
'-Wno-missing-declarations',
|
||||
'-Wno-unused-variable',
|
||||
'-Wno-unused-label',
|
||||
'-Wno-float-equal',
|
||||
])
|
||||
endif
|
||||
|
||||
libsbi_openapi = library('ogssbi-openapi',
|
||||
sources : libsbi_openapi_sources,
|
||||
version : libogslib_version,
|
||||
c_args : sbi_openapi_cc_flags,
|
||||
include_directories : [libsbi_openapi_inc, libinc],
|
||||
dependencies : libcore_dep,
|
||||
install : true)
|
||||
|
||||
libsbi_openapi_dep = declare_dependency(
|
||||
link_with : libsbi_openapi,
|
||||
include_directories : [libsbi_openapi_inc, libinc],
|
||||
dependencies : libcore_dep)
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "access_type.h"
|
||||
|
||||
char* OpenAPI_access_type_ToString(OpenAPI_access_type_e access_type)
|
||||
{
|
||||
const char *access_typeArray[] = { "NULL", "3GPP_ACCESS", "NON_3GPP_ACCESS" };
|
||||
size_t sizeofArray = sizeof(access_typeArray) / sizeof(access_typeArray[0]);
|
||||
if (access_type < sizeofArray)
|
||||
return (char *)access_typeArray[access_type];
|
||||
else
|
||||
return (char *)"Unknown";
|
||||
}
|
||||
|
||||
OpenAPI_access_type_e OpenAPI_access_type_FromString(char* access_type)
|
||||
{
|
||||
int stringToReturn = 0;
|
||||
const char *access_typeArray[] = { "NULL", "3GPP_ACCESS", "NON_3GPP_ACCESS" };
|
||||
size_t sizeofArray = sizeof(access_typeArray) / sizeof(access_typeArray[0]);
|
||||
while (stringToReturn < sizeofArray) {
|
||||
if (strcmp(access_type, access_typeArray[stringToReturn]) == 0) {
|
||||
return stringToReturn;
|
||||
}
|
||||
stringToReturn++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* access_type.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_access_type_H_
|
||||
#define _OpenAPI_access_type_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum { OpenAPI_access_type_NULL = 0, OpenAPI_access_type_3GPP_ACCESS, OpenAPI_access_type_NON_3GPP_ACCESS } OpenAPI_access_type_e;
|
||||
|
||||
char* OpenAPI_access_type_ToString(OpenAPI_access_type_e access_type);
|
||||
|
||||
OpenAPI_access_type_e OpenAPI_access_type_FromString(char* access_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_access_type_H_ */
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "amf_cond.h"
|
||||
|
||||
OpenAPI_amf_cond_t *OpenAPI_amf_cond_create(
|
||||
char *amf_set_id,
|
||||
char *amf_region_id
|
||||
)
|
||||
{
|
||||
OpenAPI_amf_cond_t *amf_cond_local_var = OpenAPI_malloc(sizeof(OpenAPI_amf_cond_t));
|
||||
if (!amf_cond_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
amf_cond_local_var->amf_set_id = amf_set_id;
|
||||
amf_cond_local_var->amf_region_id = amf_region_id;
|
||||
|
||||
return amf_cond_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_amf_cond_free(OpenAPI_amf_cond_t *amf_cond)
|
||||
{
|
||||
if (NULL == amf_cond) {
|
||||
return;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
ogs_free(amf_cond->amf_set_id);
|
||||
ogs_free(amf_cond->amf_region_id);
|
||||
ogs_free(amf_cond);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_amf_cond_convertToJSON(OpenAPI_amf_cond_t *amf_cond)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if (amf_cond == NULL) {
|
||||
ogs_error("OpenAPI_amf_cond_convertToJSON() failed [AmfCond]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
if (amf_cond->amf_set_id) {
|
||||
if (cJSON_AddStringToObject(item, "amfSetId", amf_cond->amf_set_id) == NULL) {
|
||||
ogs_error("OpenAPI_amf_cond_convertToJSON() failed [amf_set_id]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (amf_cond->amf_region_id) {
|
||||
if (cJSON_AddStringToObject(item, "amfRegionId", amf_cond->amf_region_id) == NULL) {
|
||||
ogs_error("OpenAPI_amf_cond_convertToJSON() failed [amf_region_id]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_amf_cond_t *OpenAPI_amf_cond_parseFromJSON(cJSON *amf_condJSON)
|
||||
{
|
||||
OpenAPI_amf_cond_t *amf_cond_local_var = NULL;
|
||||
cJSON *amf_set_id = cJSON_GetObjectItemCaseSensitive(amf_condJSON, "amfSetId");
|
||||
|
||||
if (amf_set_id) {
|
||||
if (!cJSON_IsString(amf_set_id)) {
|
||||
ogs_error("OpenAPI_amf_cond_parseFromJSON() failed [amf_set_id]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *amf_region_id = cJSON_GetObjectItemCaseSensitive(amf_condJSON, "amfRegionId");
|
||||
|
||||
if (amf_region_id) {
|
||||
if (!cJSON_IsString(amf_region_id)) {
|
||||
ogs_error("OpenAPI_amf_cond_parseFromJSON() failed [amf_region_id]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
amf_cond_local_var = OpenAPI_amf_cond_create (
|
||||
amf_set_id ? ogs_strdup(amf_set_id->valuestring) : NULL,
|
||||
amf_region_id ? ogs_strdup(amf_region_id->valuestring) : NULL
|
||||
);
|
||||
|
||||
return amf_cond_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* amf_cond.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_amf_cond_H_
|
||||
#define _OpenAPI_amf_cond_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_amf_cond_s OpenAPI_amf_cond_t;
|
||||
typedef struct OpenAPI_amf_cond_s {
|
||||
char *amf_set_id;
|
||||
char *amf_region_id;
|
||||
} OpenAPI_amf_cond_t;
|
||||
|
||||
OpenAPI_amf_cond_t *OpenAPI_amf_cond_create(
|
||||
char *amf_set_id,
|
||||
char *amf_region_id
|
||||
);
|
||||
void OpenAPI_amf_cond_free(OpenAPI_amf_cond_t *amf_cond);
|
||||
OpenAPI_amf_cond_t *OpenAPI_amf_cond_parseFromJSON(cJSON *amf_condJSON);
|
||||
cJSON *OpenAPI_amf_cond_convertToJSON(OpenAPI_amf_cond_t *amf_cond);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_amf_cond_H_ */
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "amf_info.h"
|
||||
|
||||
OpenAPI_amf_info_t *OpenAPI_amf_info_create(
|
||||
char *amf_set_id,
|
||||
char *amf_region_id,
|
||||
OpenAPI_list_t *guami_list,
|
||||
OpenAPI_list_t *tai_list,
|
||||
OpenAPI_list_t *tai_range_list,
|
||||
OpenAPI_list_t *backup_info_amf_failure,
|
||||
OpenAPI_list_t *backup_info_amf_removal,
|
||||
OpenAPI_n2_interface_amf_info_t *n2_interface_amf_info
|
||||
)
|
||||
{
|
||||
OpenAPI_amf_info_t *amf_info_local_var = OpenAPI_malloc(sizeof(OpenAPI_amf_info_t));
|
||||
if (!amf_info_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
amf_info_local_var->amf_set_id = amf_set_id;
|
||||
amf_info_local_var->amf_region_id = amf_region_id;
|
||||
amf_info_local_var->guami_list = guami_list;
|
||||
amf_info_local_var->tai_list = tai_list;
|
||||
amf_info_local_var->tai_range_list = tai_range_list;
|
||||
amf_info_local_var->backup_info_amf_failure = backup_info_amf_failure;
|
||||
amf_info_local_var->backup_info_amf_removal = backup_info_amf_removal;
|
||||
amf_info_local_var->n2_interface_amf_info = n2_interface_amf_info;
|
||||
|
||||
return amf_info_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_amf_info_free(OpenAPI_amf_info_t *amf_info)
|
||||
{
|
||||
if (NULL == amf_info) {
|
||||
return;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
ogs_free(amf_info->amf_set_id);
|
||||
ogs_free(amf_info->amf_region_id);
|
||||
OpenAPI_list_for_each(amf_info->guami_list, node) {
|
||||
OpenAPI_guami_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(amf_info->guami_list);
|
||||
OpenAPI_list_for_each(amf_info->tai_list, node) {
|
||||
OpenAPI_tai_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(amf_info->tai_list);
|
||||
OpenAPI_list_for_each(amf_info->tai_range_list, node) {
|
||||
OpenAPI_tai_range_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(amf_info->tai_range_list);
|
||||
OpenAPI_list_for_each(amf_info->backup_info_amf_failure, node) {
|
||||
OpenAPI_guami_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(amf_info->backup_info_amf_failure);
|
||||
OpenAPI_list_for_each(amf_info->backup_info_amf_removal, node) {
|
||||
OpenAPI_guami_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(amf_info->backup_info_amf_removal);
|
||||
OpenAPI_n2_interface_amf_info_free(amf_info->n2_interface_amf_info);
|
||||
ogs_free(amf_info);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_amf_info_convertToJSON(OpenAPI_amf_info_t *amf_info)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if (amf_info == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [AmfInfo]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
if (!amf_info->amf_set_id) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [amf_set_id]");
|
||||
goto end;
|
||||
}
|
||||
if (cJSON_AddStringToObject(item, "amfSetId", amf_info->amf_set_id) == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [amf_set_id]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!amf_info->amf_region_id) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [amf_region_id]");
|
||||
goto end;
|
||||
}
|
||||
if (cJSON_AddStringToObject(item, "amfRegionId", amf_info->amf_region_id) == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [amf_region_id]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!amf_info->guami_list) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [guami_list]");
|
||||
goto end;
|
||||
}
|
||||
cJSON *guami_listList = cJSON_AddArrayToObject(item, "guamiList");
|
||||
if (guami_listList == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [guami_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *guami_list_node;
|
||||
if (amf_info->guami_list) {
|
||||
OpenAPI_list_for_each(amf_info->guami_list, guami_list_node) {
|
||||
cJSON *itemLocal = OpenAPI_guami_convertToJSON(guami_list_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [guami_list]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(guami_listList, itemLocal);
|
||||
}
|
||||
}
|
||||
|
||||
if (amf_info->tai_list) {
|
||||
cJSON *tai_listList = cJSON_AddArrayToObject(item, "taiList");
|
||||
if (tai_listList == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [tai_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *tai_list_node;
|
||||
if (amf_info->tai_list) {
|
||||
OpenAPI_list_for_each(amf_info->tai_list, tai_list_node) {
|
||||
cJSON *itemLocal = OpenAPI_tai_convertToJSON(tai_list_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [tai_list]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(tai_listList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (amf_info->tai_range_list) {
|
||||
cJSON *tai_range_listList = cJSON_AddArrayToObject(item, "taiRangeList");
|
||||
if (tai_range_listList == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [tai_range_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *tai_range_list_node;
|
||||
if (amf_info->tai_range_list) {
|
||||
OpenAPI_list_for_each(amf_info->tai_range_list, tai_range_list_node) {
|
||||
cJSON *itemLocal = OpenAPI_tai_range_convertToJSON(tai_range_list_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [tai_range_list]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(tai_range_listList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (amf_info->backup_info_amf_failure) {
|
||||
cJSON *backup_info_amf_failureList = cJSON_AddArrayToObject(item, "backupInfoAmfFailure");
|
||||
if (backup_info_amf_failureList == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [backup_info_amf_failure]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *backup_info_amf_failure_node;
|
||||
if (amf_info->backup_info_amf_failure) {
|
||||
OpenAPI_list_for_each(amf_info->backup_info_amf_failure, backup_info_amf_failure_node) {
|
||||
cJSON *itemLocal = OpenAPI_guami_convertToJSON(backup_info_amf_failure_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [backup_info_amf_failure]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(backup_info_amf_failureList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (amf_info->backup_info_amf_removal) {
|
||||
cJSON *backup_info_amf_removalList = cJSON_AddArrayToObject(item, "backupInfoAmfRemoval");
|
||||
if (backup_info_amf_removalList == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [backup_info_amf_removal]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *backup_info_amf_removal_node;
|
||||
if (amf_info->backup_info_amf_removal) {
|
||||
OpenAPI_list_for_each(amf_info->backup_info_amf_removal, backup_info_amf_removal_node) {
|
||||
cJSON *itemLocal = OpenAPI_guami_convertToJSON(backup_info_amf_removal_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [backup_info_amf_removal]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(backup_info_amf_removalList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (amf_info->n2_interface_amf_info) {
|
||||
cJSON *n2_interface_amf_info_local_JSON = OpenAPI_n2_interface_amf_info_convertToJSON(amf_info->n2_interface_amf_info);
|
||||
if (n2_interface_amf_info_local_JSON == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [n2_interface_amf_info]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToObject(item, "n2InterfaceAmfInfo", n2_interface_amf_info_local_JSON);
|
||||
if (item->child == NULL) {
|
||||
ogs_error("OpenAPI_amf_info_convertToJSON() failed [n2_interface_amf_info]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_amf_info_t *OpenAPI_amf_info_parseFromJSON(cJSON *amf_infoJSON)
|
||||
{
|
||||
OpenAPI_amf_info_t *amf_info_local_var = NULL;
|
||||
cJSON *amf_set_id = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "amfSetId");
|
||||
if (!amf_set_id) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [amf_set_id]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (!cJSON_IsString(amf_set_id)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [amf_set_id]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
cJSON *amf_region_id = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "amfRegionId");
|
||||
if (!amf_region_id) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [amf_region_id]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (!cJSON_IsString(amf_region_id)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [amf_region_id]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
cJSON *guami_list = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "guamiList");
|
||||
if (!guami_list) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [guami_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_list_t *guami_listList;
|
||||
|
||||
cJSON *guami_list_local_nonprimitive;
|
||||
if (!cJSON_IsArray(guami_list)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [guami_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
guami_listList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(guami_list_local_nonprimitive, guami_list ) {
|
||||
if (!cJSON_IsObject(guami_list_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [guami_list]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_guami_t *guami_listItem = OpenAPI_guami_parseFromJSON(guami_list_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(guami_listList, guami_listItem);
|
||||
}
|
||||
|
||||
cJSON *tai_list = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "taiList");
|
||||
|
||||
OpenAPI_list_t *tai_listList;
|
||||
if (tai_list) {
|
||||
cJSON *tai_list_local_nonprimitive;
|
||||
if (!cJSON_IsArray(tai_list)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [tai_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
tai_listList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(tai_list_local_nonprimitive, tai_list ) {
|
||||
if (!cJSON_IsObject(tai_list_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [tai_list]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_tai_t *tai_listItem = OpenAPI_tai_parseFromJSON(tai_list_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(tai_listList, tai_listItem);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *tai_range_list = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "taiRangeList");
|
||||
|
||||
OpenAPI_list_t *tai_range_listList;
|
||||
if (tai_range_list) {
|
||||
cJSON *tai_range_list_local_nonprimitive;
|
||||
if (!cJSON_IsArray(tai_range_list)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [tai_range_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
tai_range_listList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(tai_range_list_local_nonprimitive, tai_range_list ) {
|
||||
if (!cJSON_IsObject(tai_range_list_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [tai_range_list]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_tai_range_t *tai_range_listItem = OpenAPI_tai_range_parseFromJSON(tai_range_list_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(tai_range_listList, tai_range_listItem);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *backup_info_amf_failure = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "backupInfoAmfFailure");
|
||||
|
||||
OpenAPI_list_t *backup_info_amf_failureList;
|
||||
if (backup_info_amf_failure) {
|
||||
cJSON *backup_info_amf_failure_local_nonprimitive;
|
||||
if (!cJSON_IsArray(backup_info_amf_failure)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [backup_info_amf_failure]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
backup_info_amf_failureList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(backup_info_amf_failure_local_nonprimitive, backup_info_amf_failure ) {
|
||||
if (!cJSON_IsObject(backup_info_amf_failure_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [backup_info_amf_failure]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_guami_t *backup_info_amf_failureItem = OpenAPI_guami_parseFromJSON(backup_info_amf_failure_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(backup_info_amf_failureList, backup_info_amf_failureItem);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *backup_info_amf_removal = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "backupInfoAmfRemoval");
|
||||
|
||||
OpenAPI_list_t *backup_info_amf_removalList;
|
||||
if (backup_info_amf_removal) {
|
||||
cJSON *backup_info_amf_removal_local_nonprimitive;
|
||||
if (!cJSON_IsArray(backup_info_amf_removal)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [backup_info_amf_removal]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
backup_info_amf_removalList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(backup_info_amf_removal_local_nonprimitive, backup_info_amf_removal ) {
|
||||
if (!cJSON_IsObject(backup_info_amf_removal_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_amf_info_parseFromJSON() failed [backup_info_amf_removal]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_guami_t *backup_info_amf_removalItem = OpenAPI_guami_parseFromJSON(backup_info_amf_removal_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(backup_info_amf_removalList, backup_info_amf_removalItem);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *n2_interface_amf_info = cJSON_GetObjectItemCaseSensitive(amf_infoJSON, "n2InterfaceAmfInfo");
|
||||
|
||||
OpenAPI_n2_interface_amf_info_t *n2_interface_amf_info_local_nonprim = NULL;
|
||||
if (n2_interface_amf_info) {
|
||||
n2_interface_amf_info_local_nonprim = OpenAPI_n2_interface_amf_info_parseFromJSON(n2_interface_amf_info);
|
||||
}
|
||||
|
||||
amf_info_local_var = OpenAPI_amf_info_create (
|
||||
ogs_strdup(amf_set_id->valuestring),
|
||||
ogs_strdup(amf_region_id->valuestring),
|
||||
guami_listList,
|
||||
tai_list ? tai_listList : NULL,
|
||||
tai_range_list ? tai_range_listList : NULL,
|
||||
backup_info_amf_failure ? backup_info_amf_failureList : NULL,
|
||||
backup_info_amf_removal ? backup_info_amf_removalList : NULL,
|
||||
n2_interface_amf_info ? n2_interface_amf_info_local_nonprim : NULL
|
||||
);
|
||||
|
||||
return amf_info_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* amf_info.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_amf_info_H_
|
||||
#define _OpenAPI_amf_info_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
#include "guami.h"
|
||||
#include "n2_interface_amf_info.h"
|
||||
#include "tai.h"
|
||||
#include "tai_range.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_amf_info_s OpenAPI_amf_info_t;
|
||||
typedef struct OpenAPI_amf_info_s {
|
||||
char *amf_set_id;
|
||||
char *amf_region_id;
|
||||
OpenAPI_list_t *guami_list;
|
||||
OpenAPI_list_t *tai_list;
|
||||
OpenAPI_list_t *tai_range_list;
|
||||
OpenAPI_list_t *backup_info_amf_failure;
|
||||
OpenAPI_list_t *backup_info_amf_removal;
|
||||
struct OpenAPI_n2_interface_amf_info_s *n2_interface_amf_info;
|
||||
} OpenAPI_amf_info_t;
|
||||
|
||||
OpenAPI_amf_info_t *OpenAPI_amf_info_create(
|
||||
char *amf_set_id,
|
||||
char *amf_region_id,
|
||||
OpenAPI_list_t *guami_list,
|
||||
OpenAPI_list_t *tai_list,
|
||||
OpenAPI_list_t *tai_range_list,
|
||||
OpenAPI_list_t *backup_info_amf_failure,
|
||||
OpenAPI_list_t *backup_info_amf_removal,
|
||||
OpenAPI_n2_interface_amf_info_t *n2_interface_amf_info
|
||||
);
|
||||
void OpenAPI_amf_info_free(OpenAPI_amf_info_t *amf_info);
|
||||
OpenAPI_amf_info_t *OpenAPI_amf_info_parseFromJSON(cJSON *amf_infoJSON);
|
||||
cJSON *OpenAPI_amf_info_convertToJSON(OpenAPI_amf_info_t *amf_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_amf_info_H_ */
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "atom.h"
|
||||
|
||||
OpenAPI_atom_t *OpenAPI_atom_create(
|
||||
char *attr,
|
||||
char *value,
|
||||
int negative
|
||||
)
|
||||
{
|
||||
OpenAPI_atom_t *atom_local_var = OpenAPI_malloc(sizeof(OpenAPI_atom_t));
|
||||
if (!atom_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
atom_local_var->attr = attr;
|
||||
atom_local_var->value = value;
|
||||
atom_local_var->negative = negative;
|
||||
|
||||
return atom_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_atom_free(OpenAPI_atom_t *atom)
|
||||
{
|
||||
if (NULL == atom) {
|
||||
return;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
ogs_free(atom->attr);
|
||||
ogs_free(atom->value);
|
||||
ogs_free(atom);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_atom_convertToJSON(OpenAPI_atom_t *atom)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if (atom == NULL) {
|
||||
ogs_error("OpenAPI_atom_convertToJSON() failed [Atom]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
if (!atom->attr) {
|
||||
ogs_error("OpenAPI_atom_convertToJSON() failed [attr]");
|
||||
goto end;
|
||||
}
|
||||
if (cJSON_AddStringToObject(item, "attr", atom->attr) == NULL) {
|
||||
ogs_error("OpenAPI_atom_convertToJSON() failed [attr]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!atom->value) {
|
||||
ogs_error("OpenAPI_atom_convertToJSON() failed [value]");
|
||||
goto end;
|
||||
}
|
||||
if (cJSON_AddStringToObject(item, "value", atom->value) == NULL) {
|
||||
ogs_error("OpenAPI_atom_convertToJSON() failed [value]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (atom->negative) {
|
||||
if (cJSON_AddBoolToObject(item, "negative", atom->negative) == NULL) {
|
||||
ogs_error("OpenAPI_atom_convertToJSON() failed [negative]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_atom_t *OpenAPI_atom_parseFromJSON(cJSON *atomJSON)
|
||||
{
|
||||
OpenAPI_atom_t *atom_local_var = NULL;
|
||||
cJSON *attr = cJSON_GetObjectItemCaseSensitive(atomJSON, "attr");
|
||||
if (!attr) {
|
||||
ogs_error("OpenAPI_atom_parseFromJSON() failed [attr]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (!cJSON_IsString(attr)) {
|
||||
ogs_error("OpenAPI_atom_parseFromJSON() failed [attr]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
cJSON *value = cJSON_GetObjectItemCaseSensitive(atomJSON, "value");
|
||||
if (!value) {
|
||||
ogs_error("OpenAPI_atom_parseFromJSON() failed [value]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (!cJSON_IsString(value)) {
|
||||
ogs_error("OpenAPI_atom_parseFromJSON() failed [value]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
cJSON *negative = cJSON_GetObjectItemCaseSensitive(atomJSON, "negative");
|
||||
|
||||
if (negative) {
|
||||
if (!cJSON_IsBool(negative)) {
|
||||
ogs_error("OpenAPI_atom_parseFromJSON() failed [negative]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
atom_local_var = OpenAPI_atom_create (
|
||||
ogs_strdup(attr->valuestring),
|
||||
ogs_strdup(value->valuestring),
|
||||
negative ? negative->valueint : 0
|
||||
);
|
||||
|
||||
return atom_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* atom.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_atom_H_
|
||||
#define _OpenAPI_atom_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_atom_s OpenAPI_atom_t;
|
||||
typedef struct OpenAPI_atom_s {
|
||||
char *attr;
|
||||
char *value;
|
||||
int negative;
|
||||
} OpenAPI_atom_t;
|
||||
|
||||
OpenAPI_atom_t *OpenAPI_atom_create(
|
||||
char *attr,
|
||||
char *value,
|
||||
int negative
|
||||
);
|
||||
void OpenAPI_atom_free(OpenAPI_atom_t *atom);
|
||||
OpenAPI_atom_t *OpenAPI_atom_parseFromJSON(cJSON *atomJSON);
|
||||
cJSON *OpenAPI_atom_convertToJSON(OpenAPI_atom_t *atom);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_atom_H_ */
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "atsss_capability.h"
|
||||
|
||||
OpenAPI_atsss_capability_t *OpenAPI_atsss_capability_create(
|
||||
int atsss_ll,
|
||||
int mptcp
|
||||
)
|
||||
{
|
||||
OpenAPI_atsss_capability_t *atsss_capability_local_var = OpenAPI_malloc(sizeof(OpenAPI_atsss_capability_t));
|
||||
if (!atsss_capability_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
atsss_capability_local_var->atsss_ll = atsss_ll;
|
||||
atsss_capability_local_var->mptcp = mptcp;
|
||||
|
||||
return atsss_capability_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_atsss_capability_free(OpenAPI_atsss_capability_t *atsss_capability)
|
||||
{
|
||||
if (NULL == atsss_capability) {
|
||||
return;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
ogs_free(atsss_capability);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_atsss_capability_convertToJSON(OpenAPI_atsss_capability_t *atsss_capability)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if (atsss_capability == NULL) {
|
||||
ogs_error("OpenAPI_atsss_capability_convertToJSON() failed [AtsssCapability]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
if (atsss_capability->atsss_ll) {
|
||||
if (cJSON_AddBoolToObject(item, "atsssLL", atsss_capability->atsss_ll) == NULL) {
|
||||
ogs_error("OpenAPI_atsss_capability_convertToJSON() failed [atsss_ll]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (atsss_capability->mptcp) {
|
||||
if (cJSON_AddBoolToObject(item, "mptcp", atsss_capability->mptcp) == NULL) {
|
||||
ogs_error("OpenAPI_atsss_capability_convertToJSON() failed [mptcp]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_atsss_capability_t *OpenAPI_atsss_capability_parseFromJSON(cJSON *atsss_capabilityJSON)
|
||||
{
|
||||
OpenAPI_atsss_capability_t *atsss_capability_local_var = NULL;
|
||||
cJSON *atsss_ll = cJSON_GetObjectItemCaseSensitive(atsss_capabilityJSON, "atsssLL");
|
||||
|
||||
if (atsss_ll) {
|
||||
if (!cJSON_IsBool(atsss_ll)) {
|
||||
ogs_error("OpenAPI_atsss_capability_parseFromJSON() failed [atsss_ll]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *mptcp = cJSON_GetObjectItemCaseSensitive(atsss_capabilityJSON, "mptcp");
|
||||
|
||||
if (mptcp) {
|
||||
if (!cJSON_IsBool(mptcp)) {
|
||||
ogs_error("OpenAPI_atsss_capability_parseFromJSON() failed [mptcp]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
atsss_capability_local_var = OpenAPI_atsss_capability_create (
|
||||
atsss_ll ? atsss_ll->valueint : 0,
|
||||
mptcp ? mptcp->valueint : 0
|
||||
);
|
||||
|
||||
return atsss_capability_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* atsss_capability.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_atsss_capability_H_
|
||||
#define _OpenAPI_atsss_capability_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_atsss_capability_s OpenAPI_atsss_capability_t;
|
||||
typedef struct OpenAPI_atsss_capability_s {
|
||||
int atsss_ll;
|
||||
int mptcp;
|
||||
} OpenAPI_atsss_capability_t;
|
||||
|
||||
OpenAPI_atsss_capability_t *OpenAPI_atsss_capability_create(
|
||||
int atsss_ll,
|
||||
int mptcp
|
||||
);
|
||||
void OpenAPI_atsss_capability_free(OpenAPI_atsss_capability_t *atsss_capability);
|
||||
OpenAPI_atsss_capability_t *OpenAPI_atsss_capability_parseFromJSON(cJSON *atsss_capabilityJSON);
|
||||
cJSON *OpenAPI_atsss_capability_convertToJSON(OpenAPI_atsss_capability_t *atsss_capability);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_atsss_capability_H_ */
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "ausf_info.h"
|
||||
|
||||
OpenAPI_ausf_info_t *OpenAPI_ausf_info_create(
|
||||
char *group_id,
|
||||
OpenAPI_list_t *supi_ranges,
|
||||
OpenAPI_list_t *routing_indicators
|
||||
)
|
||||
{
|
||||
OpenAPI_ausf_info_t *ausf_info_local_var = OpenAPI_malloc(sizeof(OpenAPI_ausf_info_t));
|
||||
if (!ausf_info_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
ausf_info_local_var->group_id = group_id;
|
||||
ausf_info_local_var->supi_ranges = supi_ranges;
|
||||
ausf_info_local_var->routing_indicators = routing_indicators;
|
||||
|
||||
return ausf_info_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_ausf_info_free(OpenAPI_ausf_info_t *ausf_info)
|
||||
{
|
||||
if (NULL == ausf_info) {
|
||||
return;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
ogs_free(ausf_info->group_id);
|
||||
OpenAPI_list_for_each(ausf_info->supi_ranges, node) {
|
||||
OpenAPI_supi_range_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(ausf_info->supi_ranges);
|
||||
OpenAPI_list_for_each(ausf_info->routing_indicators, node) {
|
||||
ogs_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(ausf_info->routing_indicators);
|
||||
ogs_free(ausf_info);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_ausf_info_convertToJSON(OpenAPI_ausf_info_t *ausf_info)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if (ausf_info == NULL) {
|
||||
ogs_error("OpenAPI_ausf_info_convertToJSON() failed [AusfInfo]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
if (ausf_info->group_id) {
|
||||
if (cJSON_AddStringToObject(item, "groupId", ausf_info->group_id) == NULL) {
|
||||
ogs_error("OpenAPI_ausf_info_convertToJSON() failed [group_id]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (ausf_info->supi_ranges) {
|
||||
cJSON *supi_rangesList = cJSON_AddArrayToObject(item, "supiRanges");
|
||||
if (supi_rangesList == NULL) {
|
||||
ogs_error("OpenAPI_ausf_info_convertToJSON() failed [supi_ranges]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *supi_ranges_node;
|
||||
if (ausf_info->supi_ranges) {
|
||||
OpenAPI_list_for_each(ausf_info->supi_ranges, supi_ranges_node) {
|
||||
cJSON *itemLocal = OpenAPI_supi_range_convertToJSON(supi_ranges_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_ausf_info_convertToJSON() failed [supi_ranges]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(supi_rangesList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ausf_info->routing_indicators) {
|
||||
cJSON *routing_indicators = cJSON_AddArrayToObject(item, "routingIndicators");
|
||||
if (routing_indicators == NULL) {
|
||||
ogs_error("OpenAPI_ausf_info_convertToJSON() failed [routing_indicators]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *routing_indicators_node;
|
||||
OpenAPI_list_for_each(ausf_info->routing_indicators, routing_indicators_node) {
|
||||
if (cJSON_AddStringToObject(routing_indicators, "", (char*)routing_indicators_node->data) == NULL) {
|
||||
ogs_error("OpenAPI_ausf_info_convertToJSON() failed [routing_indicators]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_ausf_info_t *OpenAPI_ausf_info_parseFromJSON(cJSON *ausf_infoJSON)
|
||||
{
|
||||
OpenAPI_ausf_info_t *ausf_info_local_var = NULL;
|
||||
cJSON *group_id = cJSON_GetObjectItemCaseSensitive(ausf_infoJSON, "groupId");
|
||||
|
||||
if (group_id) {
|
||||
if (!cJSON_IsString(group_id)) {
|
||||
ogs_error("OpenAPI_ausf_info_parseFromJSON() failed [group_id]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *supi_ranges = cJSON_GetObjectItemCaseSensitive(ausf_infoJSON, "supiRanges");
|
||||
|
||||
OpenAPI_list_t *supi_rangesList;
|
||||
if (supi_ranges) {
|
||||
cJSON *supi_ranges_local_nonprimitive;
|
||||
if (!cJSON_IsArray(supi_ranges)) {
|
||||
ogs_error("OpenAPI_ausf_info_parseFromJSON() failed [supi_ranges]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
supi_rangesList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(supi_ranges_local_nonprimitive, supi_ranges ) {
|
||||
if (!cJSON_IsObject(supi_ranges_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_ausf_info_parseFromJSON() failed [supi_ranges]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_supi_range_t *supi_rangesItem = OpenAPI_supi_range_parseFromJSON(supi_ranges_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(supi_rangesList, supi_rangesItem);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *routing_indicators = cJSON_GetObjectItemCaseSensitive(ausf_infoJSON, "routingIndicators");
|
||||
|
||||
OpenAPI_list_t *routing_indicatorsList;
|
||||
if (routing_indicators) {
|
||||
cJSON *routing_indicators_local;
|
||||
if (!cJSON_IsArray(routing_indicators)) {
|
||||
ogs_error("OpenAPI_ausf_info_parseFromJSON() failed [routing_indicators]");
|
||||
goto end;
|
||||
}
|
||||
routing_indicatorsList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(routing_indicators_local, routing_indicators) {
|
||||
if (!cJSON_IsString(routing_indicators_local)) {
|
||||
ogs_error("OpenAPI_ausf_info_parseFromJSON() failed [routing_indicators]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_list_add(routing_indicatorsList, ogs_strdup(routing_indicators_local->valuestring));
|
||||
}
|
||||
}
|
||||
|
||||
ausf_info_local_var = OpenAPI_ausf_info_create (
|
||||
group_id ? ogs_strdup(group_id->valuestring) : NULL,
|
||||
supi_ranges ? supi_rangesList : NULL,
|
||||
routing_indicators ? routing_indicatorsList : NULL
|
||||
);
|
||||
|
||||
return ausf_info_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* ausf_info.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _OpenAPI_ausf_info_H_
|
||||
#define _OpenAPI_ausf_info_H_
|
||||
|
||||
#include <string.h>
|
||||
#include "../external/cJSON.h"
|
||||
#include "../include/list.h"
|
||||
#include "../include/keyValuePair.h"
|
||||
#include "../include/binary.h"
|
||||
#include "supi_range.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OpenAPI_ausf_info_s OpenAPI_ausf_info_t;
|
||||
typedef struct OpenAPI_ausf_info_s {
|
||||
char *group_id;
|
||||
OpenAPI_list_t *supi_ranges;
|
||||
OpenAPI_list_t *routing_indicators;
|
||||
} OpenAPI_ausf_info_t;
|
||||
|
||||
OpenAPI_ausf_info_t *OpenAPI_ausf_info_create(
|
||||
char *group_id,
|
||||
OpenAPI_list_t *supi_ranges,
|
||||
OpenAPI_list_t *routing_indicators
|
||||
);
|
||||
void OpenAPI_ausf_info_free(OpenAPI_ausf_info_t *ausf_info);
|
||||
OpenAPI_ausf_info_t *OpenAPI_ausf_info_parseFromJSON(cJSON *ausf_infoJSON);
|
||||
cJSON *OpenAPI_ausf_info_convertToJSON(OpenAPI_ausf_info_t *ausf_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OpenAPI_ausf_info_H_ */
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "bsf_info.h"
|
||||
|
||||
OpenAPI_bsf_info_t *OpenAPI_bsf_info_create(
|
||||
OpenAPI_list_t *dnn_list,
|
||||
OpenAPI_list_t *ip_domain_list,
|
||||
OpenAPI_list_t *ipv4_address_ranges,
|
||||
OpenAPI_list_t *ipv6_prefix_ranges
|
||||
)
|
||||
{
|
||||
OpenAPI_bsf_info_t *bsf_info_local_var = OpenAPI_malloc(sizeof(OpenAPI_bsf_info_t));
|
||||
if (!bsf_info_local_var) {
|
||||
return NULL;
|
||||
}
|
||||
bsf_info_local_var->dnn_list = dnn_list;
|
||||
bsf_info_local_var->ip_domain_list = ip_domain_list;
|
||||
bsf_info_local_var->ipv4_address_ranges = ipv4_address_ranges;
|
||||
bsf_info_local_var->ipv6_prefix_ranges = ipv6_prefix_ranges;
|
||||
|
||||
return bsf_info_local_var;
|
||||
}
|
||||
|
||||
void OpenAPI_bsf_info_free(OpenAPI_bsf_info_t *bsf_info)
|
||||
{
|
||||
if (NULL == bsf_info) {
|
||||
return;
|
||||
}
|
||||
OpenAPI_lnode_t *node;
|
||||
OpenAPI_list_for_each(bsf_info->dnn_list, node) {
|
||||
ogs_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(bsf_info->dnn_list);
|
||||
OpenAPI_list_for_each(bsf_info->ip_domain_list, node) {
|
||||
ogs_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(bsf_info->ip_domain_list);
|
||||
OpenAPI_list_for_each(bsf_info->ipv4_address_ranges, node) {
|
||||
OpenAPI_ipv4_address_range_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(bsf_info->ipv4_address_ranges);
|
||||
OpenAPI_list_for_each(bsf_info->ipv6_prefix_ranges, node) {
|
||||
OpenAPI_ipv6_prefix_range_free(node->data);
|
||||
}
|
||||
OpenAPI_list_free(bsf_info->ipv6_prefix_ranges);
|
||||
ogs_free(bsf_info);
|
||||
}
|
||||
|
||||
cJSON *OpenAPI_bsf_info_convertToJSON(OpenAPI_bsf_info_t *bsf_info)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
|
||||
if (bsf_info == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [BsfInfo]");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = cJSON_CreateObject();
|
||||
if (bsf_info->dnn_list) {
|
||||
cJSON *dnn_list = cJSON_AddArrayToObject(item, "dnnList");
|
||||
if (dnn_list == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [dnn_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *dnn_list_node;
|
||||
OpenAPI_list_for_each(bsf_info->dnn_list, dnn_list_node) {
|
||||
if (cJSON_AddStringToObject(dnn_list, "", (char*)dnn_list_node->data) == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [dnn_list]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bsf_info->ip_domain_list) {
|
||||
cJSON *ip_domain_list = cJSON_AddArrayToObject(item, "ipDomainList");
|
||||
if (ip_domain_list == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [ip_domain_list]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *ip_domain_list_node;
|
||||
OpenAPI_list_for_each(bsf_info->ip_domain_list, ip_domain_list_node) {
|
||||
if (cJSON_AddStringToObject(ip_domain_list, "", (char*)ip_domain_list_node->data) == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [ip_domain_list]");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bsf_info->ipv4_address_ranges) {
|
||||
cJSON *ipv4_address_rangesList = cJSON_AddArrayToObject(item, "ipv4AddressRanges");
|
||||
if (ipv4_address_rangesList == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [ipv4_address_ranges]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *ipv4_address_ranges_node;
|
||||
if (bsf_info->ipv4_address_ranges) {
|
||||
OpenAPI_list_for_each(bsf_info->ipv4_address_ranges, ipv4_address_ranges_node) {
|
||||
cJSON *itemLocal = OpenAPI_ipv4_address_range_convertToJSON(ipv4_address_ranges_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [ipv4_address_ranges]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(ipv4_address_rangesList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bsf_info->ipv6_prefix_ranges) {
|
||||
cJSON *ipv6_prefix_rangesList = cJSON_AddArrayToObject(item, "ipv6PrefixRanges");
|
||||
if (ipv6_prefix_rangesList == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [ipv6_prefix_ranges]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
OpenAPI_lnode_t *ipv6_prefix_ranges_node;
|
||||
if (bsf_info->ipv6_prefix_ranges) {
|
||||
OpenAPI_list_for_each(bsf_info->ipv6_prefix_ranges, ipv6_prefix_ranges_node) {
|
||||
cJSON *itemLocal = OpenAPI_ipv6_prefix_range_convertToJSON(ipv6_prefix_ranges_node->data);
|
||||
if (itemLocal == NULL) {
|
||||
ogs_error("OpenAPI_bsf_info_convertToJSON() failed [ipv6_prefix_ranges]");
|
||||
goto end;
|
||||
}
|
||||
cJSON_AddItemToArray(ipv6_prefix_rangesList, itemLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return item;
|
||||
}
|
||||
|
||||
OpenAPI_bsf_info_t *OpenAPI_bsf_info_parseFromJSON(cJSON *bsf_infoJSON)
|
||||
{
|
||||
OpenAPI_bsf_info_t *bsf_info_local_var = NULL;
|
||||
cJSON *dnn_list = cJSON_GetObjectItemCaseSensitive(bsf_infoJSON, "dnnList");
|
||||
|
||||
OpenAPI_list_t *dnn_listList;
|
||||
if (dnn_list) {
|
||||
cJSON *dnn_list_local;
|
||||
if (!cJSON_IsArray(dnn_list)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [dnn_list]");
|
||||
goto end;
|
||||
}
|
||||
dnn_listList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(dnn_list_local, dnn_list) {
|
||||
if (!cJSON_IsString(dnn_list_local)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [dnn_list]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_list_add(dnn_listList, ogs_strdup(dnn_list_local->valuestring));
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *ip_domain_list = cJSON_GetObjectItemCaseSensitive(bsf_infoJSON, "ipDomainList");
|
||||
|
||||
OpenAPI_list_t *ip_domain_listList;
|
||||
if (ip_domain_list) {
|
||||
cJSON *ip_domain_list_local;
|
||||
if (!cJSON_IsArray(ip_domain_list)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [ip_domain_list]");
|
||||
goto end;
|
||||
}
|
||||
ip_domain_listList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(ip_domain_list_local, ip_domain_list) {
|
||||
if (!cJSON_IsString(ip_domain_list_local)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [ip_domain_list]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_list_add(ip_domain_listList, ogs_strdup(ip_domain_list_local->valuestring));
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *ipv4_address_ranges = cJSON_GetObjectItemCaseSensitive(bsf_infoJSON, "ipv4AddressRanges");
|
||||
|
||||
OpenAPI_list_t *ipv4_address_rangesList;
|
||||
if (ipv4_address_ranges) {
|
||||
cJSON *ipv4_address_ranges_local_nonprimitive;
|
||||
if (!cJSON_IsArray(ipv4_address_ranges)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [ipv4_address_ranges]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ipv4_address_rangesList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(ipv4_address_ranges_local_nonprimitive, ipv4_address_ranges ) {
|
||||
if (!cJSON_IsObject(ipv4_address_ranges_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [ipv4_address_ranges]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_ipv4_address_range_t *ipv4_address_rangesItem = OpenAPI_ipv4_address_range_parseFromJSON(ipv4_address_ranges_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(ipv4_address_rangesList, ipv4_address_rangesItem);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *ipv6_prefix_ranges = cJSON_GetObjectItemCaseSensitive(bsf_infoJSON, "ipv6PrefixRanges");
|
||||
|
||||
OpenAPI_list_t *ipv6_prefix_rangesList;
|
||||
if (ipv6_prefix_ranges) {
|
||||
cJSON *ipv6_prefix_ranges_local_nonprimitive;
|
||||
if (!cJSON_IsArray(ipv6_prefix_ranges)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [ipv6_prefix_ranges]");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ipv6_prefix_rangesList = OpenAPI_list_create();
|
||||
|
||||
cJSON_ArrayForEach(ipv6_prefix_ranges_local_nonprimitive, ipv6_prefix_ranges ) {
|
||||
if (!cJSON_IsObject(ipv6_prefix_ranges_local_nonprimitive)) {
|
||||
ogs_error("OpenAPI_bsf_info_parseFromJSON() failed [ipv6_prefix_ranges]");
|
||||
goto end;
|
||||
}
|
||||
OpenAPI_ipv6_prefix_range_t *ipv6_prefix_rangesItem = OpenAPI_ipv6_prefix_range_parseFromJSON(ipv6_prefix_ranges_local_nonprimitive);
|
||||
|
||||
OpenAPI_list_add(ipv6_prefix_rangesList, ipv6_prefix_rangesItem);
|
||||
}
|
||||
}
|
||||
|
||||
bsf_info_local_var = OpenAPI_bsf_info_create (
|
||||
dnn_list ? dnn_listList : NULL,
|
||||
ip_domain_list ? ip_domain_listList : NULL,
|
||||
ipv4_address_ranges ? ipv4_address_rangesList : NULL,
|
||||
ipv6_prefix_ranges ? ipv6_prefix_rangesList : NULL
|
||||
);
|
||||
|
||||
return bsf_info_local_var;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue