Commit ae339231 authored by Rohan's avatar Rohan

Yaml config support and pfcp module synch with smf

parent 8da4870b
...@@ -31,54 +31,8 @@ SCRIPT=$(readlink -f ${BASH_SOURCE}) ...@@ -31,54 +31,8 @@ SCRIPT=$(readlink -f ${BASH_SOURCE})
THIS_SCRIPT_PATH=`dirname $SCRIPT` THIS_SCRIPT_PATH=`dirname $SCRIPT`
source $THIS_SCRIPT_PATH/build_helper source $THIS_SCRIPT_PATH/build_helper
source $THIS_SCRIPT_PATH/build_helper.fb_folly source $THIS_SCRIPT_PATH/build_helper.fb_folly
source $THIS_SCRIPT_PATH/../common-build/installation/build_helper.yamlcpp
#------------------------------------------------------------------------------- source $THIS_SCRIPT_PATH/../common-build/installation/build_helper.nlohmann
#arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries)
install_libyaml_cpp_from_git() {
# For Ubuntu 2x and RHEL we should install from repo.
echo "Starting to install libyaml_cpp"
if [ $1 -eq 0 ]; then
read -p "Do you want to install yaml_cpp ? <y/N> " prompt
OPTION=""
else
prompt='y'
OPTION="-y"
fi
if [ $2 -eq 0 ]; then
debug=0
else
debug=1
fi
if [[ $prompt =~ [yY](es)* ]]
then
GIT_URL=https://github.com/jbeder/yaml-cpp.git
echo "Install yaml-cpp from $GIT_URL"
pushd $OPENAIRCN_DIR/build/ext
echo "Downloading yaml-cpp"
if [[ $OPTION =~ -[yY](es)* ]]
then
$SUDO rm -rf yaml-cpp
fi
git clone $GIT_URL
cd yaml-cpp && git checkout master
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
mkdir _build && cd _build
$CMAKE -G "Unix Makefiles" -DYAML_BUILD_SHARED_LIBS=on -DYAML_CPP_BUILD_TESTS=off ..
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
make
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO make install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
popd
rm -Rf $OPENAIRCN_DIR/build/ext/yaml-cpp/_build
fi
echo "yaml-cpp installation complete"
return 0
}
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
install_libbpf_from_git() { install_libbpf_from_git() {
...@@ -287,55 +241,6 @@ install_fmt_from_git() { ...@@ -287,55 +241,6 @@ install_fmt_from_git() {
return 0 return 0
} }
#-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries)
install_nlohmann_from_git() {
echo_info "Starting to install Nlohmann Json"
if [ $1 -eq 0 ]; then
read -p "Do you want to install Nlohmann Json ? <y/N> " prompt
OPTION=""
else
prompt='y'
OPTION="-y"
fi
if [ $2 -eq 0 ]; then
debug=0
else
debug=1
fi
if [[ $prompt =~ [yY](es)* ]]
then
GIT_URL=https://github.com/nlohmann/json.git
echo "Install Nlohmann Json from $GIT_URL"
pushd $OPENAIRCN_DIR/build/ext
echo "Downloading Nlohmann"
if [[ $OPTION =~ -[yY](es)* ]]
then
$SUDO rm -rf json
fi
git clone $GIT_URL
cd json && git checkout -f v3.10.3
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
mkdir _build && cd _build
$CMAKE -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=OFF ..
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
make -j $(nproc)
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO make install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
popd
rm -Rf $OPENAIRCN_DIR/build/ext/json/_build
fi
echo_success "Nlohmann Json installation complete"
return 0
}
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script) #arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries) #arg2 is debug (0 or 1) (install debug libraries)
...@@ -461,13 +366,35 @@ check_install_upf_deps() { ...@@ -461,13 +366,35 @@ check_install_upf_deps() {
install_fmt_from_git $1 $2 install_fmt_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret ret=$?;[[ $ret -ne 0 ]] && return $ret
install_spdlog_from_git $1 $2 install_spdlog_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret ret=$?;[[ $ret -ne 0 ]] && return $ret
install_nlohmann_from_git $1 $2 install_nlohmann_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret ret=$?;[[ $ret -ne 0 ]] && return $ret
# latest usage of yaml-cpp suggests that we should be using 0.7+ version
# To be sure, let's install from source all the time for the moment
if [[ $OS_DISTRO == "ubuntu" ]]; then
case "$(get_distribution_release)" in
"ubuntu20.04")
# definitely, 0.6.2 as PPA installed is not enough
install_libyaml_cpp_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
;;
"ubuntu22.04")
# not sure about 0.7.0
#$SUDO $INSTALLER install $OPTION libyaml-cpp0.7 libyaml-cpp-dev
install_libyaml_cpp_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
;;
esac
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
# definitely, 0.6.2 as PPA installed is not enough
# $SUDO $INSTALLER install $OPTION yaml-cpp yaml-cpp-devel
install_libyaml_cpp_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
fi
if [[ $OS_DISTRO == "ubuntu" ]]; then if [[ $OS_DISTRO == "ubuntu" ]]; then
case "$(get_distribution_release)" in case "$(get_distribution_release)" in
"ubuntu20.04") "ubuntu20.04")
......
...@@ -49,6 +49,7 @@ RUN git config --global https.postBuffer 123289600 && \ ...@@ -49,6 +49,7 @@ RUN git config --global https.postBuffer 123289600 && \
# Copy installation scripts # Copy installation scripts
WORKDIR /oai-upf WORKDIR /oai-upf
COPY ./build/scripts /oai-upf/build/scripts/ COPY ./build/scripts /oai-upf/build/scripts/
COPY ./build/common-build /oai-upf/build/common-build
COPY ./build/upf/CMakeLists.txt /oai-upf/build/upf/CMakeLists.txt COPY ./build/upf/CMakeLists.txt /oai-upf/build/upf/CMakeLists.txt
COPY ./build/cmake_modules /oai-upf/cmake_modules/ COPY ./build/cmake_modules /oai-upf/cmake_modules/
...@@ -121,6 +122,7 @@ COPY --from=oai-upf-builder \ ...@@ -121,6 +122,7 @@ COPY --from=oai-upf-builder \
# Once Ubuntu18 support is dropped, we can remove whole copy section # Once Ubuntu18 support is dropped, we can remove whole copy section
/usr/lib/x86_64-linux-gnu/libpsl.so.5 \ /usr/lib/x86_64-linux-gnu/libpsl.so.5 \
/usr/local/lib/libfmt.so \ /usr/local/lib/libfmt.so \
/usr/lib/x86_64-linux-gnu/libyaml-cpp.so.0.? \
/usr/lib/x86_64-linux-gnu/libasan.so.5 \ /usr/lib/x86_64-linux-gnu/libasan.so.5 \
# Ubuntu 18 --> boost 67 will be copied # Ubuntu 18 --> boost 67 will be copied
/usr/lib/libboost_system.so.1.6*.0 \ /usr/lib/libboost_system.so.1.6*.0 \
......
...@@ -22,74 +22,209 @@ ...@@ -22,74 +22,209 @@
# OAI CN Configuration File # OAI CN Configuration File
### This file can be used by all OAI NFs ### This file can be used by all OAI NFs
### Some fields are specific to an NF and will be ignored by other NFs ### Some fields are specific to an NF and will be ignored by other NFs
### The {{ env['ENV_NAME'] }} syntax lets you define these values in a docker-compose file
### If you intend to mount this file or use a bare-metal deployment, please refer to README.md
### The README.md also defines default values and allowed values for each configuration parameter
############# Common configuration ############# Common configuration
# Log level for all the NFs # Log level for all the NFs
log_level: log_level:
upf: debug general: debug
# If "on": Register to NRF, DEFAULT= off # If you enable registration, the other NFs will use the NRF discovery mechanism
register_nf: register_nf:
upf: yes general: yes
http_version: 1.1 http_version: 2
############## SBI Interfaces ############## SBI Interfaces
### Each NF takes its local SBI interfaces and remote interfaces from here, unless it gets them using NRF discovery mechanisms ### Each NF takes its local SBI interfaces and remote interfaces from here, unless it gets them using NRF discovery mechanisms
nfs: nfs:
amf:
host: oai-amf
sbi:
port: 8080
api_version: v1
interface_name: eth0
n2:
interface_name: eth0
port: 38412
smf: smf:
host: oai-smf host: oai-smf
n4:
interface_name: eth0
port: 8805
nrf:
host: oai-nrf
sbi: sbi:
port: 80 port: 8080
api_version: v1 api_version: v1
interface_name: eth0 interface_name: eth0
n4:
interface_name: eth0
port: 8805
upf: upf:
host: oai-upf host: oai-upf
sbi: sbi:
port_http1: 80 port_http1: 80
api_version: v1 api_version: v1
interface_name: eth0 interface_name: demo-oai
n3: n3:
interface_name: eth0 interface_name: demo-oai
port: 2152 port: 2152
n4: n4:
interface_name: eth0 interface_name: demo-oai
port: 8805 port: 8805
n6: n6:
interface_name: eth0 interface_name: demo-oai
n9: n9:
interface_name: eth0 interface_name: demo-oai
port: 2152 port: 2152
udm:
host: oai-udm
sbi:
port: 8080
api_version: v1
interface_name: eth0
udr:
host: oai-udr
sbi:
port: 8080
api_version: v1
interface_name: eth0
ausf:
host: oai-ausf
sbi:
port: 8080
api_version: v1
interface_name: eth0
nrf:
host: oai-nrf
sbi:
port: 8080
api_version: v1
interface_name: eth0
#### Common for UDR and AMF
database:
host: mysql
user: test
type: mysql
password: test
database_name: oai_db
generate_random: true
connection_timeout: 300 # seconds
############## NF-specific configuration
amf:
pid_directory: "/var/run"
amf_name: "OAI-AMF"
# This really depends on if we want to keep the "mini" version or not
support_features_options:
enable_simple_scenario: no
enable_nssf: no
enable_smf_selection: yes
use_external_udm: no
relative_capacity: 30
statistics_timer_interval: 20 #in seconds
emergency_support: false
served_guami_list:
- mcc: 208
mnc: 95
amf_region_id: 128
amf_set_id: 1
amf_pointer: 1
- mcc: 460
mnc: 11
amf_region_id: 10
amf_set_id: 1
amf_pointer: 1
plmn_support_list:
- mcc: 208
mnc: 95
tac: 0xa000
nssai:
- sst: 1
- sst: 1
sd: 1
- sst: 222
sd: 123
supported_integrity_algorithms:
- "NIA0"
- "NIA1"
- "NIA2"
supported_encryption_algorithms:
- "NEA0"
- "NEA1"
- "NEA2"
smf:
ue_mtu: 1500
support_features:
use_local_subscription_info: yes # Use infos from local_subscription_info or from UDM
use_local_pcc_rules: yes # Use infos from local_pcc_rules or from PCF
# we resolve from NRF, this is just to configure usage_reporting
upfs:
- host: oai-spgwu
config:
enable_usage_reporting: no
ue_dns:
primary_ipv4: "172.21.3.100"
primary_ipv6: "2001:4860:4860::8888"
secondary_ipv4: "8.8.8.8"
secondary_ipv6: "2001:4860:4860::8888"
ims:
pcscf_ipv4: "127.0.0.1"
pcscf_ipv6: "fe80::7915:f408:1787:db8b"
# the DNN you configure here should be configured in "dnns"
local_subscription_infos:
- single_nssai:
sst: 1
dnn: "oai"
qos_profile:
5qi: 9
session_ambr_ul: "200Mbps"
session_ambr_dl: "400Mbps"
- single_nssai:
sst: 1
sd: 1
dnn: "oai.ipv4"
qos_profile:
5qi: 9
session_ambr_ul: "100Mbps"
session_ambr_dl: "200Mbps"
- single_nssai:
sst: 222
sd: 123
dnn: "oai.ipv4"
qos_profile:
5qi: 9
session_ambr_ul: "50Mbps"
session_ambr_dl: "100Mbps"
##### Options to enable/disable #####
upf: upf:
support_features: support_features:
enable_bpf_datapath: no # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off enable_bpf_datapath: no # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off
enable_snat: yes # If "on": Source natting is done for UE, DEFAULT= off enable_snat: yes # If "on": Source natting is done for UE, DEFAULT= off
enable_usage_reporting: no # If "on": Enable usage monitoring and reposrting with default URR, DEFAULT= off remote_n6_gw: oai-ext-dn
sNssaiList: upf_info:
- sNssai: - sst: 1
- sst: 1 sd: 123
sd: 0xFFFFFF dnnList:
dnnList: - dnn: oai
- dnn: oai - dnn: default
- sst: 1 - sst: 1
sd: 1 sd: 0xFFFFFF
dnnList: dnnList:
- dnn: oai.ipv4 - dnn: oai.ipv4
## DNN configuration
dnns: dnns:
- dnn: "oai" - dnn: "oai"
pdu_session_type: "IPv4" pdu_session_type: "IPV4"
ipv4_pool: "12.1.1.151 - 12.1.1.253" ipv4_subnet: "12.1.1.0/24"
ipv6_prefix: "2001:1:2::/64"
- dnn: "oai.ipv4" - dnn: "oai.ipv4"
pdu_session_type: "IPv4" pdu_session_type: "IPV4"
ipv4_pool: "12.1.1.51 - 12.1.1.150" ipv4_subnet: "12.1.2.0/24"
ipv6_prefix: "2001:1:2::/64" - dnn: "default"
\ No newline at end of file pdu_session_type: "IPV4"
ipv4_subnet: "12.1.3.0/24"
- dnn: "ims"
pdu_session_type: "IPV4V6"
ipv4_subnet: "12.1.4.0/24"
...@@ -143,6 +143,7 @@ UPF = ...@@ -143,6 +143,7 @@ UPF =
USE_FQDN_NRF = "{{ env["USE_FQDN_NRF"] if "USE_FQDN_NRF" in env.keys() else 'no' }}"; USE_FQDN_NRF = "{{ env["USE_FQDN_NRF"] if "USE_FQDN_NRF" in env.keys() else 'no' }}";
# Set FQDN of UPF # Set FQDN of UPF
UPF_FQDN_5G = "{{ env["UPF_FQDN_5G"] if "UPF_FQDN_5G" in env.keys() else 'localhost' }}"; UPF_FQDN_5G = "{{ env["UPF_FQDN_5G"] if "UPF_FQDN_5G" in env.keys() else 'localhost' }}";
REMOTE_N6_GW = "{{ env["REMOTE_N6_GW"] if "REMOTE_N6_GW" in env.keys() else 'oai-ext-dn' }}";
{%- else %} {%- else %}
ENABLE_5G_FEATURES = "no" # Set to 'yes' to support 5G Features ENABLE_5G_FEATURES = "no" # Set to 'yes' to support 5G Features
REGISTER_NRF = "no"; # Set to 'yes' if UPF registers to an NRF REGISTER_NRF = "no"; # Set to 'yes' if UPF registers to an NRF
...@@ -173,7 +174,7 @@ UPF = ...@@ -173,7 +174,7 @@ UPF =
{%- if env["NSSAI_SST_0"] is defined %} {%- if env["NSSAI_SST_0"] is defined %}
{ {
NSSAI_SST = {{ env["NSSAI_SST_0"] }}; NSSAI_SST = {{ env["NSSAI_SST_0"] }};
NSSAI_SD = "{{ env["NSSAI_SD_0"] if "NSSAI_SD_0" in env.keys() else '0xFFFFFF' }}"; NSSAI_SD = {{ env["NSSAI_SD_0"] if "NSSAI_SD_0" in env.keys() else '0xFFFFFF' }};
DNN_LIST = ( DNN_LIST = (
{ {
DNN = "{{ env["DNN_0"] if "DNN_0" in env.keys() else 'oai' }}"; DNN = "{{ env["DNN_0"] if "DNN_0" in env.keys() else 'oai' }}";
...@@ -183,7 +184,7 @@ UPF = ...@@ -183,7 +184,7 @@ UPF =
{%- if env["NSSAI_SST_1"] is defined %} {%- if env["NSSAI_SST_1"] is defined %}
,{ ,{
NSSAI_SST = {{ env["NSSAI_SST_1"] }}; NSSAI_SST = {{ env["NSSAI_SST_1"] }};
NSSAI_SD = "{{ env["NSSAI_SD_1"] if "NSSAI_SD_1" in env.keys() else '0xFFFFFF' }}"; NSSAI_SD = {{ env["NSSAI_SD_1"] if "NSSAI_SD_1" in env.keys() else '0xFFFFFF' }};
DNN_LIST = ( DNN_LIST = (
{ {
DNN = "{{ env["DNN_1"] }}"; DNN = "{{ env["DNN_1"] }}";
...@@ -194,7 +195,7 @@ UPF = ...@@ -194,7 +195,7 @@ UPF =
{%- if env["NSSAI_SST_2"] is defined %} {%- if env["NSSAI_SST_2"] is defined %}
,{ ,{
NSSAI_SST = {{ env["NSSAI_SST_2"] }}; NSSAI_SST = {{ env["NSSAI_SST_2"] }};
NSSAI_SD = "{{ env["NSSAI_SD_2"] if "NSSAI_SD_2" in env.keys() else '0xFFFFFF' }}"; NSSAI_SD = {{ env["NSSAI_SD_2"] if "NSSAI_SD_2" in env.keys() else '0xFFFFFF' }};
DNN_LIST = ( DNN_LIST = (
{ {
DNN = "{{ env["DNN_2"] }}"; DNN = "{{ env["DNN_2"] }}";
...@@ -205,7 +206,7 @@ UPF = ...@@ -205,7 +206,7 @@ UPF =
{%- if env["NSSAI_SST_3"] is defined %} {%- if env["NSSAI_SST_3"] is defined %}
,{ ,{
NSSAI_SST = {{ env["NSSAI_SST_3"] }}; NSSAI_SST = {{ env["NSSAI_SST_3"] }};
NSSAI_SD = "{{ env["NSSAI_SD_3"] if "NSSAI_SD_3" in env.keys() else '0xFFFFFF' }}"; NSSAI_SD = {{ env["NSSAI_SD_3"] if "NSSAI_SD_3" in env.keys() else '0xFFFFFF' }};
DNN_LIST = ( DNN_LIST = (
{ {
DNN = "{{ env["DNN_3"] }}"; DNN = "{{ env["DNN_3"] }}";
...@@ -214,7 +215,7 @@ UPF = ...@@ -214,7 +215,7 @@ UPF =
} }
{%- endif %} {%- endif %}
{%- else %} {%- else %}
{ NSSAI_SST = 1; NSSAI_SD = "0xFFFFFF"; DNN_LIST = ({DNN = "oai";}); } { NSSAI_SST = 1; NSSAI_SD = 0xFFFFFF; DNN_LIST = ({DNN = "oai";}); }
{%- endif %} {%- endif %}
); );
} }
......
common-src @ 139a12ea
Subproject commit 8484dae08c16fd07140b6d7a9a349132fc53c3c8 Subproject commit 139a12ea786f1fed1f48577eb64b86e4c8049656
...@@ -20,15 +20,101 @@ ...@@ -20,15 +20,101 @@
*/ */
/*! \file 3gpp_23.003.h /*! \file 3gpp_23.003.h
\brief \brief
\author Lionel Gauthier \author Lionel Gauthier
\company Eurecom \company Eurecom
\email: lionel.gauthier@eurecom.fr \email: lionel.gauthier@eurecom.fr
*/ */
#ifndef FILE_3GPP_23_003_SEEN #ifndef FILE_3GPP_23_003_SEEN
#define FILE_3GPP_23_003_SEEN #define FILE_3GPP_23_003_SEEN
#define SST_MAX_STANDARDIZED_VALUE 127 #include <stdint.h>
#define SD_NO_VALUE 0xFFFFFF
typedef struct plmn_s {
uint8_t mcc_digit2 : 4;
uint8_t mcc_digit1 : 4;
uint8_t mcc_digit3 : 4;
uint8_t mnc_digit3 : 4;
uint8_t mnc_digit2 : 4;
uint8_t mnc_digit1 : 4;
} plmn_t;
#define INVALID_TAC_0000 (uint16_t) 0x0000
#define INVALID_TAC_FFFE (uint16_t) 0xFFFE
#define INVALID_TAC (uint32_t) 0x00000000
#define INVALID_TMSI \
UINT32_MAX /*!< \brief The network shall not allocate a TMSI with all 32 \
bits equal to 1 (this is because the TMSI must be stored in \
the SIM, and the SIM uses 4 octets with all bits \
equal to 1 to indicate that no valid TMSI is \
available). */
typedef uint16_t tac_t;
typedef struct tai_s {
plmn_t plmn; /*!< \brief <MCC> + <MNC> */
tac_t tac; /*!< \brief Tracking Area Code */
} tai_t;
typedef struct eci_s {
uint32_t gnb_id : 20;
uint32_t cell_id : 8;
uint32_t empty : 4;
} ci_t;
typedef struct cgi_s {
plmn_t plmn;
ci_t cell_identity; // 28 bits
} cgi_t;
typedef struct nr_tai_s /*5G ADD it*/
{
plmn_t plmn;
uint32_t tac : 24;
} nr_tai_t;
typedef struct nr_cell_identity_s /*5G ADD it */
{
uint32_t gnb_id;
uint8_t cell_id : 4;
} nr_cell_identity_t;
typedef struct nr_cgi_s /*5G ADD it */
{
plmn_t plmn;
nr_cell_identity_t cell_identity;
} nr_cgi_t;
typedef struct fiveG_s_tmsi_s /*5G ADD it */
{
uint16_t amf_set_id : 10;
uint8_t amf_pointer : 6;
uint32_t fiveG_s_tmsi; // 32
} fiveG_s_tmsi_t;
typedef struct fiveG_s_gua_s /*5G ADD it */
{
plmn_t plmn;
uint8_t region_id;
uint16_t amf_set_id : 10;
uint8_t amf_pointer : 6;
} fiveG_s_gua_t;
typedef struct amf_set_id_s /*5G ADD it*/
{
uint16_t amf_set_id : 10;
} amf_set_id_t;
typedef struct allowed_nssai /*5G ADD it*/
{
uint8_t sST;
uint32_t sD : 24;
} allowed_nssai;
typedef struct allowed_nssai_s /*5G ADD it*/
{
allowed_nssai* s_nssai;
uint32_t count;
} allowed_nssai_t;
#endif /* FILE_3GPP_23_003_SEEN */ #endif
This diff is collapsed.
This diff is collapsed.
...@@ -24,27 +24,71 @@ ...@@ -24,27 +24,71 @@
#include <vector> #include <vector>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <boost/algorithm/string.hpp>
#include <map>
#include <unordered_set>
const uint32_t SD_NO_VALUE = 0xFFFFFF;
const std::string SD_NO_VALUE_STR = "0xFFFFFF";
const uint8_t SST_MAX_STANDARDIZED_VALUE = 127;
// Section 28.4, TS23.003 // Section 28.4, TS23.003
typedef struct s_nssai { typedef struct s_nssai // section 28.4, TS23.003
uint8_t sST; {
std::string sD; const uint8_t HASH_SEED = 17;
s_nssai(const uint8_t& sst, const std::string sd) : sST(sst), sD(sd) {} const uint8_t HASH_FACTOR = 31;
s_nssai() : sST(), sD() {}
s_nssai(const s_nssai& p) : sST(p.sST), sD(p.sD) {} uint8_t sst;
uint32_t sd;
s_nssai(const uint8_t& m_sst, const uint32_t m_sd) : sst(m_sst), sd(m_sd) {}
s_nssai(const uint8_t& m_sst, const std::string m_sd) : sst(m_sst) {
sd = SD_NO_VALUE;
if (m_sd.empty()) return;
uint8_t base = 10;
try {
if (m_sd.size() > 2) {
if (boost::iequals(m_sd.substr(0, 2), "0x")) {
base = 16;
}
}
sd = std::stoul(m_sd, nullptr, base);
} catch (const std::exception& e) {
Logger::upf_app().error(
"Error when converting from string to int for S-NSSAI SD, error: %s",
e.what());
sd = SD_NO_VALUE;
}
}
s_nssai() : sst(), sd() {}
s_nssai(const s_nssai& p) : sst(p.sst), sd(p.sd) {}
bool operator==(const struct s_nssai& s) const { bool operator==(const struct s_nssai& s) const {
if ((s.sST == this->sST) && (s.sD.compare(this->sD) == 0)) { if ((s.sst == this->sst) && (s.sd == this->sd)) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
s_nssai& operator=(const s_nssai& s) {
sST = s.sST; s_nssai& operator=(const struct s_nssai& s) {
sD = s.sD; sst = s.sst;
sd = s.sd;
return *this; return *this;
} }
std::string toString() const {
std::string s = {};
s.append("SST=").append(std::to_string(sst));
s.append(", SD=").append(std::to_string(sd));
return s;
}
size_t operator()(const s_nssai&) const {
size_t res = HASH_SEED;
res = res * HASH_FACTOR + std::hash<uint32_t>()(sd);
res = res * HASH_FACTOR + std::hash<uint32_t>()(sst);
return res;
}
} snssai_t; } snssai_t;
typedef struct dnai_s { typedef struct dnai_s {
...@@ -52,63 +96,136 @@ typedef struct dnai_s { ...@@ -52,63 +96,136 @@ typedef struct dnai_s {
typedef struct dnn_upf_info_item_s { typedef struct dnn_upf_info_item_s {
std::string dnn; std::string dnn;
// std::vector<std::string> dnai_list std::unordered_set<std::string> dnai_list;
// supported from R16.8
std::map<std::string, std::string> dnai_nw_instance_list;
// std::vector<std::string> pdu_session_types // std::vector<std::string> pdu_session_types
dnn_upf_info_item_s& operator=(const dnn_upf_info_item_s& d) { dnn_upf_info_item_s& operator=(const dnn_upf_info_item_s& d) {
dnn = d.dnn; dnn = d.dnn;
dnai_list = d.dnai_list;
dnai_nw_instance_list = d.dnai_nw_instance_list;
return *this; return *this;
} }
bool operator==(const dnn_upf_info_item_s& s) const { return dnn == s.dnn; }
size_t operator()(const dnn_upf_info_item_s&) const {
return std::hash<std::string>()(dnn);
}
std::string to_string() const {
std::string s = {};
s.append("DNN = ").append(dnn).append(", ");
if (dnai_list.size() > 0) {
s.append("DNAI list: {");
for (const auto& dnai : dnai_list) {
s.append("DNAI = ").append(dnai).append(", ");
}
s.append("}, ");
}
if (dnai_nw_instance_list.size() > 0) {
s.append("DNAI NW Instance list: {");
for (const auto& dnai_nw : dnai_nw_instance_list) {
s.append("(")
.append(dnai_nw.first)
.append(", ")
.append(dnai_nw.second)
.append("),");
}
s.append("}, ");
}
return s;
}
} dnn_upf_info_item_t; } dnn_upf_info_item_t;
typedef struct snssai_upf_info_item_s { typedef struct snssai_upf_info_item_s {
snssai_t snssai; mutable snssai_t snssai;
std::vector<dnn_upf_info_item_t> dnn_upf_info_list; mutable std::unordered_set<dnn_upf_info_item_t, dnn_upf_info_item_t>
dnn_upf_info_list;
snssai_upf_info_item_s& operator=(const snssai_upf_info_item_s& s) { snssai_upf_info_item_s& operator=(const snssai_upf_info_item_s& s) {
dnn_upf_info_list = s.dnn_upf_info_list;
snssai = s.snssai; snssai = s.snssai;
dnn_upf_info_list = s.dnn_upf_info_list;
return *this; return *this;
} }
} snssai_upf_info_item_t;
typedef struct upf_info_s { bool operator==(const snssai_upf_info_item_s& s) const {
std::vector<snssai_upf_info_item_t> snssai_upf_info_list; return (snssai == s.snssai) and (dnn_upf_info_list == s.dnn_upf_info_list);
void add_snssai(snssai_t snssai, std::string dnn) { }
bool found_snssai = false;
dnn_upf_info_item_t dnn_item = {}; size_t operator()(const snssai_upf_info_item_s&) const {
dnn_item.dnn = dnn; return snssai.operator()(snssai);
for (int i = 0; i < snssai_upf_info_list.size(); i++) { }
if (snssai_upf_info_list[i].snssai == snssai) {
// Add DNN to the dnn_upf_info_list if not exist std::string to_string() const {
bool found_dnn = false; std::string s = {};
for (int j = 0; j < snssai_upf_info_list[i].dnn_upf_info_list.size();
j++) { s.append("{" + snssai.toString() + ", ");
if (snssai_upf_info_list[i].dnn_upf_info_list[j].dnn.compare(dnn) ==
0) { if (dnn_upf_info_list.size() > 0) {
found_dnn = true; s.append("{");
break;
} for (auto dnn_upf : dnn_upf_info_list) {
} s.append(dnn_upf.to_string());
if (!found_dnn) {
snssai_upf_info_list[i].dnn_upf_info_list.push_back(dnn_item);
}
found_snssai = true;
} }
s.append("}, ");
} }
if (!found_snssai) { return s;
snssai_upf_info_item_t snssai_item = {};
snssai_item.snssai = snssai;
snssai_item.dnn_upf_info_list.push_back(dnn_item);
snssai_upf_info_list.push_back(snssai_item);
}
} }
void add_snssai(snssai_upf_info_item_t snssai_item) {
snssai_upf_info_list.push_back(snssai_item); } snssai_upf_info_item_t;
typedef struct interface_upf_info_item_s {
std::string interface_type;
std::vector<struct in_addr> ipv4_addresses;
std::vector<struct in6_addr> ipv6_addresses;
std::string endpoint_fqdn;
std::string network_instance;
interface_upf_info_item_s& operator=(const interface_upf_info_item_s& i) {
interface_type = i.interface_type;
ipv4_addresses = i.ipv4_addresses;
ipv6_addresses = i.ipv6_addresses;
endpoint_fqdn = i.endpoint_fqdn;
network_instance = i.network_instance;
return *this;
} }
} interface_upf_info_item_t;
typedef struct upf_info_s {
std::vector<interface_upf_info_item_t> interface_upf_info_list;
std::vector<snssai_upf_info_item_t> snssai_upf_info_list;
upf_info_s& operator=(const upf_info_s& s) { upf_info_s& operator=(const upf_info_s& s) {
snssai_upf_info_list = s.snssai_upf_info_list; interface_upf_info_list = s.interface_upf_info_list;
snssai_upf_info_list = s.snssai_upf_info_list;
return *this; return *this;
} }
std::string to_string() const {
std::string s = {};
// TODO: Interface UPF Info List
if (!snssai_upf_info_list.empty()) {
s.append("S-NSSAI UPF Info: ");
for (auto sn : snssai_upf_info_list) {
s.append("{" + sn.snssai.toString() + ", ");
for (auto d : sn.dnn_upf_info_list) {
s.append("{DNN = " + d.dnn + "} ");
}
s.append("};");
}
}
return s;
}
} upf_info_t; } upf_info_t;
typedef struct patch_item_s { typedef struct patch_item_s {
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the
* License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef FILE_3GPP_29_571_SEEN
#define FILE_3GPP_29_571_SEEN
#include <nlohmann/json.hpp>
#include "3gpp_23.003.h"
typedef struct session_ambr_s {
std::string uplink;
std::string downlink;
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["uplink"] = uplink;
json_data["downlink"] = downlink;
return json_data;
}
} session_ambr_t;
enum preemtion_capability_e { NOT_PREEMPT = 1, MAY_PREEMPT = 2 };
static const std::vector<std::string> preemtion_capability_e2str = {
"Error", "NOT_PREEMPT", "MAY_PREEMPT"};
// see section 5.5.4.1@TS 29.571
typedef struct arp_5gc_s {
uint8_t priority_level; // (integer 1-15)
std::string preempt_cap;
std::string preempt_vuln; // NOT_PREEMPTABLE, PREEMPTABLE
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["priority_level"] = priority_level;
json_data["preempt_cap"] = preempt_cap;
json_data["preempt_vuln"] = preempt_vuln;
return json_data;
}
} arp_5gc_t;
// see section 5.4.4.1@TS 29.571
typedef struct subscribed_default_qos_s {
uint8_t _5qi;
arp_5gc_t arp;
uint8_t priority_level; // 1-127
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["_5qi"] = _5qi;
json_data["arp"] = arp.to_json();
json_data["priority_level"] = priority_level;
return json_data;
}
} subscribed_default_qos_t;
enum reflective_qos_attribute_e { RQOS = 1, NO_RQOS = 2 };
static const std::vector<std::string> reflective_qos_attribute_e2str = {
"ERROR", "RQOS", "NO_RQOS"};
typedef struct gNB_id_s {
uint8_t bit_length;
std::string gNB_value;
nlohmann::json to_json() const {
nlohmann::json json_data = {};
json_data["bit_length"] = bit_length;
json_data["gNB_value"] = gNB_value;
return json_data;
}
} gNB_id_t; // 22bits to 32bits
typedef struct global_ran_node_id_s {
plmn_t plmn_id;
// n3IwfId:
gNB_id_t gNbId;
// ngeNbId:
} global_ran_node_id_t;
#endif
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "logger_base.hpp" #include "logger_base.hpp"
static const std::string ASYNC_CMD = "async_cmd"; static const std::string ASYNC_CMD = "asc_cmd";
static const std::string GTPV1_U = "gtpv1_u"; static const std::string GTPV1_U = "gtpv1_u";
static const std::string ITTI = "itti "; static const std::string ITTI = "itti ";
static const std::string UPF_APP = "upf_app"; static const std::string UPF_APP = "upf_app";
......
This diff is collapsed.
...@@ -26,7 +26,9 @@ ...@@ -26,7 +26,9 @@
* \email: lionel.gauthier@eurecom.fr * \email: lionel.gauthier@eurecom.fr
*/ */
#include "3gpp_conversions.hpp" #include "3gpp_conversions.hpp"
#include "3gpp_29.510.h"
#include <boost/algorithm/string.hpp>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
...@@ -152,3 +154,23 @@ bool xgpp_conv::endpoint_to_gtp_u_peer_address( ...@@ -152,3 +154,23 @@ bool xgpp_conv::endpoint_to_gtp_u_peer_address(
return false; return false;
} }
} }
//------------------------------------------------------------------------------
void xgpp_conv::sd_string_to_int(const std::string& sd_str, uint32_t& sd) {
sd = SD_NO_VALUE;
if (sd_str.empty()) return;
uint8_t base = 10;
try {
if (sd_str.size() > 2) {
if (boost::iequals(sd_str.substr(0, 2), "0x")) {
base = 16;
}
}
sd = std::stoul(sd_str, nullptr, base);
} catch (const std::exception& e) {
Logger::upf_app().error(
"Error when converting from string to int for S-NSSAI SD, error: %s",
e.what());
sd = SD_NO_VALUE;
}
}
...@@ -45,6 +45,7 @@ void pfcp_from_core_fteid(pfcp::fteid_t& pfteid, const fteid_t& fteid); ...@@ -45,6 +45,7 @@ void pfcp_from_core_fteid(pfcp::fteid_t& pfteid, const fteid_t& fteid);
void pfcp_cause_to_core_cause(const pfcp::cause_t& pc, cause_t& c); void pfcp_cause_to_core_cause(const pfcp::cause_t& pc, cause_t& c);
bool endpoint_to_gtp_u_peer_address( bool endpoint_to_gtp_u_peer_address(
const endpoint& ep, gtp_u_peer_address_t& gpa); const endpoint& ep, gtp_u_peer_address_t& gpa);
void sd_string_to_int(const std::string& sd_str, uint32_t& sd);
} // namespace xgpp_conv } // namespace xgpp_conv
#endif /* FILE_3GPP_CONVERSIONS_HPP_SEEN */ #endif /* FILE_3GPP_CONVERSIONS_HPP_SEEN */
...@@ -22,6 +22,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ...@@ -22,6 +22,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${SRC_TOP_DIR}/common) include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/common/msg) include_directories(${SRC_TOP_DIR}/common/msg)
include_directories(${SRC_TOP_DIR}/common/utils) include_directories(${SRC_TOP_DIR}/common/utils)
include_directories(${SRC_TOP_DIR}/common/utils/bstr)
include_directories(${SRC_TOP_DIR}/itti) include_directories(${SRC_TOP_DIR}/itti)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger) include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
......
Copyright (c) 2014, Paul Hsieh
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of bstrlib nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Better String Library
The Better String Library is an abstraction of a string data type which is
superior to the C library char buffer string type, or C++'s std::string.
Among the features achieved are:
- Substantial mitigation of buffer overflow/overrun problems and other
failures that result from erroneous usage of the common C string
library functions
- Significantly simplified string manipulation
- High performance interoperability with other source/libraries which
expect '\0' terminated char buffers
- Improved overall performance of common string operations
- Functional equivalency with other more modern languages
The library is totally stand alone, portable (known to work with gcc/g++,
MSVC++, Intel C++, WATCOM C/C++, Turbo C, Borland C++, IBM's native CC
compiler on Windows, Linux and Mac OS X), high performance, easy to use and
is not part of some other collection of data structures. Even the file I/O
functions are totally abstracted (so that other stream-like mechanisms, like
sockets, can be used.) Nevertheless, it is adequate as a complete
replacement of the C string library for string manipulation in any C program.
The library includes a robust C++ wrapper that uses overloaded operators,
rich constructors, exceptions, stream I/O and STL to make the CBString
struct a natural and powerful string abstraction with more functionality and
higher performance than std::string.
Bstrlib is stable, well tested and suitable for any software production
environment.
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license. Refer to the accompanying documentation for details on usage and
* license.
*/
/*
* bsafe.c
*
* This is an optional module that can be used to help enforce a safety
* standard based on pervasive usage of bstrlib. This file is not necessarily
* portable, however, it has been tested to work correctly with Intel's C/C++
* compiler, WATCOM C/C++ v11.x and Microsoft Visual C++.
*/
#include <stdio.h>
#include <stdlib.h>
#include "bsafe.h"
static int bsafeShouldExit = 1;
char* strcpy(char* dst, const char* src);
char* strcat(char* dst, const char* src);
char* strcpy(char* dst, const char* src) {
(void) dst;
(void) src;
fprintf(stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
char* strcat(char* dst, const char* src) {
(void) dst;
(void) src;
fprintf(stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
#if !defined(__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
char*(gets) (char* buf) {
(void) buf;
fprintf(stderr, "bsafe error: gets() is not safe, use bgets.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
#endif
char*(strncpy) (char* dst, const char* src, size_t n) {
(void) dst;
(void) src;
(void) n;
fprintf(stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n");
// if (bsafeShouldExit) exit (-1);
return NULL;
}
char*(strncat) (char* dst, const char* src, size_t n) {
(void) dst;
(void) src;
(void) n;
fprintf(
stderr,
"bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor "
"cstr2tbstr, btrunc then bstrcat instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
char*(strtok) (char* s1, const char* s2) {
(void) s1;
(void) s2;
fprintf(
stderr,
"bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
/*
//TODO: temporary solution for Release mode
char * (strdup) (const char *s) {
(void) s;
fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
}
*/
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2004, and is covered by the BSD open source
* license. Refer to the accompanying documentation for details on usage and
* license.
*/
/*
* bsafe.h
*
* This is an optional module that can be used to help enforce a safety
* standard based on pervasive usage of bstrlib. This file is not necessarily
* portable, however, it has been tested to work correctly with Intel's C/C++
* compiler, WATCOM C/C++ v11.x and Microsoft Visual C++.
*/
#ifndef BSTRLIB_BSAFE_INCLUDE
#define BSTRLIB_BSAFE_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
/* This is caught in the linker, so its not necessary for gcc. */
extern char*(gets) (char* buf);
#endif
extern char*(strncpy) (char* dst, const char* src, size_t n);
extern char*(strncat) (char* dst, const char* src, size_t n);
extern char*(strtok) (char* s1, const char* s2);
// extern char * (strdup) (const char *s);
#undef strcpy
#undef strcat
#define strcpy(a, b) bsafe_strcpy(a, b)
#define strcat(a, b) bsafe_strcat(a, b)
#ifdef __cplusplus
}
#endif
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* buniutil.c
*
* This file is not necessarily part of the core bstring library itself, but
* is just an implementation of basic utf8 processing for bstrlib. Note that
* this module is dependent upon bstrlib.c and utf8util.c
*/
#include "bstrlib.h"
#include "buniutil.h"
#define UNICODE__CODE_POINT__REPLACEMENT_CHARACTER (0xFFFDL)
/* int buIsUTF8Content (const_bstring bu)
*
* Scan string and return 1 if its entire contents is entirely UTF8 code
* points. Otherwise return 0.
*/
int buIsUTF8Content(const_bstring bu) {
struct utf8Iterator iter;
if (NULL == bdata(bu)) return 0;
for (utf8IteratorInit(&iter, bu->data, bu->slen); iter.next < iter.slen;) {
if (0 >= utf8IteratorGetNextCodePoint(&iter, -1)) return 0;
}
return 1;
}
/* int buGetBlkUTF16 (cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu,
* int pos)
*
* Convert a string of UTF8 codepoints (bu) skipping the first pos, into a
* sequence of UTF16 encoded code points. Returns the number of UCS2 16-bit
* words written to the output. No more than len words are written to the
* target array ucs2. If any code point in bu is unparsable, it will be
* translated to errCh.
*/
int buGetBlkUTF16(
/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos) {
struct tagbstring t;
struct utf8Iterator iter;
cpUcs4 ucs4;
int i, j;
if (!isLegalUnicodeCodePoint(errCh))
errCh = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER;
if (NULL == ucs2 || 0 >= len || NULL == bdata(bu) || 0 > pos) return BSTR_ERR;
for (j = 0, i = 0; j < bu->slen; j++) {
if (0x80 != (0xC0 & bu->data[j])) {
if (i >= pos) break;
i++;
}
}
t.mlen = -1;
t.data = bu->data + j;
t.slen = bu->slen - j;
utf8IteratorInit(&iter, t.data, t.slen);
ucs4 = BSTR_ERR;
for (i = 0; 0 < len && iter.next < iter.slen &&
0 <= (ucs4 = utf8IteratorGetNextCodePoint(&iter, errCh));
i++) {
if (ucs4 < 0x10000) {
*ucs2++ = (cpUcs2) ucs4;
len--;
} else {
if (len < 2) {
*ucs2++ = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER;
len--;
} else {
long y = ucs4 - 0x10000;
ucs2[0] = (cpUcs2) (0xD800 | (y >> 10));
ucs2[1] = (cpUcs2) (0xDC00 | (y & 0x03FF));
len -= 2;
ucs2 += 2;
i++;
}
}
}
while (0 < len) {
*ucs2++ = 0;
len--;
}
utf8IteratorUninit(&iter);
if (0 > ucs4) return BSTR_ERR;
return i;
}
/*
Unicode UTF-8
------- -----
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-32: U-000000 - U-10FFFF
*/
/* int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh)
*
* Convert an array of UCS4 code points (bu) to UTF8 codepoints b. Any
* invalid code point is replaced by errCh. If errCh is itself not a
* valid code point, then this translation will halt upon the first error
* and return BSTR_ERR. Otherwise BSTR_OK is returned.
*/
int buAppendBlkUcs4(bstring b, const cpUcs4* bu, int len, cpUcs4 errCh) {
int i, oldSlen;
if (NULL == bu || NULL == b || 0 > len || 0 > (oldSlen = blengthe(b, -1)))
return BSTR_ERR;
if (!isLegalUnicodeCodePoint(errCh)) errCh = ~0;
for (i = 0; i < len; i++) {
unsigned char c[6];
cpUcs4 v = bu[i];
if (!isLegalUnicodeCodePoint(v)) {
if (~0 == errCh) {
b->slen = oldSlen;
return BSTR_ERR;
}
v = errCh;
}
if (v < 0x80) {
if (BSTR_OK != bconchar(b, (char) v)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else if (v < 0x800) {
c[0] = (unsigned char) ((v >> 6) + 0xc0);
c[1] = (unsigned char) ((v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk(b, c, 2)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else if (v < 0x10000) {
c[0] = (unsigned char) ((v >> 12) + 0xe0);
c[1] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[2] = (unsigned char) ((v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk(b, c, 3)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else
#if 0
if (v < 0x200000)
#endif
{
c[0] = (unsigned char) ((v >> 18) + 0xf0);
c[1] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[3] = (unsigned char) ((v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk(b, c, 4)) {
b->slen = oldSlen;
return BSTR_ERR;
}
}
#if 0
else if (v < 0x4000000) {
c[0] = (unsigned char) ( (v >> 24) + 0xf8);
c[1] = (unsigned char) (((v >> 18) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[3] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[4] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 5)) {
b->slen = oldSlen;
return BSTR_ERR;
}
} else {
c[0] = (unsigned char) ( (v >> 30) + 0xfc);
c[1] = (unsigned char) (((v >> 24) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 18) & 0x3f) + 0x80);
c[3] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[4] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[5] = (unsigned char) (( v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 6)) {
b->slen = oldSlen;
return BSTR_ERR;
}
}
#endif
}
return BSTR_OK;
}
#define endSwap(cs, mode) \
((mode) ? ((((cs) &0xFF) << 8) | (((cs) >> 8) & 0xFF)) : (cs))
#define TEMP_UCS4_BUFFER_SIZE (64)
/* int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len,
* cpUcs2* bom, cpUcs4 errCh)
*
* Append an array of UCS2 code points (utf16) to UTF8 codepoints (bu). Any
* invalid code point is replaced by errCh. If errCh is itself not a
* valid code point, then this translation will halt upon the first error
* and return BSTR_ERR. Otherwise BSTR_OK is returned. If a byte order mark
* has been previously read, it may be passed in as bom, otherwise if *bom is
* set to 0, it will be filled in with the BOM as read from the first
* character if it is a BOM.
*/
int buAppendBlkUTF16(
bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh) {
cpUcs4 buff[TEMP_UCS4_BUFFER_SIZE];
int cc, i, sm, oldSlen;
if (NULL == bdata(bu) || NULL == utf16 || len < 0) return BSTR_ERR;
if (!isLegalUnicodeCodePoint(errCh)) errCh = ~0;
if (len == 0) return BSTR_OK;
oldSlen = bu->slen;
i = 0;
/* Check for BOM character and select endianess. Also remove the
BOM from the stream, since there is no need for it in a UTF-8 encoding. */
if (bom && (cpUcs2) 0xFFFE == *bom) {
sm = 8;
} else if (bom && (cpUcs2) 0xFEFF == *bom) {
sm = 0;
} else if (utf16[i] == (cpUcs2) 0xFFFE) {
if (bom) *bom = utf16[i];
sm = 8;
i++;
} else if (utf16[i] == (cpUcs2) 0xFEFF) {
if (bom) *bom = utf16[i];
sm = 0;
i++;
} else {
sm = 0; /* Assume local endianness. */
}
cc = 0;
for (; i < len; i++) {
cpUcs4 c, v;
v = endSwap(utf16[i], sm);
if ((v | 0x7FF) == 0xDFFF) { /* Deal with surrogate pairs */
if (v >= 0xDC00 || i >= len) {
ErrMode:;
if (~0 == errCh) {
ErrReturn:;
bu->slen = oldSlen;
return BSTR_ERR;
}
v = errCh;
} else {
i++;
if ((c = endSwap(utf16[i], sm) - 0xDC00) > 0x3FF) goto ErrMode;
v = ((v - 0xD800) << 10) + c + 0x10000;
}
}
buff[cc] = v;
cc++;
if (cc >= TEMP_UCS4_BUFFER_SIZE) {
if (0 > buAppendBlkUcs4(bu, buff, cc, errCh)) goto ErrReturn;
cc = 0;
}
}
if (cc > 0 && 0 > buAppendBlkUcs4(bu, buff, cc, errCh)) goto ErrReturn;
return BSTR_OK;
}
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* buniutil.h
*
* This file is the interface for the buniutil basic "Unicode for bstrings"
* functions. Note that there are dependencies on bstrlib.h and utf8util.h .
*/
#ifndef BSTRLIB_UNICODE_UTILITIES
#define BSTRLIB_UNICODE_UTILITIES
#include "utf8util.h"
#include "bstrlib.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int buIsUTF8Content(const_bstring bu);
extern int buAppendBlkUcs4(bstring b, const cpUcs4* bu, int len, cpUcs4 errCh);
/* For those unfortunate enough to be stuck supporting UTF16. */
extern int buGetBlkUTF16(
/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos);
extern int buAppendBlkUTF16(
bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh);
#ifdef __cplusplus
}
#endif
#endif /* BSTRLIB_UNICODE_UTILITIES */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* utf8util.h
*
* This file defines the interface to the utf8 utility functions.
*/
#ifndef UTF8_UNICODE_UTILITIES
#define UTF8_UNICODE_UTILITIES
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
#if INT_MAX >= 0x7fffffffUL
typedef int cpUcs4;
#elif LONG_MAX >= 0x7fffffffUL
typedef long cpUcs4;
#else
#error This compiler is not supported
#endif
#if UINT_MAX == 0xFFFF
typedef unsigned int cpUcs2;
#elif USHRT_MAX == 0xFFFF
typedef unsigned short cpUcs2;
#elif UCHAR_MAX == 0xFFFF
typedef unsigned char cpUcs2;
#else
#error This compiler is not supported
#endif
#define isLegalUnicodeCodePoint(v) \
((((v) < 0xD800L) || ((v) > 0xDFFFL)) && \
(((unsigned long) (v)) <= 0x0010FFFFL) && (((v) | 0x1F0001) != 0x1FFFFFL))
struct utf8Iterator {
unsigned char* data;
int slen;
int start, next;
int error;
};
#define utf8IteratorNoMore(it) (!(it) || (it)->next >= (it)->slen)
extern void utf8IteratorInit(
struct utf8Iterator* iter, unsigned char* data, int slen);
extern void utf8IteratorUninit(struct utf8Iterator* iter);
extern cpUcs4 utf8IteratorGetNextCodePoint(
struct utf8Iterator* iter, cpUcs4 errCh);
extern cpUcs4 utf8IteratorGetCurrCodePoint(
struct utf8Iterator* iter, cpUcs4 errCh);
extern int utf8ScanBackwardsForCodePoint(
unsigned char* msg, int len, int pos, cpUcs4* out);
#ifdef __cplusplus
}
#endif
#endif /* UTF8_UNICODE_UTILITIES */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "conversions.hpp" #include "conversions.hpp"
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <ctype.h> #include <ctype.h>
...@@ -124,6 +125,17 @@ struct in_addr conv::fromString(const std::string addr4) { ...@@ -124,6 +125,17 @@ struct in_addr conv::fromString(const std::string addr4) {
struct in_addr* ia = (struct in_addr*) buf; struct in_addr* ia = (struct in_addr*) buf;
return *ia; return *ia;
} }
//------------------------------------------------------------------------------
struct in6_addr conv::fromStringV6(const std::string& addr6) {
unsigned char buf[sizeof(struct in6_addr)] = {};
struct in6_addr ipv6_addr {};
if (inet_pton(AF_INET6, addr6.c_str(), buf) == 1) {
memcpy(&ipv6_addr, buf, sizeof(struct in6_addr));
}
return ipv6_addr;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::string conv::toString(const struct in_addr& inaddr) { std::string conv::toString(const struct in_addr& inaddr) {
std::string s = {}; std::string s = {};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment