Commit a9fb711c authored by Raphael Defosseux's avatar Raphael Defosseux

Merge remote-tracking branch 'origin/develop'

parents e12d77f9 113144f6
{
"files.associations": {
"deque": "cpp",
"string": "cpp",
"vector": "cpp"
}
}
\ No newline at end of file
# RELEASE NOTES: #
## v1.5.0 -- January 2023 ##
* Minimal fix for Decoding RegistrationRequest from COTS UE
* Fix small issue for NGAP lib
* NGAP IES code refactoring
* Fix PDU session release
* Refactor NGAP message callback
* Fix nake ptr
* feat(fqdn): giving some time for FQDN resolution
* Fix UL NAS transport
* Fix typo for Rejected NSSAI
* PDU session release supported
* Update SST type (int instead of string) in conf file
* Events exposure: location report with empty supi fixed
* small fix for event exposure loss of connectivity
* Minor fix for encoding no SD in PduSessionResourceSetupRequest
* Fix SST/SD on cots ue
* Docker images improvements
* Fixed docker exit by catching SIGTERM
* release mode does not use libasan anymore --> allocation of 20T virtual memory is no longer done
* Ubuntu22 and cgroup2 support
## v1.4.0 -- July 2022 ##
* Fix SCTP NG Shutdown issue
......
......@@ -25,7 +25,7 @@
#
#######################################
#SUPPORTED_DISTRO="Ubuntu 18.04, CentOS 7, RHEL 7"
SUPPORTED_DISTRO="Ubuntu 18.04, RHEL8"
SUPPORTED_DISTRO="Ubuntu 18.04,20.04,22.04, RHEL8"
if [ ! -f /etc/os-release ]; then
echo_fatal "No /etc/os-release file found. You're likely on an unsupported distro."
fi
......@@ -40,12 +40,14 @@ case "$OS_DISTRO" in
esac
IS_CONTAINER=`egrep -c "docker|kubepods|podman|buildah|libpod" /proc/self/cgroup || true`
IS_DOCKERBUILD=${IS_DOCKERFILE:-0}
if [ $IS_CONTAINER -eq 0 ]
if [ $IS_CONTAINER -eq 0 ] && [ $IS_DOCKERBUILD -eq 0 ]
then
SUDO='sudo -S -E'
else
SUDO=''
IS_CONTAINER=1
fi
###############################
......@@ -83,7 +85,7 @@ echo_info() { cecho "$*" $blue ;}
#-------------------------------------------------------------------------------
# From https://stackoverflow.com/questions/4023830/how-to-compare-two-strings-in-dot-separated-version-format-in-bash
# arg1 is a dotted (or not) version number (ex 4.10.6.56-ubunutu)
# arg1 is a dotted (or not) version number (ex 4.10.6.56-ubunutu)
# arg2 is a dotted (or not) version number (ex 4.10.6.56-ubunutu)
# return 0 if $1 lower or equal $2, else 1
version_le() {
......@@ -129,14 +131,14 @@ check_supported_distribution() {
case "$distribution" in
"ubuntu18.04") return 0 ;;
"ubuntu20.04") return 0 ;;
"ubuntu22.04") return 0 ;;
"rhel8") return 0 ;;
"rhel8.2") return 0 ;;
"rhel8.3") return 0 ;;
"rhel8.4") return 0 ;;
"rhel8.5") return 0 ;;
"rhel8.6") return 0 ;;
"rhel8.7") return 0 ;;
#"centos7") return 0 ;;
"rhel8.2") return 0 ;;
"rhel8.3") return 0 ;;
"rhel8.4") return 0 ;;
"rhel8.5") return 0 ;;
"rhel8.6") return 0 ;;
"rhel8.7") return 0 ;;
esac
return 1
}
......@@ -165,7 +167,10 @@ clean_kernel() {
#-------------------------------------------------------------------------------
disable_ipv6() {
$SUDO sysctl -w net.ipv6.conf.all.disable_ipv6=1
if [ $IS_CONTAINER -eq 0 ]
then
$SUDO sysctl -w net.ipv6.conf.all.disable_ipv6=1
fi
}
......@@ -174,8 +179,8 @@ disable_ipv6() {
# arg1 = version
# arg2 = req_version
#
function version_gt() {
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1";
function version_gt() {
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1";
}
......@@ -293,7 +298,10 @@ check_enable_epel_repos() {
echo "EPEL repos already present. Good."
else
echo "EPEL repos not present. Installing them."
$SUDO $INSTALLER install $OPTION https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
wget --tries=4 --retry-connrefused --wait=8 \
https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$SUDO $INSTALLER install $OPTION epel-release-latest-7.noarch.rpm
rm -f epel-release-latest-7.noarch.rpm
fi
fi
}
......@@ -312,5 +320,3 @@ set_openair_env(){
openair_path=${openair_path%/src/s6a/*}
export OPENAIRCN_DIR=$openair_path
}
......@@ -30,90 +30,6 @@
SCRIPT=$(readlink -f ${BASH_SOURCE})
THIS_SCRIPT_PATH=`dirname $SCRIPT`
source $THIS_SCRIPT_PATH/build_helper
source $THIS_SCRIPT_PATH/build_helper.fb_folly
#-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries)
install_cpprestsdk_from_git() {
echo "Starting to install cpprestsdk"
if [ $1 -eq 0 ]; then
read -p "Do you want to install C++ REST SDK ? <y/N> " prompt
OPTION="-y"
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/Microsoft/cpprestsdk.git
echo "Install C++ REST SDK from $GIT_URL"
pushd $OPENAIRCN_DIR/build/ext
echo "Downloading C++ REST SDK"
if [[ $OPTION =~ -[yY](es)* ]]
then
$SUDO rm -rf cpprestsdk
fi
git clone $GIT_URL
cd cpprestsdk
git submodule update --init
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
mkdir _build && cd _build
$CMAKE -G Ninja .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF -DBUILD_SAMPLES=OFF
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO ninja install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO ldconfig -v
popd
fi
echo "cpprestsdk installation complete"
return 0
}
#-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries)
install_fmt() {
echo "Starting to install fmt"
if [ $1 -eq 0 ]; then
read -p "Do you want to install open-source formatting library for C++ ? <y/N> " prompt
OPTION=""
else
prompt='y'
OPTION="-y"
fi
echo "Install fmt from source"
if [[ $prompt =~ [yY](es)* ]]
then
cd /tmp
echo "Downloading fmt"
$SUDO rm -rf /tmp/fmt*
git clone https://github.com/fmtlib/fmt.git
ret=$?;[[ $ret -ne 0 ]] && return $ret
cd fmt
# Looks like since Nov 11 commits, we cannot build
git checkout -f 1936dddc3c53c1c0db55a665cf419dc7a257ba62
$CMAKE -DFMT_TEST=FALSE .
ret=$?;[[ $ret -ne 0 ]] && return $ret
make -j `nproc`
ret=$?;[[ $ret -ne 0 ]] && return $ret
$SUDO make install
cd /tmp
rm -rf /tmp/fmt*
fi
echo "fmt installation complete"
return 0
}
#-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script)
......@@ -194,13 +110,14 @@ install_pistache_from_git() {
-DPISTACHE_BUILD_EXAMPLES=false \
-DPISTACHE_BUILD_TESTS=false \
-DPISTACHE_BUILD_DOCS=false \
..
..
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
make
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/pistache/_build
fi
echo "pistache installation complete"
return 0
......@@ -247,6 +164,7 @@ install_nlohmann_from_git() {
$SUDO make install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
popd
rm -Rf $OPENAIRCN_DIR/build/ext/json/_build
fi
echo "Nlohmann Json installation complete"
return 0
......@@ -276,7 +194,7 @@ install_nghttp2_from_git() {
if [[ $OS_DISTRO == "ubuntu" ]]; then
PACKAGE_LIST="\
g++ \
cmake \
$CMAKE \
binutils \
autoconf \
automake \
......@@ -287,7 +205,7 @@ install_nghttp2_from_git() {
libcunit1-dev \
libssl-dev \
libxml2-dev libev-dev libevent-dev libjansson-dev libc-ares-dev \
libjemalloc-dev libsystemd-dev cython python3-dev python-setuptools"
libjemalloc-dev libsystemd-dev python3-dev python-setuptools"
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
PACKAGE_LIST="\
gcc-c++ \
......@@ -332,12 +250,13 @@ install_nghttp2_from_git() {
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
./configure --enable-asio-lib --enable-lib-only
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
make
make -j $(nproc)
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO make install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO ldconfig
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
git clean -x -d -ff .
popd
fi
echo "nghttp2 installation complete"
......@@ -351,7 +270,7 @@ check_install_amf_deps(){
if [ $1 -gt 0 ]; then
OPTION="-y"
else
else
OPTION=""
fi
if [ $2 -eq 0 ]; then
......@@ -360,7 +279,7 @@ check_install_amf_deps(){
debug=1
fi
echo "Check supported distribution"
echo "Check supported distribution"
check_supported_distribution
[[ $? -ne 0 ]] && return $?
......@@ -370,7 +289,9 @@ check_install_amf_deps(){
#$SUDO systemctl mask apt-daily.timer
#$SUDO systemctl mask apt-daily-upgrade.service
#$SUDO systemctl mask apt-daily-upgrade.timer
$SUDO sed -i 's/1/0/g' /etc/apt/apt.conf.d/10periodic
if [ $IS_CONTAINER -eq 0 ]; then
$SUDO sed -i 's/1/0/g' /etc/apt/apt.conf.d/10periodic
fi
fi
update_package_db
......@@ -383,26 +304,16 @@ check_install_amf_deps(){
PACKAGE_LIST="\
autoconf \
automake \
bison \
build-essential \
$CMAKE \
daemon \
doxygen \
flex \
gdb \
wget \
git"
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
PACKAGE_LIST="\
autoconf \
automake \
gcc-c++ \
bison \
$CMAKE \
make \
doxygen \
flex \
gdb \
git"
else
echo_fatal "$OS_DISTRO is not a supported distribution."
......@@ -410,24 +321,28 @@ check_install_amf_deps(){
echo "Install build tools"
$SUDO $INSTALLER install $OPTION $PACKAGE_LIST
ret=$?;[[ $ret -ne 0 ]] && return $ret
# Libraries
if [[ $OS_DISTRO == "ubuntu" ]]; then
case "$(get_distribution_release)" in
"ubuntu18.04")
# Currently Ubuntu18.04 has boost 1.65 as the latest
# We need at least 1.66
# PPA has 1.67
$SUDO add-apt-repository ppa:mhier/libboost-latest --yes
$SUDO $INSTALLER update
if [ $IS_CONTAINER -eq 0 ]; then
specific_packages="libconfig++-dev libasio-dev libboost-all-dev mysql-server"
else
specific_packages="libconfig++-dev libasio-dev libboost-all-dev"
fi
# Currently Ubuntu18.04 has boost 1.65 as the latest
# We need at least 1.66
# PPA has 1.67
$SUDO $INSTALLER install $OPTION software-properties-common
$SUDO add-apt-repository ppa:mhier/libboost-latest --yes
$SUDO $INSTALLER update
if [ $IS_CONTAINER -eq 0 ]; then
specific_packages="libconfig++-dev libasio-dev libboost-all-dev mysql-server libasan4"
else
specific_packages="libconfig++-dev libasio-dev libboost-all-dev libasan4"
fi
;;
"ubuntu20.04")
specific_packages="libconfig++-dev libasio-dev libboost-all-dev libmysqlclient-dev"
specific_packages="libconfig++-dev libasio-dev libboost-all-dev libasan5"
;;
"ubuntu22.04")
specific_packages="libconfig++-dev libasio-dev libboost-all-dev libasan6"
;;
esac
# removed libspdlog-dev
......@@ -435,43 +350,29 @@ check_install_amf_deps(){
$specific_packages \
mysql-client \
libmysqlclient-dev \
guile-2.0-dev \
libcurl4-gnutls-dev \
libevent-dev \
libgcrypt?-dev \
libgmp-dev \
libhogweed? \
libidn2-0-dev \
libidn11-dev \
libpthread-stubs0-dev \
libsctp-dev \
libssl-dev \
libtool \
libxml2 \
libxml2-dev \
openssl \
python \
nettle-dev \
libcurl4 \
net-tools \
pkg-config \
ninja-build \
wget \
libasan?"
ninja-build"
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
PACKAGE_LIST="\
guile-devel \
mysql \
mysql-devel \
mysql-libs \
libconfig-devel \
libgcrypt-devel \
gmp-devel \
libidn-devel \
lksctp-tools \
lksctp-tools-devel \
openssl-devel \
libnghttp2 \
libtool \
libxml2 \
libxml2-devel \
......@@ -488,38 +389,29 @@ check_install_amf_deps(){
fi
echo "Install distro libs"
$SUDO $INSTALLER install $OPTION $PACKAGE_LIST
# fix issue with libboost in U18 for a bare metal deployment
if [[ $OS_DISTRO == "ubuntu" ]]; then
case "$(get_distribution_release)" in
"ubuntu18.04")
$SUDO $INSTALLER remove $OPTION libboost1.65-dev || true
$SUDO $INSTALLER autoremove $OPTION || true
$SUDO $INSTALLER install $OPTION libboost1.67-dev
;;
;;
esac
fi
fi
ret=$?;[[ $ret -ne 0 ]] && return $ret
echo "distro libs installation complete"
install_cpprestsdk_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
# Use fmt lib included in spdlog
# install_fmt $1
# ret=$?;[[ $ret -ne 0 ]] && return $ret
install_spdlog_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
install_fb_folly_from_source $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
install_pistache_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
install_nlohmann_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
ret=$?;[[ $ret -ne 0 ]] && return $ret
install_nghttp2_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
......
################################################################################
# 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
################################################################################
# file build_helper.fb_folly
# brief
# author Lionel GAUTHIER
#
#######################################
SCRIPT=$(readlink -f ${BASH_SOURCE})
THIS_SCRIPT_PATH=`dirname $SCRIPT`
source $THIS_SCRIPT_PATH/build_helper
#arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries)
install_fb_folly_from_source(){
echo "Starting to install folly"
if [ $1 -eq 0 ]; then
OPTION=""
read -p "Do you want to install FaceBook folly (github)? <y/N> " prompt
else
prompt='y'
OPTION="-y"
fi
if [ $2 -eq 0 ]; then
debug=0
else
debug=1
fi
if [[ $prompt =~ [yY](es)* ]]
then
if [[ "$OS_BASEDISTRO" == "fedora" ]]; then
$SUDO $INSTALLER install $OPTION \
gcc-c++ \
$CMAKE \
make \
libevent-devel \
double-conversion-devel \
glog-devel \
gflags-devel \
snappy-devel \
lz4-devel \
zlib-devel \
binutils-devel \
jemalloc-devel \
openssl-devel
ret=$?;[[ $ret -ne 0 ]] && return $ret
elif [[ $OS_DISTRO == "ubuntu" ]]; then
$SUDO $INSTALLER install $OPTION \
$CMAKE \
g++ \
libevent-dev \
libdouble-conversion-dev \
libgoogle-glog-dev \
libgflags-dev \
libiberty-dev \
liblz4-dev \
liblzma-dev \
libsnappy-dev \
wget \
zlib1g-dev \
binutils-dev \
libjemalloc-dev
ret=$?;[[ $ret -ne 0 ]] && return $ret
fi
pushd /tmp
if [ $debug -eq 1 ]; then
# For advanced debugging options
$SUDO $INSTALLER install $OPTION \
libunwind8-dev \
libelf-dev \
libdwarf-dev
ret=$?;[[ $ret -ne 0 ]] && return $ret
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz && \
tar zxf release-1.8.0.tar.gz && \
rm -f release-1.8.0.tar.gz && \
cd googletest-release-1.8.0 && \
$CMAKE . && \
make && \
$SUDO make install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
cd ..
fi
$SUDO rm -rf /tmp/folly
git clone https://github.com/facebook/folly.git
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
cd folly
if [[ "$OS_BASEDISTRO" == "fedora" ]]; then
git checkout -f v2019.06.17.00
echo 'diff --git a/build/fbcode_builder/CMake/FindGflags.cmake b/build/fbcode_builder/CMake/FindGflags.cmake' > patch.diff
echo 'index 246ceac..3b96716 100644' >> patch.diff
echo '--- a/build/fbcode_builder/CMake/FindGflags.cmake' >> patch.diff
echo '+++ b/build/fbcode_builder/CMake/FindGflags.cmake' >> patch.diff
echo '@@ -34,6 +34,9 @@ IF (LIBGFLAGS_INCLUDE_DIR)' >> patch.diff
echo ' ENDIF ()' >> patch.diff
echo '' >> patch.diff
echo ' find_package(gflags CONFIG QUIET)' >> patch.diff
echo '+get_filename_component (_LIB_PATH "${gflags_CONFIG}/../../../" ABSOLUTE)' >> patch.diff
echo '+unset(gflags_LIBRARIES)' >> patch.diff
echo '+find_library(gflags_LIBRARIES gflags PATHS ${_LIB_PATH})' >> patch.diff
echo ' if (gflags_FOUND)' >> patch.diff
echo ' if (NOT Gflags_FIND_QUIETLY)' >> patch.diff
echo ' message(STATUS "Found gflags from package config ${gflags_CONFIG}")' >> patch.diff
git apply patch.diff
else
git checkout -f v2019.11.11.00
fi
mkdir _build && cd _build
$CMAKE ..
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
fi
echo_success "folly installation complete"
return 0
}
# prompt has been removed for easier Ctrl+C Ctrl+V
# please update the following information according to your configuration
INSTANCE=1
PREFIX='/usr/local/etc/oai'
sudo mkdir -m 0777 -p $PREFIX
cp ../../etc/amf.conf $PREFIX
declare -A AMF_CONF
AMF_CONF[@INSTANCE@]=$INSTANCE
AMF_CONF[@PREFIX@]=$PREFIX
AMF_CONF[@PID_DIRECTORY@]='/var/run'
AMF_CONF[@MCC@]='208'
AMF_CONF[@MNC@]='95'
AMF_CONF[@REGION_ID@]='128'
AMF_CONF[@AMF_SET_ID@]='1'
AMF_CONF[@SERVED_GUAMI_MCC_0@]='208'
AMF_CONF[@SERVED_GUAMI_MNC_0@]='95'
AMF_CONF[@SERVED_GUAMI_REGION_ID_0@]='128'
AMF_CONF[@SERVED_GUAMI_AMF_SET_ID_0@]='1'
AMF_CONF[@SERVED_GUAMI_MCC_1@]='460'
AMF_CONF[@SERVED_GUAMI_MNC_1@]='11'
AMF_CONF[@SERVED_GUAMI_REGION_ID_1@]='10'
AMF_CONF[@SERVED_GUAMI_AMF_SET_ID_1@]='1'
AMF_CONF[@PLMN_SUPPORT_MCC@]='208'
AMF_CONF[@PLMN_SUPPORT_MNC@]='95'
AMF_CONF[@PLMN_SUPPORT_TAC@]='0xa000'
AMF_CONF[@SST_0@]='128'
AMF_CONF[@SD_0@]='128'
AMF_CONF[@SST_1@]='1'
AMF_CONF[@SD_1@]='1'
AMF_CONF[@AMF_INTERFACE_NAME_FOR_NGAP@]='eth0'
AMF_CONF[@AMF_INTERFACE_NAME_FOR_N11@]='eth0'
AMF_CONF[@EXTERNAL_AUSF@]='no'
AMF_CONF[@EXTERNAL_UDM@]='no'
AMF_CONF[@EXTERNAL_NRF@]='no'
AMF_CONF[@EXTERNAL_NSSF@]='no'
AMF_CONF[@USE_FQDN_DNS@]='no'
AMF_CONF[@USE_HTTP2@]='no'
AMF_CONF[@NF_REGISTRATION@]='no'
AMF_CONF[@SMF_SELECTION@]='no'
AMF_CONF[@SMF_INSTANCE_ID_0@]='1'
AMF_CONF[@SMF_IPV4_ADDR_0@]='192.168.22.208'
AMF_CONF[@SMF_HTTP_VERSION_0@]='v1'
AMF_CONF[@SMF_FQDN_0@]='oai-smf'
AMF_CONF[@SMF_INSTANCE_ID_1@]='2'
AMF_CONF[@SMF_IPV4_ADDR_1@]='192.168.22.207'
AMF_CONF[@SMF_HTTP_VERSION_1@]='v1'
AMF_CONF[@SMF_FQDN_1@]='oai-smf2'
AMF_CONF[@NRF_IPV4_ADDRESS@]='192.168.22.195'
AMF_CONF[@NRF_PORT@]='80'
AMF_CONF[@NRF_API_VERSION@]='v1'
AMF_CONF[@NRF_FQDN@]='oai-nrf'
AMF_CONF[@AUSF_IPV4_ADDRESS@]='192.168.22.199'
AMF_CONF[@AUSF_PORT@]='80'
AMF_CONF[@AUSF_API_VERSION@]='v1'
AMF_CONF[@AUSF_FQDN@]='oai-ausf'
AMF_CONF[@NSSF_IPV4_ADDRESS@]='192.168.22.214'
AMF_CONF[@NSSF_PORT@]='80'
AMF_CONF[@NSSF_API_VERSION@]='v1'
AMF_CONF[@NSSF_FQDN@]='oai-nssf'
AMF_CONF[@UDM_IPV4_ADDRESS@]='192.168.22.209'
AMF_CONF[@UDM_PORT@]='80'
AMF_CONF[@UDM_API_VERSION@]='v1'
AMF_CONF[@UDM_FQDN@]='oai-udm'
AMF_CONF[@NRF_SELECTION@]='no'
AMF_CONF[@INT_ALGO_LIST@]='[ "NIA0" , "NIA1" , "NIA2" ]'
AMF_CONF[@CIPH_ALGO_LIST@]='[ "NEA0" , "NEA1" , "NEA2" ]'
AMF_CONF[@MYSQL_SERVER@]='127.0.0.1'
AMF_CONF[@MYSQL_USER@]='root'
AMF_CONF[@MYSQL_PASS@]='linux'
AMF_CONF[@MYSQL_DB@]='oai_db'
for K in "${!AMF_CONF[@]}"; do
egrep -lRZ "$K" $PREFIX | xargs -0 -l sed -i -e "s|$K|${AMF_CONF[$K]}|g"
ret=$?;[[ ret -ne 0 ]] && echo "Tried to replace $K with ${AMF_CONF[$K]}"
done
#!/bin/sh
################################################################################
# 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
################################################################################
## Sample values for configuration
export INSTANCE=0
export PID_DIRECTORY=/var/run
export MCC=208
export MNC=95
export REGION_ID=128
export AMF_SET_ID=1
export SERVED_GUAMI_MCC_0=208
export SERVED_GUAMI_MNC_0=95
export SERVED_GUAMI_REGION_ID_0=128
export SERVED_GUAMI_AMF_SET_ID_0=1
export PLMN_SUPPORT_MCC=208
export PLMN_SUPPORT_MNC=95
export PLMN_SUPPORT_TAC=0xa000
export SST_0=1
export SD_0=0xFFFFFF
export SST_1=1
export SD_1=1
export AMF_INTERFACE_NAME_FOR_NGAP=eth0
export AMF_INTERFACE_NAME_FOR_N11=eth0
export SMF_INSTANCE_ID_0=1
export SMF_FQDN_0=localhost
export SMF_IPV4_ADDR_0=127.0.0.1
export SMF_HTTP_VERSION_0=v1
export SELECTED_0=true
export MYSQL_SERVER=127.0.0.1
export MYSQL_USER=root
export MYSQL_PASS=linux
export MYSQL_DB=oai_db
export NRF_IPV4_ADDRESS=127.0.0.1
export NRF_PORT=80
export EXTERNAL_NRF=no
export NF_REGISTRATION=yes
export SMF_SELECTION=yes
export USE_FQDN_DNS=yes
export EXTERNAL_AUSF=yes
export EXTERNAL_UDM=no
export EXTERNAL_NSSF=no
export USE_HTTP2=no
export NRF_API_VERSION=v1
export NRF_FQDN=localhost
export AUSF_IPV4_ADDRESS=127.0.0.1
export AUSF_PORT=80
export AUSF_API_VERSION=v1
export AUSF_FQDN=localhost
export UDM_IPV4_ADDRESS=127.0.0.1
export UDM_PORT=80
export UDM_API_VERSION=v2
export UDM_FQDN=localhost
../../scripts/entrypoint.py
\ No newline at end of file
......@@ -183,12 +183,13 @@ pipeline {
// Currently this pipeline only runs for pushes to `develop` branch
// First clean image registry
try {
myShCmd('docker image tag oai-amf:develop oai-amf:develop-previous', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker image rm oai-amf:develop', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
} catch (Exception e) {
echo "Maybe a previous build went wrong"
}
// In case of push to `develop` branch we build from scratch
myShCmd('docker build --no-cache --target oai-amf --tag oai-amf:' + amf_tag + ' --file docker/Dockerfile.amf.ubuntu18 . > archives/amf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker build --no-cache --target oai-amf --tag oai-amf:' + amf_tag + ' --file docker/Dockerfile.amf.ubuntu . > archives/amf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
}
if ("MERGE".equals(env.gitlabActionType)) {
try {
......@@ -201,7 +202,7 @@ pipeline {
}
// "latest" is the tag used in the docker file.
myShCmd('docker image tag oai-amf-base:' + AMF_BASE_IMAGE_TAG + ' oai-amf-base:latest', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker build --no-cache --target oai-amf --tag oai-amf:' + amf_tag + ' --file ci-scripts/docker/Dockerfile.ci.ubuntu.18.04 . > archives/amf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker build --no-cache --target oai-amf --tag oai-amf:' + amf_tag + ' --file ci-scripts/docker/Dockerfile.ci.ubuntu . > archives/amf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
}
// Putting a place holder to try out on the flattening of image.
// If not satisfactory, we can remove it.
......@@ -221,9 +222,12 @@ pipeline {
}
}
success {
myShCmd('docker image rm oai-amf:develop-previous || true', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
sh "echo 'OAI-AMF DOCKER IMAGE BUILD: OK' >> archives/amf_docker_image_build.log"
}
unsuccessful {
myShCmd('docker image tag oai-amf:develop-previous oai-amf:develop || true', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker image rm oai-amf:develop-previous || true', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
sh "echo 'OAI-AMF DOCKER IMAGE BUILD: KO' >> archives/amf_docker_image_build.log"
}
}
......@@ -238,6 +242,7 @@ pipeline {
// Currently this pipeline only runs for pushes to `develop` branch
// First clean image registry
try {
myShCmd('sudo podman image tag oai-amf:develop oai-amf:develop-previous || true', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman image rm oai-amf:develop || true', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
} catch (Exception e) {
echo "Maybe a previous build went wrong"
......@@ -252,10 +257,7 @@ pipeline {
myShCmd('cp /etc/pki/entitlement/*pem ./etc-pki-entitlement', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo cp /etc/rhsm/rhsm.conf ./rhsm-conf', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo cp /etc/rhsm/ca/*.pem ./rhsm-ca', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman build --no-cache --target oai-amf --tag oai-amf:' + amf_tag + ' --file docker/Dockerfile.amf.rhel8 . > archives/amf_podman_image_build.log 2>&1', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
// Putting a place holder to try out on the flattening of image.
// If not satisfactory, we can remove it.
myShCmd('python3 ./ci-scripts/flatten_image.py --tag oai-amf:' + amf_tag, rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman build --no-cache --squash --target oai-amf --tag oai-amf:' + amf_tag + ' --file docker/Dockerfile.amf.rhel8 --format docker . > archives/amf_podman_image_build.log 2>&1', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman image ls >> archives/amf_podman_image_build.log', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
if ("MERGE".equals(env.gitlabActionType)) {
myShCmd('sudo podman image tag oai-amf:' + amf_tag + ' oai-amf:' + rhel_amf_tag, rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
......@@ -271,9 +273,12 @@ pipeline {
}
}
success {
myShCmd('sudo podman image rm oai-amf:develop-previous || true', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
sh "echo 'OAI-AMF PODMAN RHEL8 IMAGE BUILD: OK' >> archives/amf_podman_image_build.log"
}
unsuccessful {
myShCmd('sudo podman image tag oai-amf:develop-previous oai-amf:develop || true', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman image rm oai-amf:develop-previous || true', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
sh "echo 'OAI-AMF PODMAN RHEL8 IMAGE BUILD: KO' >> archives/amf_podman_image_build.log"
}
}
......
......@@ -205,4 +205,4 @@ echo "Nb Files that do NOT follow OAI rules: $NB_TO_FORMAT over $NB_TOTAL checke
echo "NB_FILES_FAILING_CHECK=$NB_TO_FORMAT" > ./oai_rules_result.txt
echo "NB_FILES_CHECKED=$NB_TOTAL" >> ./oai_rules_result.txt
exit 0
if [ $NB_TO_FORMAT -ne 0 ]; then exit -1; else exit 0; fi
......@@ -21,23 +21,27 @@
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface AMF service
# Valid for Ubuntu-18.04 (bionic)
# Valid for Ubuntu-18.04 (bionic),
# Ubuntu-20.04 (focal),
# Ubuntu-22.04 (jammy)
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# BUILDER IMAGE
#---------------------------------------------------------------------
ARG BASE_IMAGE=ubuntu:bionic
FROM oai-amf-base:latest as oai-amf-builder
# Copying source code
RUN rm -Rf /openair-amf/
WORKDIR /openair-amf/
COPY . /openair-amf
RUN cp -Rf /openair-amf-ext-ref /openair-amf/build/ext
# Building AMF
WORKDIR /openair-amf/build/scripts
RUN ldconfig && \
cp -Rf /openair-amf-ext-ref /openair-amf/build/ext && \
./build_amf --clean --Verbose --build-type Release --jobs && \
ldd /openair-amf/build/amf/build/amf && \
mv /openair-amf/build/amf/build/amf /openair-amf/build/amf/build/oai_amf
......@@ -45,7 +49,7 @@ RUN ldconfig && \
#---------------------------------------------------------------------
# TARGET IMAGE
#---------------------------------------------------------------------
FROM ubuntu:bionic as oai-amf
FROM $BASE_IMAGE as oai-amf
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Paris
# We install some debug tools for the moment in addition of mandatory libraries
......@@ -56,39 +60,56 @@ RUN apt-get update && \
psmisc \
net-tools \
bc \
libssh-4 \
openssl \
perl \
libasan4 \
libbrotli1 \
netbase \
python3\
python3-jinja2\
# Ubuntu 18 --> libasan4
# Ubuntu 20 --> libasan5
# Ubuntu 22 --> libasan6
# libasan? \
libgssapi-krb5-2 \
libldap-2.4-2 \
# Ubuntu 18/20 --> libldap-2.4-2
# Ubuntu 22 --> libldap-2.5-0
libldap-2.?-? \
libconfig++9v5 \
libsctp1 \
&& rm -rf /var/lib/apt/lists/*
librtmp1 \
libpsl5 \
# Ubuntu 18/20 --> mysqlclient20, Ubuntu22 --> mysqlclient21
libmysqlclient2? \
libsqlite3-0 \
libcurl4-gnutls-dev \
# Ubuntu 18 --> boost62/65 -> will remove both
# Ubuntu 20 --> boost67/71 -> will remove 67
# Ubuntu 22 --> boost74
libboost-thread1.??.0 \
libboost-chrono1.??.0 \
&& rm -rf /var/lib/apt/lists/* \
/lib/x86_64-linux-gnu/libboost_system.so.1.6*.0 \
/lib/x86_64-linux-gnu/libboost_chrono.so.1.6*.0 \
/lib/x86_64-linux-gnu/libboost_thread.so.1.6*.0
# Copying executable and generated libraries
WORKDIR /openair-amf/bin
COPY --from=oai-amf-builder \
/openair-amf/build/amf/build/oai_amf \
/openair-amf/scripts/entrypoint.sh \
./
WORKDIR /usr/lib/x86_64-linux-gnu
COPY --from=oai-amf-builder \
/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 \
/usr/lib/x86_64-linux-gnu/libsqlite3.so.0 \
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 \
/usr/lib/x86_64-linux-gnu/librtmp.so.1 \
/usr/lib/x86_64-linux-gnu/libpsl.so.5 \
/openair-amf/scripts/entrypoint.py \
/openair-amf/scripts/healthcheck.sh \
./
WORKDIR /usr/local/lib
COPY --from=oai-amf-builder \
# Copying only the packages built from source
/usr/local/lib/libnghttp2.so.14 \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib/libboost_system.so.1.67.0 \
/usr/lib/libboost_thread.so.1.67.0 \
/usr/lib/libboost_chrono.so.1.67.0 \
/usr/local/lib/libpistache.so \
# Ubuntu 18 --> boost 67 will be copied
/usr/lib/libboost_system.so.1.* \
/usr/lib/libboost_thread.so.1.* \
/usr/lib/libboost_chrono.so.1.* \
./
RUN ldconfig && \
......@@ -102,6 +123,11 @@ WORKDIR /openair-amf
# expose ports
EXPOSE 80/tcp 9090/tcp 38412/sctp
# healthcheck
HEALTHCHECK --interval=10s \
--timeout=15s \
--retries=6 \
CMD /openair-amf/bin/healthcheck.sh
ENTRYPOINT ["/bin/bash","/openair-amf/bin/entrypoint.sh"]
ENTRYPOINT ["python3", "/openair-amf/bin/entrypoint.py"]
CMD ["/openair-amf/bin/oai_amf", "-c", "/openair-amf/etc/amf.conf", "-o"]
......@@ -49,6 +49,9 @@ def perform_flattening(tag):
if re.search('podman', podman_check.strip()):
cli = 'sudo podman'
image_prefix = 'localhost/'
# since HEALTHCHECK is not supported by podman import
# we don't flatten
return 0
if cli == '':
cmd = 'which docker || true'
docker_check = subprocess.check_output(cmd, shell=True, universal_newlines=True)
......@@ -76,8 +79,9 @@ def perform_flattening(tag):
cmd += ' --change "EXPOSE 9090/tcp" '
if cli == 'docker':
cmd += ' --change "EXPOSE 38412/sctp" '
cmd += ' --change "HEALTHCHECK --interval=10s --timeout=15s --retries=6 CMD /openair-amf/bin/healthcheck.sh" '
cmd += ' --change "CMD [\\"/openair-amf/bin/oai_amf\\", \\"-c\\", \\"/openair-amf/etc/amf.conf\\", \\"-o\\"]" '
cmd += ' --change "ENTRYPOINT [\\"/bin/bash\\", \\"/openair-amf/bin/entrypoint.sh\\"]" '
cmd += ' --change "ENTRYPOINT [\\"python3\\", \\"/openair-amf/bin/entrypoint.py\\"]" '
cmd += ' - ' + image_prefix + tag
print (cmd)
subprocess.check_output(cmd, shell=True, universal_newlines=True)
......
......@@ -195,7 +195,7 @@ class HtmlReport():
self.file.write(' <strong>All files in repository follow OAI rules. <span class="glyphicon glyphicon-ok-circle"></span> -> (' + nb_total.strip() + ' were checked)</strong>\n')
self.file.write(' </div>\n')
else:
self.file.write(' <div class="alert alert-warning">\n')
self.file.write(' <div class="alert alert-danger">\n')
if self.git_pull_request:
self.file.write(' <strong>' + nb_fail.strip() + ' modified files in Pull-Request DO NOT follow OAI rules. <span class="glyphicon glyphicon-warning-sign"></span> -> (' + nb_total.strip() + ' were checked)</strong>\n')
else:
......@@ -463,20 +463,18 @@ class HtmlReport():
section_end_pattern = 'build_amf --clean --Verbose --build-type Release --jobs'
section_status = False
package_install = False
folly_build_start = False
folly_build_status = False
spdlog_build_start = False
spdlog_build_status = False
pistache_build_start = False
pistache_build_status = False
json_build_start = False
json_build_status = False
cpprest_build_start = False
cpprest_build_status = False
nghttp2_build_start = False
nghttp2_build_status = False
base_image = False
with open(cwd + '/archives/' + logFileName, 'r') as logfile:
for line in logfile:
result = re.search('FROM oai-amf-base', line)
result = re.search('FROM oai-amf-base:latest', line)
if result is not None:
base_image = True
result = re.search(section_start_pattern, line)
......@@ -492,18 +490,12 @@ class HtmlReport():
result = re.search('distro libs installation complete', line)
if result is not None:
package_install = True
result = re.search('Starting to install cpprestsdk', line)
result = re.search('Starting to install nghttp2', line)
if result is not None:
cpprest_build_start = True
result = re.search('cpprestsdk installation complete', line)
if result is not None and cpprest_build_start:
cpprest_build_status = True
result = re.search('Starting to install folly', line)
if result is not None:
folly_build_start = True
result = re.search('folly installation complete', line)
if result is not None and folly_build_start:
folly_build_status = True
nghttp2_build_start = True
result = re.search('nghttp2 installation complete', line)
if result is not None and nghttp2_build_start:
nghttp2_build_status = True
result = re.search('Starting to install spdlog', line)
if result is not None:
spdlog_build_start = True
......@@ -540,17 +532,11 @@ class HtmlReport():
else:
cell_msg += ' ** Packages Installation: KO\n'
if base_image:
cell_msg += ' ** cpprestsdk Installation: N/A\n'
elif cpprest_build_status:
cell_msg += ' ** cpprestsdk Installation: OK\n'
else:
cell_msg += ' ** cpprestsdk Installation: KO\n'
if base_image:
cell_msg += ' ** folly Installation: N/A\n'
elif folly_build_status:
cell_msg += ' ** folly Installation: OK\n'
cell_msg += ' ** nghttp2-asio Installation: N/A\n'
elif nghttp2_build_status:
cell_msg += ' ** nghttp2-asio Installation: OK\n'
else:
cell_msg += ' ** folly Installation: KO\n'
cell_msg += ' ** nghttp2-asio Installation: KO\n'
if base_image:
cell_msg += ' ** spdlog Installation: N/A\n'
elif spdlog_build_status:
......
#/*
# * 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
# */
#---------------------------------------------------------------------
#
---
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
name: "oai-amf"
namespace: oaicicd-core
spec:
runPolicy: "Serial"
source:
type: "Binary"
secrets:
- secret:
name: etc-pki-entitlement
destinationDir: etc-pki-entitlement
configMaps:
- configMap:
name: rhsm-conf
destinationDir: rhsm-conf
- configMap:
name: rhsm-ca
destinationDir: rhsm-ca
strategy:
dockerStrategy:
dockerfilePath: "docker/Dockerfile.amf.rhel8"
output:
to:
kind: "ImageStreamTag"
name: "oai-amf:develop"
#/*
# * 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
# */
#---------------------------------------------------------------------
#
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: oai-amf
namespace: oaicicd-core
spec:
lookupPolicy:
local: true
status:
tag: develop
......@@ -21,7 +21,7 @@
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface AMF service
# Valid for RHEL 8.2
# Valid for UBI 8.6 | RHEL 8.6
#
#---------------------------------------------------------------------
......@@ -30,7 +30,7 @@
#---------------------------------------------------------------------
FROM registry.access.redhat.com/ubi8/ubi:latest AS oai-amf-builder
ARG NEEDED_GIT_PROXY
ENV IS_DOCKERFILE=1
# Copy the entitlements
COPY ./etc-pki-entitlement /etc/pki/entitlement
......@@ -49,17 +49,16 @@ RUN rm -f /etc/rhsm-host && \
diffutils \
file \
gcc-c++ \
cmake3 \
ninja-build \
boost-devel \
openssl-devel \
openssl \
wget \
libasan && \
echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf
# Some GIT configuration command quite useful
RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi"
RUN git config --global https.postBuffer 123289600 && \
git config --global http.sslverify false
......@@ -76,51 +75,60 @@ WORKDIR /openair-amf/build/scripts
RUN ldconfig && \
./build_amf --clean --Verbose --build-type Release --jobs && \
ldd /openair-amf/build/amf/build/amf && \
mv /openair-amf/build/amf/build/amf /openair-amf/build/amf/build/oai_amf
mv /openair-amf/build/amf/build/amf /openair-amf/build/amf/build/oai_amf && \
# Remove entitlements and Subscription Manager configs
rm -rf /etc/pki/entitlement && \
rm -rf /etc/rhsm
#---------------------------------------------------------------------
# TARGET IMAGE
#---------------------------------------------------------------------
FROM registry.access.redhat.com/ubi8/ubi:latest as oai-amf
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest as oai-amf
ENV TZ=Europe/Paris
# We install some debug tools for the moment in addition of mandatory libraries
RUN yum update -y && \
yum install -y --enablerepo="ubi-8-codeready-builder" \
# Copy the entitlements
COPY ./etc-pki-entitlement /etc/pki/entitlement
# Copy the subscription manager configurations
COPY ./rhsm-conf /etc/rhsm
COPY ./rhsm-ca /etc/rhsm/ca
RUN rm -f /etc/rhsm-host && \
microdnf update -y && \
microdnf install -y \
tzdata \
libasan \
# libasan \
lksctp-tools \
procps-ng \
psmisc \
net-tools \
libevent && \
yum clean all -y && \
rm -rf /var/cache/yum /var/cache/dnf
libicu \
boost \
libevent \
findutils \
python3\
python3-jinja2\
mysql-libs \
libconfig && \
microdnf clean all -y && \
rm -rf /var/cache/yum /var/cache/dnf && \
# Remove entitlements and Subscription Manager configs
rm -rf /etc/pki/entitlement && \
rm -rf /etc/rhsm
# Copying executable and generated libraries
WORKDIR /openair-amf/bin
COPY --from=oai-amf-builder \
/openair-amf/build/amf/build/oai_amf \
/openair-amf/scripts/entrypoint.sh \
/openair-amf/scripts/entrypoint.py \
/openair-amf/scripts/healthcheck.sh \
./
COPY --from=oai-amf-builder \
/usr/lib64/libconfig++.so.9 \
/usr/lib64/libboost_system.so.1.66.0 \
/usr/local/lib64/libpistache.so.0 \
/usr/local/lib/libnghttp2_asio.so \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib64/mysql/libmysqlclient.so.21 \
/usr/lib64/libsctp.so.1 \
/usr/local/lib64/libcpprest.so.2.10 \
/usr/lib64/libboost_random.so.1.66.0 \
/usr/lib64/libboost_thread.so.1.66.0 \
/usr/lib64/libboost_filesystem.so.1.66.0 \
/usr/lib64/libboost_chrono.so.1.66.0 \
/usr/lib64/libboost_atomic.so.1.66.0 \
/usr/lib64/libboost_date_time.so.1.66.0 \
/usr/lib64/libboost_regex.so.1.66.0 \
/usr/lib64/libicudata.so.60 \
/usr/lib64/libicui18n.so.60 \
/usr/lib64/libicuuc.so.60 \
/usr/lib64/
RUN ldconfig && \
......@@ -134,6 +142,11 @@ WORKDIR /openair-amf
# expose ports
EXPOSE 80/tcp 9090/tcp 38412/sctp
# healthcheck
HEALTHCHECK --interval=10s \
--timeout=15s \
--retries=6 \
CMD /openair-amf/bin/healthcheck.sh
ENTRYPOINT ["/openair-amf/bin/entrypoint.sh"]
ENTRYPOINT ["python3", "/openair-amf/bin/entrypoint.py"]
CMD ["/openair-amf/bin/oai_amf", "-c", "/openair-amf/etc/amf.conf", "-o"]
......@@ -21,30 +21,29 @@
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface AMF service
# Valid for Ubuntu-18.04 (bionic)
# Valid for Ubuntu-18.04 (bionic),
# Ubuntu-20.04 (focal),
# Ubuntu-22.04 (jammy)
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# BUILDER IMAGE
# BASE IMAGE
#---------------------------------------------------------------------
FROM ubuntu:bionic as oai-amf-builder
ARG NEEDED_GIT_PROXY
ARG BASE_IMAGE=ubuntu:bionic
FROM $BASE_IMAGE as oai-amf-base
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Paris
ENV IS_DOCKERFILE=1
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
psmisc \
software-properties-common \
git \
vim \
&& rm -rf /var/lib/apt/lists/*
# Some GIT configuration commands quite useful
RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi"
RUN git config --global https.postBuffer 123289600 && \
git config --global http.sslverify false
......@@ -54,8 +53,13 @@ COPY . /openair-amf
# Installing all the needed libraries/packages to build and run AMF
WORKDIR /openair-amf/build/scripts
RUN ./build_amf --install-deps --force
RUN ./build_amf --install-deps --force && \
cp -Rf /openair-amf/build/ext /openair-amf-ext-ref
#---------------------------------------------------------------------
# BUILDER IMAGE
#---------------------------------------------------------------------
FROM oai-amf-base as oai-amf-builder
# Building AMF
WORKDIR /openair-amf/build/scripts
RUN ldconfig && \
......@@ -66,7 +70,7 @@ RUN ldconfig && \
#---------------------------------------------------------------------
# TARGET IMAGE
#---------------------------------------------------------------------
FROM ubuntu:bionic as oai-amf
FROM $BASE_IMAGE as oai-amf
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Paris
# We install some debug tools for the moment in addition of mandatory libraries
......@@ -77,39 +81,56 @@ RUN apt-get update && \
psmisc \
net-tools \
bc \
libssh-4 \
openssl \
perl \
libasan4 \
libbrotli1 \
netbase \
python3\
python3-jinja2\
# Ubuntu 18 --> libasan4
# Ubuntu 20 --> libasan5
# Ubuntu 22 --> libasan6
# libasan? \
libgssapi-krb5-2 \
libldap-2.4-2 \
# Ubuntu 18/20 --> libldap-2.4-2
# Ubuntu 22 --> libldap-2.5-0
libldap-2.?-? \
libconfig++9v5 \
libsctp1 \
&& rm -rf /var/lib/apt/lists/*
librtmp1 \
libpsl5 \
# Ubuntu 18/20 --> mysqlclient20, Ubuntu22 --> mysqlclient21
libmysqlclient2? \
libsqlite3-0 \
libcurl4-gnutls-dev \
# Ubuntu 18 --> boost62/65 -> will remove both
# Ubuntu 20 --> boost67/71 -> will remove 67
# Ubuntu 22 --> boost74
libboost-thread1.??.0 \
libboost-chrono1.??.0 \
&& rm -rf /var/lib/apt/lists/* \
/lib/x86_64-linux-gnu/libboost_system.so.1.6*.0 \
/lib/x86_64-linux-gnu/libboost_chrono.so.1.6*.0 \
/lib/x86_64-linux-gnu/libboost_thread.so.1.6*.0
# Copying executable and generated libraries
WORKDIR /openair-amf/bin
COPY --from=oai-amf-builder \
/openair-amf/build/amf/build/oai_amf \
/openair-amf/scripts/entrypoint.sh \
./
WORKDIR /usr/lib/x86_64-linux-gnu
COPY --from=oai-amf-builder \
/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 \
/usr/lib/x86_64-linux-gnu/libsqlite3.so.0 \
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 \
/usr/lib/x86_64-linux-gnu/librtmp.so.1 \
/usr/lib/x86_64-linux-gnu/libpsl.so.5 \
/openair-amf/scripts/entrypoint.py \
/openair-amf/scripts/healthcheck.sh \
./
WORKDIR /usr/local/lib
COPY --from=oai-amf-builder \
# Copying only the packages built from source
/usr/local/lib/libnghttp2.so.14 \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib/libboost_system.so.1.67.0 \
/usr/lib/libboost_thread.so.1.67.0 \
/usr/lib/libboost_chrono.so.1.67.0 \
/usr/local/lib/libpistache.so \
# Ubuntu 18 --> boost 67 will be copied
/usr/lib/libboost_system.so.1.* \
/usr/lib/libboost_thread.so.1.* \
/usr/lib/libboost_chrono.so.1.* \
./
RUN ldconfig && \
......@@ -123,6 +144,11 @@ WORKDIR /openair-amf
# expose ports
EXPOSE 80/tcp 9090/tcp 38412/sctp
# healthcheck
HEALTHCHECK --interval=10s \
--timeout=15s \
--retries=6 \
CMD /openair-amf/bin/healthcheck.sh
ENTRYPOINT ["/bin/bash","/openair-amf/bin/entrypoint.sh"]
ENTRYPOINT ["python3", "/openair-amf/bin/entrypoint.py"]
CMD ["/openair-amf/bin/oai_amf", "-c", "/openair-amf/etc/amf.conf", "-o"]
This diff is collapsed.
#!/usr/bin/env python3
################################################################################
# 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
################################################################################
from jinja2 import Environment, FileSystemLoader
import socket
import os
import sys
CONFIG_FILE = str(os.getenv('CONFIG_FILE','/openair-amf/etc/amf.conf'))
MOUNT_CONFIG = str(os.getenv('MOUNT_CONFIG','no')).lower()
def resolve(hostname):
try:
return socket.gethostbyname(hostname)
except socket.error:
print(f"Not able to resolve {hostname}")
def render(filepath,funcs,values):
env = Environment(loader=FileSystemLoader(os.path.dirname(filepath)))
jinja_template = env.get_template(os.path.basename(filepath))
jinja_template.globals.update(funcs)
template_string = jinja_template.render(env=values)
return template_string
env_variables = dict()
#list of all the environment variables
for name, value in os.environ.items():
env_variables.update({name:value})
if MOUNT_CONFIG != "yes":
output = render(CONFIG_FILE,{"resolve":resolve},env_variables)
with open(CONFIG_FILE, "w") as fh:
fh.write(output)
print(f"Configuration file {CONFIG_FILE} is ready")
if len(sys.argv) == 1:
sys.exit(0)
os.execvp(sys.argv[1], sys.argv[1:]) #important for running the network function it works like exec $@
else:
print("Configuration file is mounted to the network function")
\ No newline at end of file
#!/bin/bash
set -euo pipefail
CONFIG_DIR="/openair-amf/etc"
# Default values
EXTERNAL_NRF=${EXTERNAL_NRF:-no}
EXTERNAL_NSSF=${EXTERNAL_NSSF:-no}
EXTERNAL_AUSF=${EXTERNAL_AUSF:-no}
EXTERNAL_UDM=${EXTERNAL_UDM:-no}
UDM_IPV4_ADDRESS=${UDM_IPV4_ADDRESS:-0.0.0.0}
UDM_PORT=${UDM_PORT:-80}
UDM_API_VERSION=${UDM_API_VERSION:-v2}
UDM_FQDN=${UDM_FQDN:-oai-udm}
EXTERNAL_NRF=${EXTERNAL_NRF:-no}
NRF_SELECTION=${NRF_SELECTION:-no}
EXTERNAL_NSSF=${EXTERNAL_NSSF:-no}
NSSF_IPV4_ADDRESS=${NSSF_IPV4_ADDRESS:-0.0.0.0}
NSSF_PORT=${NSSF_PORT:-80}
NSSF_API_VERSION=${NSSF_API_VERSION:-v2}
NSSF_FQDN=${NSSF_FQDN:-oai-nssf}
INT_ALGO_LIST=${INT_ALGO_LIST:-'[ "NIA0" , "NIA1" , "NIA2" ]'}
CIPH_ALGO_LIST=${CIPH_ALGO_LIST:-'[ "NEA0" , "NEA1" , "NEA2" ]'}
USE_HTTP2=${USE_HTTP2:-no}
SST_0=${SST_0:-128}
SD_0=${SD_0:-128}
SST_1=${SST_1:-1}
SD_1=${SD_1:-0xFFFFFF}
SST_2=${SST_2:-130}
SD_2=${SD_2:-130}
OPERATOR_KEY=${OPERATOR_KEY:-'63bfa50ee6523365ff14c1f45f88737d'}
if [[ ${USE_FQDN_DNS} == "yes" ]];then
NSSF_IPV4_ADDR=${NSSF_IPV4_ADDR_0:-0.0.0.0}
SMF_IPV4_ADDR_0=${SMF_IPV4_ADDR_0:-0.0.0.0}
SMF_IPV4_ADDR_1=${SMF_IPV4_ADDR_1:-0.0.0.0}
NRF_IPV4_ADDRESS=${NRF_IPV4_ADDRESS:-0.0.0.0}
AUSF_IPV4_ADDRESS=${AUSF_IPV4_ADDRESS:-0.0.0.0}
UDM_IPV4_ADDRESS=${UDM_IPV4_ADDRESS:-0.0.0.0}
fi
for c in ${CONFIG_DIR}/*.conf; do
# grep variable names (format: ${VAR}) from template to be rendered
if ! grep -oP '@[a-zA-Z0-9_]+@' ${c}; then
echo "Configuration is already set"
exec "$@"
fi
VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs)
echo "Now setting these variables '${VARS}'"
# create sed expressions for substituting each occurrence of ${VAR}
# with the value of the environment variable "VAR"
EXPRESSIONS=""
for v in ${VARS}; do
NEW_VAR=`echo $v | sed -e "s#@##g"`
if [[ -z ${!NEW_VAR+x} ]]; then
echo "Error: Environment variable '${NEW_VAR}' is not set." \
"Config file '$(basename $c)' requires all of $VARS."
exit 1
fi
EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g"
done
EXPRESSIONS="${EXPRESSIONS#';'}"
# render template and inline replace config file
sed -i "${EXPRESSIONS}" ${c}
done
echo "Done setting the configuration"
exec "$@"
#!/bin/bash
set -eo pipefail
STATUS=0
AMF_PORT_FOR_NGAP=38412
AMF_PORT_FOR_N11_HTTP=80
AMF_IP_NGAP_INTERFACE=$(ifconfig $AMF_INTERFACE_NAME_FOR_NGAP | grep inet | awk {'print $2'})
AMF_IP_N11_INTERFACE=$(ifconfig $AMF_INTERFACE_NAME_FOR_N11 | grep inet | awk {'print $2'})
N2_PORT_STATUS=$(netstat -Snpl | grep -o "$AMF_IP_NGAP_INTERFACE:$AMF_PORT_FOR_NGAP")
N11_PORT_STATUS=$(netstat -tnpl | grep -o "$AMF_IP_N11_INTERFACE:$AMF_PORT_FOR_N11_HTTP")
#Check if entrypoint properly configured the conf file and no parameter is unset (optional)
NB_UNREPLACED_AT=`cat /openair-amf/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true`
if [ $NB_UNREPLACED_AT -ne 0 ]; then
STATUS=1
echo "Healthcheck error: configuration file is not configured properly"
fi
if [[ -z $N2_PORT_STATUS ]]; then
STATUS=1
echo "Healthcheck error: N2 SCTP port $AMF_PORT_FOR_NGAP is not listening"
fi
if [[ -z $N11_PORT_STATUS ]]; then
STATUS=1
echo "Healthcheck error: N11/SBI TCP/HTTP port $AMF_PORT_FOR_N11_HTTP is not listening"
fi
exit $STATUS
# CODEOWNERS
src/contexts:
- Keliang DU, BUPT
- Tien Thinh NGUYEN, Eurecom
src/amf-app
- Keliang DU, BUPT
- Tien Thinh NGUYEN, Eurecom
- Shivam Gandhi, KCL
src/itti
- Lionel GAUTHIER, Eurecom
- Tien Thinh NGUYEN, Eurecom
src/common
- Sebastien ROUX, Eurecom
- Lionel Gauthier, Eurecom
- Tien Thinh NGUYEN, Eurecom
- Keliang DU, BUPT
Secu_algorithms
- Kharbach Othmane
- GAUTHIER Lionel, Eurecom
- Keliang DU, Bupt
SCTP
- Keliang DU, Bupt
NGAP
- Keliang DU, Bupt
- Tien Thinh NGUYEN, Eurecom
SBI
- Keliang DU, Bupt
- Tien Thinh NGUYEN, Eurecom
NAS/UTILS: To be updated
\ No newline at end of file
......@@ -50,7 +50,7 @@ file(GLOB AMF_src_files
${CMAKE_CURRENT_SOURCE_DIR}/amf_module_from_config.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_n1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_n2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_n11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_sbi.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_event.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_profile.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_statistics.cpp
......
This diff is collapsed.
......@@ -19,36 +19,27 @@
* contact@openairinterface.org
*/
/*! \file amf_app.hpp
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _AMF_APP_H_
#define _AMF_APP_H_
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <map>
#include <shared_mutex>
#include <string>
#include "ProblemDetails.h"
#include "UeN1N2InfoSubscriptionCreateData.h"
#include "amf_config.hpp"
#include "amf_module_from_config.hpp"
#include "amf_msg.hpp"
#include "amf_profile.hpp"
#include "amf_subscription.hpp"
#include "itti.hpp"
#include "itti_msg_n11.hpp"
#include "itti_msg_amf_app.hpp"
#include "ue_context.hpp"
#include "amf_subscription.hpp"
#include "itti_msg_sbi.hpp"
#include "amf_msg.hpp"
#include "ProblemDetails.h"
#include "UeN1N2InfoSubscriptionCreateData.h"
#include "ue_context.hpp"
#include "uint_generator.hpp"
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
using namespace config;
......@@ -92,9 +83,9 @@ class amf_app {
std::map<uint32_t, boost::shared_ptr<boost::promise<std::string>>>
curl_handle_responses_n2_sm;
mutable std::shared_mutex m_curl_handle_responses_n11;
mutable std::shared_mutex m_curl_handle_responses_sbi;
std::map<uint32_t, boost::shared_ptr<boost::promise<nlohmann::json>>>
curl_handle_responses_n11;
curl_handle_responses_sbi;
util::uint_generator<uint32_t> n1n2sub_id_generator;
std::map<
......@@ -152,6 +143,13 @@ class amf_app {
*/
void handle_itti_message(itti_sbi_n1n2_message_unsubscribe& itti_msg);
/*
* Handle ITTI message (SBI PDU Session Release Notification)
* @param [itti_sbi_pdu_session_release_notif&]: ITTI message
* @return void
*/
void handle_itti_message(itti_sbi_pdu_session_release_notif& itti_msg);
/*
* Handle ITTI message (SBI AMF configuration)
* @param [itti_sbi_amf_configuration&]: ITTI message
......@@ -298,6 +296,18 @@ class amf_app {
const string& supi,
std::vector<std::shared_ptr<pdu_session_context>>& sessions_ctx);
/*
* Update PDU Session Context status
* @param [const std::string&] ue_id: UE SUPI
* @param [const uint8_t&] pdu_session_id: PDU Session ID
* @param [const oai::amf::model::SmContextStatusNotification&]
* statusNotification: Notification information received from SMF
* @return true if success, otherwise false
*/
bool update_pdu_sessions_context(
const string& ue_id, const uint8_t& pdu_session_id,
const oai::amf::model::SmContextStatusNotification& statusNotification);
/*
* Generate a TMSI value for UE
* @param void
......@@ -458,14 +468,14 @@ class amf_app {
void generate_amf_profile();
/*
* Send request to N11 task to trigger NF instance registration to NRF
* Send request to SBI task to trigger NF instance registration to NRF
* @param [void]
* @return void
*/
void trigger_nf_registration_request();
/*
* Send request to N11 task to trigger NF instance deregistration to NRF
* Send request to SBI task to trigger NF instance deregistration to NRF
* @param [void]
* @return void
*/
......
This diff is collapsed.
......@@ -19,13 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_config.hpp
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _AMF_CONFIG_H_
#define _AMF_CONFIG_H_
......@@ -33,18 +26,19 @@
#include <netinet/in.h>
#include <sys/socket.h>
#include <boost/algorithm/string.hpp>
#include <libconfig.h++>
#include <nlohmann/json.hpp>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include "amf_config.hpp"
#include "amf.hpp"
#include "amf_config.hpp"
#include "common_defs.h"
#include "if.hpp"
#include "pdu_session_context.hpp"
#include "string.hpp"
#include "thread_sched.hpp"
#include "common_defs.h"
#define AMF_CONFIG_STRING_AMF_CONFIG "AMF"
#define AMF_CONFIG_STRING_PID_DIRECTORY "PID_DIRECTORY"
......@@ -59,7 +53,7 @@
#define AMF_CONFIG_STRING_PPID "PPID"
#define AMF_CONFIG_STRING_SBI_HTTP2_PORT "HTTP2_PORT"
#define AMF_CONFIG_STRING_INTERFACE_N11 "N11"
#define AMF_CONFIG_STRING_INTERFACE_SBI "SBI"
#define AMF_CONFIG_STRING_SMF_INSTANCES_POOL "SMF_INSTANCES_POOL"
#define AMF_CONFIG_STRING_SMF_INSTANCE_ID "SMF_INSTANCE_ID"
#define AMF_CONFIG_STRING_SMF_INSTANCE_PORT "PORT"
......@@ -124,7 +118,7 @@ using namespace libconfig;
namespace config {
typedef struct {
typedef struct auth_conf_s {
std::string mysql_server;
std::string mysql_user;
std::string mysql_pass;
......@@ -148,7 +142,7 @@ typedef struct {
this->random = json_data["random"].get<std::string>();
}
} auth_conf;
} auth_conf_t;
typedef struct interface_cfg_s {
std::string if_name;
......@@ -457,6 +451,28 @@ class amf_config {
*/
std::string get_ausf_ue_authentications_uri();
/*
* Get the URI of SMF PDU Session Service
* @param [const std::shared_ptr<pdu_session_context>&] psc: pointer to the
* PDU Session Context
* @param [std::string&] smf_uri: based URI of Nsmf_PDUSession Services
* @return true if can get the URI. otherwise false
*/
bool get_smf_pdu_session_context_uri(
const std::shared_ptr<pdu_session_context>& psc, std::string& smf_uri);
/*
* Get the URI of SMF Services
* @param [const std::string&] smf_addr: SMF's Addr in String representation
* @param [const std::string&] smf_port: SMF's port in String representation
* @param [const std::string&] smf_api_version: SMF's API version in String
* representation
* @return URI in string format
*/
std::string get_smf_pdu_session_base_uri(
const std::string& smf_addr, const std::string& smf_port,
const std::string& smf_api_version);
/*
* Display the AMF configuration parameters
* @param void
......@@ -481,7 +497,7 @@ class amf_config {
unsigned int instance;
std::string pid_dir;
interface_cfg_t n2;
interface_cfg_t n11;
interface_cfg_t sbi;
itti_cfg_t itti;
std::string sbi_api_version;
unsigned int sbi_http2_port;
......@@ -493,7 +509,7 @@ class amf_config {
unsigned int relative_amf_capacity;
std::vector<plmn_item_t> plmn_list;
std::string is_emergency_support;
auth_conf auth_para;
auth_conf_t auth_para;
nas_conf_t nas_cfg;
std::vector<smf_inst_t> smf_pool;
......
......@@ -19,16 +19,9 @@
* contact@openairinterface.org
*/
/*! \file amf_event.cpp
\brief
\author Shivam Gandhi (KCL), Tien-Thinh NGUYEN (EURECOM)
\company
\date 2021
\email: contact@openairinterface.org
*/
#include "amf_event.hpp"
using namespace amf_application;
//------------------------------------------------------------------------------
bs2::connection amf_event::subscribe_ue_location_report(
const ue_location_report_sig_t::slot_type& sig) {
......@@ -51,3 +44,13 @@ bs2::connection amf_event::subscribe_ue_connectivity_state(
const ue_connectivity_state_sig_t::slot_type& sig) {
return ue_connectivity_state.connect(sig);
}
bs2::connection amf_event::subscribe_ue_loss_of_connectivity(
const ue_loss_of_connectivity_sig_t::slot_type& sig) {
return ue_loss_of_connectivity.connect(sig);
}
//------------------------------------------------------------------------------
bs2::connection amf_event::subscribe_ue_communication_failure(
const ue_communication_failure_sig_t::slot_type& sig) {
return ue_communication_failure.connect(sig);
}
......@@ -19,14 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_event.hpp
\brief
\author Shivam Gandhi (KCL), Tien-Thinh NGUYEN (EURECOM)
\company
\date 2021
\email: contact@openairinterface.org
*/
#include <boost/signals2.hpp>
namespace bs2 = boost::signals2;
......@@ -90,7 +82,22 @@ class amf_event {
bs2::connection subscribe_ue_connectivity_state(
const ue_connectivity_state_sig_t::slot_type& sig);
private:
/*
* Subscribe to UE Loss of Connectivity Notification signal
* @param [const ue_loss_of_connectivity_sig_t::slot_type&] sig: slot_type*/
bs2::connection subscribe_ue_loss_of_connectivity(
const ue_loss_of_connectivity_sig_t::slot_type& sig);
/*
* Subscribe to UE Communication Failure Notification signal
* @param [const ue_communication_failure_sig_t::slot_type&] sig: slot_type
* parameter
* @return boost::signals2::connection: the connection between the signal and
* the slot
*/
bs2::connection subscribe_ue_communication_failure(
const ue_communication_failure_sig_t::slot_type& sig);
ue_location_report_sig_t ue_location_report; // Signal for UE Location Report
ue_reachability_status_sig_t
ue_reachability_status; // Signal for UE Reachability Report
......@@ -98,5 +105,9 @@ class amf_event {
ue_registration_state; // Signal for UE Registration State Report
ue_connectivity_state_sig_t
ue_connectivity_state; // Signal for UE Connectivity State Report
ue_loss_of_connectivity_sig_t
ue_loss_of_connectivity; // Signal for UE Loss of Connectivity
ue_communication_failure_sig_t
ue_communication_failure; // Signal for UE Communication Failure Report
};
} // namespace amf_application
......@@ -19,20 +19,14 @@
* contact@openairinterface.org
*/
/*! \file amf_event_sig.hpp
\brief
\author Shivam Gandhi (KCL), Tien-Thinh NGUYEN (EURECOM)
\company
\date 2021
\email: contact@openairinterface.org
*/
#ifndef FILE_SMF_EVENT_SIG_HPP_SEEN
#define FILE_SMF_EVENT_SIG_HPP_SEEN
#include <boost/signals2.hpp>
#include <string>
#include "UserLocation.h"
#include "CommunicationFailure.h"
namespace bs2 = boost::signals2;
......@@ -58,7 +52,7 @@ typedef bs2::signal_type<
// Signal for UE Registration State Report
// SUPI, registration state, HTTP version
typedef bs2::signal_type<
void(std::string, uint8_t, uint8_t),
void(std::string, uint8_t, uint8_t, uint32_t, long),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
ue_registration_state_sig_t;
......@@ -69,9 +63,23 @@ typedef bs2::signal_type<
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
ue_connectivity_state_sig_t;
// Signal for Loss of Connectivity
// SUPI, status, HTTP version,
// RAN UE NGAP ID, AMF UE NGAP ID
typedef bs2::signal_type<
void(std::string, uint8_t, uint8_t, uint32_t, long),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
ue_loss_of_connectivity_sig_t;
// TODO: Communication-Failure-Report
// Signal for Communication Failure Report
// SUPI, Communication Failure codes, HTTP version
typedef bs2::signal_type<
void(std::string, oai::amf::model::CommunicationFailure, uint8_t),
bs2::keywords::mutex_type<bs2::dummy_mutex>>::type
ue_communication_failure_sig_t;
// TODO: UEs-In-Area-Report
// TODO: Loss-of-Connectivity
} // namespace amf_application
#endif
......@@ -19,19 +19,12 @@
* contact@openairinterface.org
*/
/*! \file amf_module_from_config.cpp
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#include "amf_module_from_config.hpp"
#include "common_defs.h"
#include <iostream>
#include <string>
#include "common_defs.h"
#include "logger.hpp"
namespace config {
......
......@@ -19,13 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_module_from_config.hpp
\brief
\author Keliang DU, BUPT
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _AMF_MODULE_FROM_CONFIG_H_
#define _AMF_MODULE_FROM_CONFIG_H_
......
......@@ -19,13 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_msg.cpp
\brief
\author Shivam Gandhi
\company KCL
\date 2021
\email: shivam.gandhi@kcl.ac.uk
*/
#include "amf_msg.hpp"
using namespace amf_application;
......
......@@ -19,20 +19,13 @@
* contact@openairinterface.org
*/
/*! \file amf_msg.hpp
\brief
\author
\company
\date 2021
\email:
*/
#ifndef FILE_AMF_MSG_HPP_SEEN
#define FILE_AMF_MSG_HPP_SEEN
#include "amf.hpp"
#include "3gpp_29.518.h"
#include "amf_profile.hpp"
#include "AmfEventReport.h"
#include "amf.hpp"
#include "amf_profile.hpp"
namespace amf_application {
......
This diff is collapsed.
......@@ -19,13 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_n1.hpp
\brief
\author Keliang DU (BUPT), Tien-Thinh NGUYEN (EURECOM)
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _AMF_N1_H_
#define _AMF_N1_H_
......@@ -36,22 +29,22 @@
#include <map>
#include <shared_mutex>
#include "3gpp_ts24501.hpp"
#include "3gpp_29.503.h"
#include "3gpp_ts24501.hpp"
#include "AuthorizedNetworkSliceInfo.h"
#include "Nssai.h"
#include "RegistrationAccept.hpp"
#include "SliceInfoForRegistration.h"
#include "amf.hpp"
#include "amf_event.hpp"
#include "amf_statistics.hpp"
#include "bstrlib.h"
#include "itti.hpp"
#include "itti_msg_n1.hpp"
#include "mysql_db.hpp"
#include "nas_context.hpp"
#include "pdu_session_context.hpp"
#include "amf_event.hpp"
#include "RegistrationAccept.hpp"
#include "ue_context.hpp"
#include "itti.hpp"
#include "SliceInfoForRegistration.h"
#include "AuthorizedNetworkSliceInfo.h"
#include "Nssai.h"
namespace amf_application {
......@@ -152,6 +145,15 @@ class amf_n1 {
*/
bool is_amf_ue_id_2_nas_context(const long& amf_ue_ngap_id) const;
/*
* Verify if a UE NAS context associated with an AMF UE NGAP ID exist
* @param [const long& ] amf_ue_ngap_id: AMF UE NGAP ID
* @param [std::shared_ptr<nas_context>&] nc: pointer to UE NAS context
* @return true if UE NAS context exist, otherwise false
*/
bool is_amf_ue_id_2_nas_context(
const long& amf_ue_ngap_id, std::shared_ptr<nas_context>& nc) const;
/*
* Get UE NAS context associated with an AMF UE NGAP ID
* @param [const long& ] amf_ue_ngap_id: AMF UE NGAP ID
......@@ -284,7 +286,8 @@ class amf_n1 {
std::shared_ptr<nas_context>& nc, bstring& nas_msg);
/*
* Generate the Authentication Vectors
* Generate the Authentication Vectors (either from AUSF(UDM) or generate
* locally in AMF)
* @param [std::shared_ptr<nas_context>&] nc: Pointer to the UE NAS Context
* @return true if generated successfully, otherwise return false
*/
......@@ -797,10 +800,13 @@ class amf_n1 {
* @param [std::string] supi: SUPI
* @param [uint8_t] status: Registration status
* @param [uint8_t] http_version: HTTP version (for the notification)
* @param [uint32_t] ran_ue_ngap_id: RAN UE NGAP ID
* @param [long] amf_ue_ngap_id: AMF UE NGAP ID
* @return void
*/
void handle_ue_registration_state_change(
std::string supi, uint8_t status, uint8_t http_version);
std::string supi, uint8_t status, uint8_t http_version,
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id);
/*
* Handle the UE Connectivity State Change event to trigger the notification
......@@ -813,7 +819,32 @@ class amf_n1 {
void handle_ue_connectivity_state_change(
std::string supi, uint8_t status, uint8_t http_version);
private:
/*
* Handle the UE Loss of Connectivity Change event to trigger the notification
* to the subscribed NFs
* @param [std::string] supi: SUPI
* @param [uint8_t] status: UE Loss of Connectivity status
* @param [uint8_t] http_version: HTTP version (for the notification)
* @param [uint32_t] ran_ue_ngap_id: RAN UE NGAP ID
* @param [long] amf_ue_ngap_id: AMF UE NGAP ID
* @return void
*/
void handle_ue_loss_of_connectivity_change(
std::string supi, uint8_t status, uint8_t http_version,
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id);
/*
* Handle the UE Communication Failure event to trigger the notification to
* the subscribed NFs
* @param [std::string] supi: SUPI
* @param [oai::amf::model::CommunicationFailure] comm_failure: Communication
* Failure reason
* @param [uint8_t] http_version: HTTP version (for the notification)
* @return void
*/
void handle_ue_communication_failure_change(
std::string supi, oai::amf::model::CommunicationFailure,
uint8_t http_version);
/*
* Handle UE-initiated Deregistration Request message
* @param [const uint32_t] ran_ue_ngap_id: RAN UE NGAP ID
......@@ -958,6 +989,16 @@ class amf_n1 {
const uint8_t cause_value, const uint32_t ran_ue_ngap_id,
const long amf_ue_ngap_id);
// for Event Handling
amf_event event_sub;
bs2::connection ee_ue_location_report_connection;
bs2::connection ee_ue_reachability_status_connection;
bs2::connection ee_ue_registration_state_connection;
bs2::connection ee_ue_connectivity_state_connection;
bs2::connection ee_ue_loss_of_connectivity_connection;
bs2::connection ee_ue_communication_failure_connection;
private:
std::map<long, std::shared_ptr<nas_context>>
amfueid2nas_context; // amf ue ngap id
mutable std::shared_mutex m_amfueid2nas_context;
......@@ -973,14 +1014,7 @@ class amf_n1 {
static std::map<std::string, std::string> rand_record;
static uint8_t no_random_delta;
random_state_t random_state;
database_t* db_desc;
// for Event Handling
amf_event event_sub;
bs2::connection ee_ue_location_report_connection;
bs2::connection ee_ue_reachability_status_connection;
bs2::connection ee_ue_registration_state_connection;
bs2::connection ee_ue_connectivity_state_connection;
database_t db_desc;
};
} // namespace amf_application
......
This diff is collapsed.
......@@ -19,13 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_n2.hpp
\brief
\author Keliang DU (BUPT), Tien-Thinh NGUYEN (EURECOM)
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _AMF_N2_H_
#define _AMF_N2_H_
......@@ -36,6 +29,7 @@
#include "itti_msg_n2.hpp"
#include "ngap_app.hpp"
#include "ue_ngap_context.hpp"
#include "struct.hpp"
namespace amf_application {
......@@ -52,14 +46,22 @@ class amf_n2 : public ngap::ngap_app {
void handle_itti_message(itti_new_sctp_association& new_assoc);
/*
* Handle ITTI message (Downlink NAS Transfer)
* Handle ITTI message (NG Setup Request)
* @param [itti_downlink_nas_transfer&]: ITTI message
* @return void
*/
void handle_itti_message(itti_ng_setup_request& ngsetupreq);
void handle_itti_message(itti_ng_setup_request& ng_setup_req);
/*
* Handle ITTI message (Downlink NAS Transfer)
* Handle ITTI message (NG Setup Request)
* @param [std::shared_ptr<itti_ng_setup_request>]: ITTI message
* @return void
*/
void handle_itti_message(
std::shared_ptr<itti_ng_setup_request>& ng_setup_req);
/*
* Handle ITTI message (NG Reset)
* @param [itti_downlink_nas_transfer&]: ITTI message
* @return void
*/
......@@ -80,7 +82,7 @@ class amf_n2 : public ngap::ngap_app {
void handle_itti_message(itti_initial_ue_message& init_ue_msg);
/*
* Handle ITTI message (ULNASTransport)
* Handle ITTI message (UplinkNASTransport)
* @param [itti_ul_nas_transport&]: ITTI message
* @return void
*/
......@@ -204,14 +206,23 @@ class amf_n2 : public ngap::ngap_app {
/*
* Get list of common PLMN between AMF and gNB
* @param [const std::vector<SupportedItem_t>&] list: Supported TA list from
* @param [const std::vector<SupportedTaItem_t>&] list: Supported TA list from
* gNB
* @param [std::vector<SupportedItem_t>&] result: list of common TA
* @param [std::vector<SupportedTaItem_t>&] result: list of common TA
* @return true if there's at least 1 common TA, otherwise return false
*/
bool get_common_plmn(
const std::vector<SupportedItem_t>& list,
std::vector<SupportedItem_t>& result);
const std::vector<SupportedTaItem_t>& list,
std::vector<SupportedTaItem_t>& result);
/*
* Get list of common S-NSSAIs between AMF and gNB to be used by UE
* @param [const uint32_t&] ran_ue_ngap_id: RAN UE NGAP ID
* @param [std::vector<nas::SNSSAI_t>&] common_nssai: list of common S-NSSAIs
* @return void
*/
bool get_common_NSSAI(
const uint32_t& ran_ue_ngap_id, std::vector<nas::SNSSAI_t>& common_nssai);
/*
* Get UE NGAP context associated with a RAN UE NGAP ID
......@@ -228,6 +239,17 @@ class amf_n2 : public ngap::ngap_app {
*/
bool is_ran_ue_id_2_ue_ngap_context(const uint32_t& ran_ue_ngap_id) const;
/*
* Verify whether a UE NGAP context associated with a RAN UE NGAP ID exist
* @param [const uint32_t&] ran_ue_ngap_id: RAN UE NGAP ID
* @param [std::shared_ptr<ue_ngap_context>&] unc: shared pointer to the UE
* NGAP context
* @return true if exist, otherwise return false
*/
bool is_ran_ue_id_2_ue_ngap_context(
const uint32_t& ran_ue_ngap_id,
std::shared_ptr<ue_ngap_context>& unc) const;
/*
* Store UE NGAP context associated with a RAN UE NGAP ID
* @param [const uint32_t&] ran_ue_ngap_id: RAN UE NGAP ID
......@@ -269,6 +291,17 @@ class amf_n2 : public ngap::ngap_app {
bool is_amf_ue_id_2_ue_ngap_context(
const unsigned long& amf_ue_ngap_id) const;
/*
* Verify whether a UE NGAP context associated with a AMF UE NGAP ID exist
* @param [const unsigned long&] amf_ue_ngap_id: AMF UE NGAP ID
* @param [std::shared_ptr<ue_ngap_context>&] unc: store the pointer to UE
* NGAP context
* @return true if exist, otherwise return false
*/
bool is_amf_ue_id_2_ue_ngap_context(
const unsigned long& amf_ue_ngap_id,
std::shared_ptr<ue_ngap_context>& unc) const;
/*
* Store UE NGAP context associated with a AMF UE NGAP ID
* @param [const unsigned long&] amf_ue_ngap_id: AMF UE NGAP ID
......
......@@ -19,14 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_profile.cpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email: Tien-Thinh.Nguyen@eurecom.fr
*/
#include "amf_profile.hpp"
#include <boost/algorithm/string/classification.hpp>
......
......@@ -19,14 +19,6 @@
* contact@openairinterface.org
*/
/*! \file amf_profile.hpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2021
\email: Tien-Thinh.Nguyen@eurecom.fr
*/
#ifndef FILE_AMF_PROFILE_HPP_SEEN
#define FILE_AMF_PROFILE_HPP_SEEN
......@@ -85,6 +77,7 @@ class nf_profile : public std::enable_shared_from_this<nf_profile> {
return *this;
}
// nf_profile(nf_profile &b) = delete;
virtual ~nf_profile() {}
/*
* Set NF instance ID
......
......@@ -19,36 +19,27 @@
* contact@openairinterface.org
*/
/*! \file amf_n11.hpp
\brief
\author Keliang DU (BUPT), Tien-Thinh NGUYEN (EURECOM)
\date 2020
\email: contact@openairinterface.org
*/
#ifndef _AMF_N11_H_
#define _AMF_N11_H_
#ifndef _AMF_SBI_H_
#define _AMF_SBI_H_
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <map>
#include <shared_mutex>
#include <string>
#include "AuthenticationInfo.h"
#include "UEAuthenticationCtx.h"
#include "itti_msg_n11.hpp"
#include "itti_msg_sbi.hpp"
#include "pdu_session_context.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
namespace amf_application {
class amf_n11 {
class amf_sbi {
public:
amf_n11();
~amf_n11();
amf_sbi();
~amf_sbi();
/*
* Handle ITTI message (Nsmf_PDUSessionCreateSMContext) to create a new PDU
......@@ -90,34 +81,34 @@ class amf_n11 {
/*
* Handle ITTI message to get the Slice Selection Subscription Data from UDM
* @param [itti_n11_slice_selection_subscription_data&]: ITTI message
* @param [itti_sbi_slice_selection_subscription_data&]: ITTI message
* @return void
*/
void handle_itti_message(
itti_n11_slice_selection_subscription_data& itti_msg);
itti_sbi_slice_selection_subscription_data& itti_msg);
/*
* Handle ITTI message to get the Network Slice Selection Information from
* NSSF
* @param [itti_n11_network_slice_selection_information&]: ITTI message
* @param [itti_sbi_network_slice_selection_information&]: ITTI message
* @return void
*/
void handle_itti_message(
itti_n11_network_slice_selection_information& itti_msg);
itti_sbi_network_slice_selection_information& itti_msg);
/*
* Handle ITTI message to reroute N1 message to the targer AMF
* @param [itti_n11_n1_message_notify&]: ITTI message
* @param [itti_sbi_n1_message_notify&]: ITTI message
* @return void
*/
void handle_itti_message(itti_n11_n1_message_notify& itti_msg);
void handle_itti_message(itti_sbi_n1_message_notify& itti_msg);
/*
* Handle ITTI message to discover NF instance information from NRF
* @param [itti_n11_nf_instance_discovery&]: ITTI message
* @param [itti_sbi_nf_instance_discovery&]: ITTI message
* @return void
*/
void handle_itti_message(itti_n11_nf_instance_discovery& itti_msg);
void handle_itti_message(itti_sbi_nf_instance_discovery& itti_msg);
/*
* Handle request to create a new PDU Session
......@@ -151,25 +142,24 @@ class amf_n11 {
/*
* Handle ITTI message to register to NRF
* @param [itti_n11_register_nf_instance_request&]: ITTI message
* @param [itti_sbi_register_nf_instance_request&]: ITTI message
* @return void
*/
void register_nf_instance(
std::shared_ptr<itti_n11_register_nf_instance_request> msg);
std::shared_ptr<itti_sbi_register_nf_instance_request> msg);
/*
* Send the request to update PDU session context at SMF
* @param [const std::string&] supi: SUPI
* @param [std::shared_ptr<pdu_session_context>&] psc: Pointer to the PDU
* Session Context
* @param [const std::string&] smf_addr: SMF's Address
* @param [bstring] sm_msg: SM message
* @param [const std::string&] dnn: DNN
* @return void
*/
void send_pdu_session_update_sm_context_request(
const std::string& supi, std::shared_ptr<pdu_session_context>& psc,
const std::string& smf_addr, bstring sm_msg, const std::string& dnn);
bstring sm_msg, const std::string& dnn);
/*
* Select SMF from the configuration file
......
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.
......@@ -137,4 +137,8 @@ static const std::vector<std::string> n2_sm_info_type_e2str = {
"HANDOVER_REQ_ACK", "HANDOVER_RES_ALLOC_FAIL",
"SECONDARY_RAT_USAGE"};
#define NSMF_PDU_SESSION_CREATE "/sm-contexts"
#define NSMF_PDU_SESSION_MODIFY "/modify"
#define NSMF_PDU_SESSION_RELEASE "/release"
#endif
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.
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.
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.
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.
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