Commit 5c6ad314 authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'origin/develop' into mu_with_tdd1

The monolithic eNodeB is not fully functional in FDD.

The TDD mode has not been tested.

Do not consider this commit as functional.

Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/build_oai
	common/utils/itti/intertask_interface.c
	openair1/PHY/INIT/lte_init.c
	openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
	openair1/PHY/LTE_TRANSPORT/dci_tools.c
	openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
	openair1/PHY/LTE_TRANSPORT/transport_eNB.h
	openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
	openair1/PHY/defs_eNB.h
	openair1/PHY/impl_defs_lte.h
	openair1/SCHED/fapi_l1.c
	openair1/SCHED/phy_procedures_lte_eNb.c
	openair1/SCHED/pusch_pc.c
	openair2/COMMON/platform_types.h
	openair2/COMMON/rrc_messages_types.h
	openair2/ENB_APP/enb_config.c
	openair2/ENB_APP/enb_paramdef.h
	openair2/LAYER2/MAC/config.c
	openair2/LAYER2/MAC/eNB_scheduler.c
	openair2/LAYER2/MAC/eNB_scheduler_RA.c
	openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
	openair2/LAYER2/MAC/eNB_scheduler_primitives.c
	openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
	openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c
	openair2/LAYER2/MAC/mac.h
	openair2/LAYER2/MAC/mac_proto.h
	openair2/LAYER2/MAC/pre_processor.c
	openair2/LAYER2/RLC/rlc.c
	openair2/LAYER2/RLC/rlc_rrc.c
	openair2/RRC/LITE/rrc_common.c
	openair2/RRC/LTE/L2_interface.c
	openair2/RRC/LTE/MESSAGES/asn1_msg.c
	openair2/RRC/LTE/rrc_eNB.c
	openair2/UTIL/LOG/log.h
	targets/COMMON/openairinterface5g_limits.h
	targets/RT/USER/lte-enb.c
	targets/RT/USER/lte-ru.c
	targets/RT/USER/lte-softmodem.c
	targets/RT/USER/lte-softmodem.h
parents a3329b56 3fd24705
This diff is collapsed.
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
Active_eNBs = ( "eNB_Eurecom_LTEBox"); Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying # Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none"; Asn1_verbosity = "none";
...@@ -10,7 +10,7 @@ eNBs = ...@@ -10,7 +10,7 @@ eNBs =
cell_type = "CELL_MACRO_ENB"; cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox"; eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values // Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1"; tracking_area_code = "1";
......
...@@ -13,7 +13,7 @@ class connection: ...@@ -13,7 +13,7 @@ class connection:
try: try:
(pid, fd) = os.forkpty() (pid, fd) = os.forkpty()
except BaseException, e: except BaseException, e:
log("ERROR: forkpty for '" + description + "': " + e) log("ERROR: forkpty for '" + description + "': " + str(e))
(pid, fd) = (-1, -1) (pid, fd) = (-1, -1)
if pid == -1: if pid == -1:
...@@ -26,7 +26,7 @@ class connection: ...@@ -26,7 +26,7 @@ class connection:
os.execvp('sshpass', ['sshpass', '-p', password, os.execvp('sshpass', ['sshpass', '-p', password,
'ssh', user + '@' + host]) 'ssh', user + '@' + host])
except BaseException, e: except BaseException, e:
log("ERROR: execvp for '" + description + "': " + e) log("ERROR: execvp for '" + description + "': " + str(e))
log("ERROR: execvp failed for '" + description + "'") log("ERROR: execvp failed for '" + description + "'")
os._exit(1) os._exit(1)
......
This diff is collapsed.
...@@ -8,5 +8,5 @@ set(DEBUG_PHY False) ...@@ -8,5 +8,5 @@ set(DEBUG_PHY False)
set(MU_RECIEVER False) set(MU_RECIEVER False)
set(NAS_UE False) set(NAS_UE False)
set(MESSAGE_CHART_GENERATOR False) set(MESSAGE_CHART_GENERATOR False)
set(RRC_ASN1_VERSION "Rel14")
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt) include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
...@@ -30,7 +30,7 @@ set ( MESSAGE_CHART_GENERATOR_RLC_MAC False ) ...@@ -30,7 +30,7 @@ set ( MESSAGE_CHART_GENERATOR_RLC_MAC False )
set ( MESSAGE_CHART_GENERATOR_PHY False ) set ( MESSAGE_CHART_GENERATOR_PHY False )
set ( MSG_PRINT False ) set ( MSG_PRINT False )
set ( MU_RECEIVER False ) set ( MU_RECEIVER False )
set ( NAS_ADDRESS_FIX True ) set ( NAS_ADDRESS_FIX False )
set ( NAS_BUILT_IN_UE False) set ( NAS_BUILT_IN_UE False)
set ( NAS_MME False ) set ( NAS_MME False )
set ( NAS_UE False ) set ( NAS_UE False )
......
...@@ -95,6 +95,7 @@ get_distribution_release() { ...@@ -95,6 +95,7 @@ get_distribution_release() {
check_supported_distribution() { check_supported_distribution() {
local distribution=$(get_distribution_release) local distribution=$(get_distribution_release)
case "$distribution" in case "$distribution" in
"ubuntu18.04") return 0 ;;
"ubuntu17.10") return 0 ;; "ubuntu17.10") return 0 ;;
"ubuntu17.04") return 0 ;; "ubuntu17.04") return 0 ;;
"ubuntu16.04") return 0 ;; "ubuntu16.04") return 0 ;;
...@@ -210,7 +211,7 @@ install_protobuf_from_source(){ ...@@ -210,7 +211,7 @@ install_protobuf_from_source(){
#cd protobuf-2.6.1/ #cd protobuf-2.6.1/
rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $USER --no-same-owner tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner
cd protobuf-3.3.0/ cd protobuf-3.3.0/
./configure ./configure
echo "Compiling protobuf" echo "Compiling protobuf"
...@@ -249,14 +250,14 @@ install_usrp_uhd_driver_from_source(){ ...@@ -249,14 +250,14 @@ install_usrp_uhd_driver_from_source(){
cd /tmp cd /tmp
echo "Downloading UHD driver" echo "Downloading UHD driver"
rm -rf /tmp/uhd rm -rf /tmp/uhd
git clone git://github.com/EttusResearch/uhd.git git clone https://github.com/EttusResearch/uhd.git
cd uhd cd uhd
git checkout tags/release_003_010_001_001 git checkout tags/release_003_010_001_001
mkdir -p host/build mkdir -p host/build
cd host/build cd host/build
$CMAKE ../ $CMAKE ../
echo "Compiling UHD" echo "Compiling UHD"
make make -j`nproc`
make test make test
$SUDO make install $SUDO make install
$SUDO ldconfig $SUDO ldconfig
...@@ -267,7 +268,7 @@ check_install_usrp_uhd_driver(){ ...@@ -267,7 +268,7 @@ check_install_usrp_uhd_driver(){
if [[ "$OS_DISTRO" == "ubuntu" ]]; then if [[ "$OS_DISTRO" == "ubuntu" ]]; then
#first we remove old installation #first we remove old installation
$SUDO apt-get remove -y uhd || true $SUDO apt-get remove -y uhd || true
$SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y $SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y || true
v=$(lsb_release -cs) v=$(lsb_release -cs)
$SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main" $SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main"
#The new USRP repository #The new USRP repository
...@@ -277,10 +278,11 @@ check_install_usrp_uhd_driver(){ ...@@ -277,10 +278,11 @@ check_install_usrp_uhd_driver(){
$SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
$SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake
$SUDO pip install requests
if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
# until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source
$SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware
install_ursp_uhd_driver_from_source install_usrp_uhd_driver_from_source
else else
$SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware $SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware
fi fi
...@@ -487,19 +489,24 @@ check_install_oai_software() { ...@@ -487,19 +489,24 @@ check_install_oai_software() {
$SUDO apt install -y software-properties-common $SUDO apt install -y software-properties-common
case "$(get_distribution_release)" in case "$(get_distribution_release)" in
"ubuntu14.04") "ubuntu14.04")
specific_packages="libtasn1-3-dev gccxml libgnutls-dev libatlas-dev" specific_packages="libtasn1-3-dev gccxml libgnutls-dev libatlas-dev iproute libconfig8-dev"
# For iperf3 # For iperf3
$SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe" $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe"
$SUDO apt-get update $SUDO apt-get update
;; ;;
"ubuntu16.04") "ubuntu16.04")
specific_packages="libtasn1-6-dev gccxml libgnutls-dev libatlas-dev" specific_packages="libtasn1-6-dev gccxml libgnutls-dev libatlas-dev iproute libconfig8-dev"
;; ;;
"ubuntu17.04") "ubuntu17.04")
specific_packages="libtasn1-6-dev castxml libgnutls28-dev libatlas-dev" specific_packages="libtasn1-6-dev castxml libgnutls28-dev libatlas-dev iproute libconfig8-dev"
;; ;;
"ubuntu17.10") "ubuntu17.10")
specific_packages="libtasn1-6-dev castxml libgnutls28-dev" specific_packages="libtasn1-6-dev castxml libgnutls28-dev iproute libconfig8-dev"
LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
;;
"ubuntu18.04")
specific_packages="libtasn1-6-dev castxml libgnutls28-dev iproute2 libconfig-dev"
LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
;; ;;
...@@ -523,12 +530,10 @@ check_install_oai_software() { ...@@ -523,12 +530,10 @@ check_install_oai_software() {
gtkwave \ gtkwave \
guile-2.0-dev \ guile-2.0-dev \
iperf \ iperf \
iproute \
iptables \ iptables \
iptables-dev \ iptables-dev \
libatlas-base-dev \ libatlas-base-dev \
libblas-dev \ libblas-dev \
libconfig8-dev \
libffi-dev \ libffi-dev \
libforms-bin \ libforms-bin \
libforms-dev \ libforms-dev \
...@@ -644,7 +649,8 @@ check_install_oai_software() { ...@@ -644,7 +649,8 @@ check_install_oai_software() {
lapack \ lapack \
lapack-devel \ lapack-devel \
blas \ blas \
blas-devel blas-devel \
libyaml-devel
fi fi
install_asn1c_from_source install_asn1c_from_source
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
RRC_Rel14=( RRC_Rel14=(
"SystemInformation-r8-IEs.h" 4df485c5ddf2540eca271876cdc512caa19b0890 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff" "SystemInformation-r8-IEs.h" 4df485c5ddf2540eca271876cdc512caa19b0890 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff"
"SystemInformation-NB-r13-IEs.h" 6d91332d5c39205819b06e5e36efe62ff8e5b33b "fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff"
) )
RRC_Rel10=( RRC_Rel10=(
......
48a49,70
> struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member {
> SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present;
> union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u {
> SystemInformationBlockType2_NB_r13_t sib2_r13;
> SystemInformationBlockType3_NB_r13_t sib3_r13;
> SystemInformationBlockType4_NB_r13_t sib4_r13;
> SystemInformationBlockType5_NB_r13_t sib5_r13;
> SystemInformationBlockType14_NB_r13_t sib14_r13;
> SystemInformationBlockType16_NB_r13_t sib16_r13;
> /*
> * This type is extensible,
> * possible extensions are below.
> */
> SystemInformationBlockType15_NB_r14_t sib15_v1430;
> SystemInformationBlockType20_NB_r14_t sib20_v1430;
> SystemInformationBlockType22_NB_r14_t sib22_v1430;
> } choice;
>
> /* Context for parsing across buffer boundaries */
> asn_struct_ctx_t _asn_ctx;
> };
>
52,72c74
< A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member {
< SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present;
< union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u {
< SystemInformationBlockType2_NB_r13_t sib2_r13;
< SystemInformationBlockType3_NB_r13_t sib3_r13;
< SystemInformationBlockType4_NB_r13_t sib4_r13;
< SystemInformationBlockType5_NB_r13_t sib5_r13;
< SystemInformationBlockType14_NB_r13_t sib14_r13;
< SystemInformationBlockType16_NB_r13_t sib16_r13;
< /*
< * This type is extensible,
< * possible extensions are below.
< */
< SystemInformationBlockType15_NB_r14_t sib15_v1430;
< SystemInformationBlockType20_NB_r14_t sib20_v1430;
< SystemInformationBlockType22_NB_r14_t sib22_v1430;
< } choice;
<
< /* Context for parsing across buffer boundaries */
< asn_struct_ctx_t _asn_ctx;
< } ) list;
---
> A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member) list;
...@@ -44,11 +44,11 @@ load_module $OPENAIR_DIR/targets/bin/nasmesh.ko ...@@ -44,11 +44,11 @@ load_module $OPENAIR_DIR/targets/bin/nasmesh.ko
if [ "$1" = "eNB" ]; then if [ "$1" = "eNB" ]; then
echo "bring up oai0 interface for enb" echo "bring up oai0 interface for enb"
sudo ifconfig oai0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255 sudo ifconfig oai0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255
$OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.9 -r 1 $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.2 -r 1
else else
if [ "$1" = "UE" ]; then if [ "$1" = "UE" ]; then
echo "bring up oai0 interface for UE" echo "bring up oai0 interface for UE"
sudo ifconfig oai0 10.0.1.9 netmask 255.255.255.0 broadcast 10.0.1.255 sudo ifconfig oai0 10.0.1.9 netmask 255.255.255.0 broadcast 10.0.1.255
$OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.9 -t 10.0.1.1 -r 1 $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.2 -t 10.0.1.1 -r 1
fi fi
fi fi
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -197,25 +197,40 @@ int i; ...@@ -197,25 +197,40 @@ int i;
return cfgptr; return cfgptr;
} }
void end_configmodule()
/* free memory allocated when reading parameters */
/* config module could be initialized again after this call */
void end_configmodule(void)
{ {
if (cfgptr != NULL) { if (cfgptr != NULL) {
if (cfgptr->end != NULL) { if (cfgptr->end != NULL) {
printf ("[CONFIG] calling config module end function...\n"); printf ("[CONFIG] calling config module end function...\n");
cfgptr->end(); cfgptr->end();
} }
if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP);
for (int i=0; i<cfgptr->num_cfgP; i++) {
if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]);
}
printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs);
for(int i=0; i<cfgptr->numptrs ; i++) { for(int i=0; i<cfgptr->numptrs ; i++) {
if (cfgptr->ptrs[i] != NULL) { if (cfgptr->ptrs[i] != NULL) {
free(cfgptr->ptrs[i]); free(cfgptr->ptrs[i]);
cfgptr->ptrs[i]=NULL;
} }
cfgptr->ptrs[i]=NULL;
} }
cfgptr->numptrs=0;
}
}
/* free all memory used by config module */
/* should be called only at program exit */
void free_configmodule(void)
{
if (cfgptr != NULL) {
end_configmodule();
if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP);
for (int i=0; i<cfgptr->num_cfgP; i++) {
if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]);
}
free(cfgptr); free(cfgptr);
cfgptr=NULL; cfgptr=NULL;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -40,15 +40,18 @@ ...@@ -40,15 +40,18 @@
#define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2... #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2...
#define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module #define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module
/* rtflags bit position definitions */ /* default values for configuration module parameters */
#define CONFIG_PRINTPARAMS 1 // print parameters values while processing #define DEFAULT_CFGMODE "libconfig" // use libconfig file
#define CONFIG_DEBUGPTR 2 // print memory allocation/free debug messages #define DEFAULT_CFGFILENAME "oai.conf" // default config file
#define CONFIG_DEBUGCMDLINE 4 // print command line processing messages
#define CONFIG_HELP 8 // print help message
#define CONFIG_ABORT 16 // config failed,abort execution
#define CONFIG_NOOOPT 32 // no -O option found when parsing command line
/* rtflags bit position definitions */
#define CONFIG_PRINTPARAMS 1 // print parameters values while processing
#define CONFIG_DEBUGPTR 1<<1 // print memory allocation/free debug messages
#define CONFIG_DEBUGCMDLINE 1<<2 // print command line processing messages
#define CONFIG_NOABORTONCHKF 1<<3 // disable abort execution when parameter checking function fails
#define CONFIG_HELP 1<<20 // print help message
#define CONFIG_ABORT 1<<21 // config failed,abort execution
#define CONFIG_NOOOPT 1<<22 // no -O option found when parsing command line
typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP); typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP);
typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix); typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix);
typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix); typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -55,16 +55,61 @@ ...@@ -55,16 +55,61 @@
#define PARAMFLAG_PARAMSET (1 << 16) // parameter has been explicitely set in get functions #define PARAMFLAG_PARAMSET (1 << 16) // parameter has been explicitely set in get functions
#define PARAMFLAG_PARAMSETDEF (1 << 17) // parameter has been set to default value in get functions #define PARAMFLAG_PARAMSETDEF (1 << 17) // parameter has been set to default value in get functions
/* checkedparam_t is possibly used in paramdef_t for specific parameter value validation */
#define CONFIG_MAX_NUMCHECKVAL 20
typedef struct paramdef paramdef_t;
typedef union checkedparam {
struct {
int (*f1)(paramdef_t *param); /* check an integer against a list of authorized values */
int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values */
int num_okintval; /* number of valid values in the checkingval array */
} s1;
struct {
int (*f1a)(paramdef_t *param); /* check an integer against a list of authorized values and set param value */
/* to the corresponding item in setintval array (mainly for RRC params) */
int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values in config file */
int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */
int num_okintval; /* number of valid values in the checkingval array */
} s1a;
struct {
int (*f2)(paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */
int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */
} s2;
struct {
int (*f3)(paramdef_t *param); /* check a string against a list of authorized values */
char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */
int num_okstrval; /* number of valid values in the checkingval array */
} s3;
struct {
int (*f3a)(paramdef_t *param); /* check a string against a list of authorized values and set param value */
/* to the corresponding item in setintval array (mainly for RRC params) */
char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */
int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */
int num_okstrval; /* number of valid values in the checkingval array */
} s3a;
struct {
int (*f4)(paramdef_t *param); /* generic check function, no arguments but the param description */
} s4;
struct {
void (*checkfunc)(void) ;
} s5;
} checkedparam_t;
/* paramdef is used to describe a parameter, array of paramdef_t strustures is used as the main parameter in */
/* config apis used to retrieve parameters values */
typedef struct paramdef typedef struct paramdef
{ {
char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */
char *helpstr; /* help string */ char *helpstr; /* help string */
unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */
union { /* pointer to the parameter value, completed by the config module */ union { /* pointer to the parameter value, completed by the config module */
char **strptr; char **strptr;
char **strlistptr; char **strlistptr;
uint8_t *u8ptr; uint8_t *u8ptr;
char *i8ptr; int8_t *i8ptr;
uint16_t *u16ptr; uint16_t *u16ptr;
int16_t *i16ptr; int16_t *i16ptr;
uint32_t *uptr; uint32_t *uptr;
...@@ -72,18 +117,21 @@ typedef struct paramdef ...@@ -72,18 +117,21 @@ typedef struct paramdef
uint64_t *u64ptr; uint64_t *u64ptr;
int64_t *i64ptr; int64_t *i64ptr;
double *dblptr; double *dblptr;
void *voidptr;
} ; } ;
union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */
char *defstrval; char *defstrval;
char **defstrlistval; char **defstrlistval;
uint32_t defuintval; uint32_t defuintval;
int defintval; int defintval;
uint64_t defint64val; uint64_t defint64val;
int *defintarrayval; int *defintarrayval;
double defdblval; double defdblval;
} ; } ;
char type; /* parameter value type, as listed below as TYPE_XXXX macro */ char type; /* parameter value type, as listed below as TYPE_XXXX macro */
int numelt; /* number of elements in a list or array parameters or max size of string value */ int numelt; /* number of elements in a list or array parameters or max size of string value */
checkedparam_t *chkPptr; /* possible pointer to the structure containing the info used to check parameter values */
int *processedvalue; /* used to store integer values computed from string original value */
} paramdef_t; } paramdef_t;
#define TYPE_INT TYPE_INT32 #define TYPE_INT TYPE_INT32
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <errno.h> #include <errno.h>
#include <dlfcn.h> #include <dlfcn.h>
#include "config_userapi.h" #include "config_userapi.h"
extern void exit_fun(const char* s); // lte-softmodem clean exit function
configmodule_interface_t *config_get_if(void) configmodule_interface_t *config_get_if(void)
...@@ -59,7 +60,7 @@ char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ...@@ -59,7 +60,7 @@ char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length)
*ptr = malloc(length); *ptr = malloc(length);
if ( *ptr != NULL) { if ( *ptr != NULL) {
memset(*ptr,0,length); memset(*ptr,0,length);
if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) != 0) { if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) {
config_get_if()->ptrs[config_get_if()->numptrs] = *ptr; config_get_if()->ptrs[config_get_if()->numptrs] = *ptr;
config_get_if()->numptrs++; config_get_if()->numptrs++;
} }
...@@ -111,7 +112,29 @@ int tmpval=val; ...@@ -111,7 +112,29 @@ int tmpval=val;
break; break;
} }
} }
void config_assign_processedint(paramdef_t *cfgoption, int val) {
cfgoption->processedvalue = malloc(sizeof(int));
if ( cfgoption->processedvalue != NULL) {
*(cfgoption->processedvalue) = val;
} else {
fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
exit(-1);
}
}
int config_get_processedint(paramdef_t *cfgoption) {
int ret;
if ( cfgoption->processedvalue != NULL) {
ret=*(cfgoption->processedvalue);
free( cfgoption->processedvalue);
cfgoption->processedvalue=NULL;
printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret);
} else {
fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname);
ret=0;
}
return ret;
}
void config_printhelp(paramdef_t *params,int numparams) void config_printhelp(paramdef_t *params,int numparams)
{ {
for (int i=0 ; i<numparams ; i++) { for (int i=0 ; i<numparams ; i++) {
...@@ -124,11 +147,31 @@ void config_printhelp(paramdef_t *params,int numparams) ...@@ -124,11 +147,31 @@ void config_printhelp(paramdef_t *params,int numparams)
} }
} }
int config_execcheck(paramdef_t *params,int numparams, char *prefix)
{
int st=0;
for (int i=0 ; i<numparams ; i++) {
if ( params[i].chkPptr == NULL) {
continue;
}
if (params[i].chkPptr->s4.f4 != NULL) {
st += params[i].chkPptr->s4.f4(&(params[i]));
}
}
if (st != 0) {
fprintf(stderr,"[CONFIG] config_execcheck: %i parameters with wrong value\n", -st);
if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) {
exit_fun("exit because configuration failed\n");
}
}
return st;
}
int config_get(paramdef_t *params,int numparams, char *prefix) int config_get(paramdef_t *params,int numparams, char *prefix)
{ {
int ret= -1; int ret= -1;
printf("numparams:%d prefix:%s\n", numparams, prefix);
if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n");
return ret; return ret;
...@@ -138,6 +181,7 @@ configmodule_interface_t *cfgif = config_get_if(); ...@@ -138,6 +181,7 @@ configmodule_interface_t *cfgif = config_get_if();
ret = config_get_if()->get(params, numparams,prefix); ret = config_get_if()->get(params, numparams,prefix);
if (ret >= 0) { if (ret >= 0) {
config_process_cmdline(params,numparams,prefix); config_process_cmdline(params,numparams,prefix);
config_execcheck(params,numparams,prefix);
} }
return ret; return ret;
} }
...@@ -153,6 +197,89 @@ int config_isparamset(paramdef_t *params,int paramidx) ...@@ -153,6 +197,89 @@ int config_isparamset(paramdef_t *params,int paramidx)
} }
} }
int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx) { void print_intvalueerror(paramdef_t *param, char *fname, int *okval, int numokval) {
fprintf(stderr,"[CONFIG] %s: %s: %i invalid value, authorized values:\n ",
fname,param->optname, (int)*(param->uptr));
for ( int i=0; i<numokval ; i++) {
fprintf(stderr, " %i",okval[i]);
}
fprintf(stderr, " \n");
}
int config_check_intval(paramdef_t *param)
{
if ( param == NULL ){
fprintf(stderr,"[CONFIG] config_check_intval: NULL param argument\n");
return -1;
}
for ( int i=0; i<param->chkPptr->s1.num_okintval ; i++) {
if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) {
return 0;
}
}
print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval);
return -1;
}
int config_check_modify_integer(paramdef_t *param)
{
for (int i=0; i < param->chkPptr->s1a.num_okintval ; i++) {
if (*(param->uptr) == param->chkPptr->s1a.okintval[i] ) {
printf_params("[CONFIG] %s: read value %i, set to %i\n",param->optname,*(param->uptr),param->chkPptr->s1a.setintval [i]);
*(param->uptr) = param->chkPptr->s1a.setintval [i];
return 0;
}
}
print_intvalueerror(param,"config_check_modify_integer", param->chkPptr->s1a.okintval,param->chkPptr->s1a.num_okintval);
return -1;
}
int config_check_intrange(paramdef_t *param)
{
if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) {
return 0;
}
fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n",
param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]);
return -1;
}
void print_strvalueerror(paramdef_t *param, char *fname, char **okval, int numokval) {
fprintf(stderr,"[CONFIG] %s: %s: %s invalid value, authorized values:\n ",
fname,param->optname, *(param->strptr));
for ( int i=0; i<numokval ; i++) {
fprintf(stderr, " %s",okval[i]);
}
fprintf(stderr, " \n");
}
int config_check_strval(paramdef_t *param)
{
if ( param == NULL ){
fprintf(stderr,"[CONFIG] config_check_strval: NULL param argument\n");
return -1;
}
for ( int i=0; i<param->chkPptr->s3.num_okstrval ; i++) {
if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) {
return 0;
}
}
print_strvalueerror(param, "config_check_strval", param->chkPptr->s3.okstrval, param->chkPptr->s3.num_okstrval);
return -1;
}
int config_checkstr_assign_integer(paramdef_t *param)
{
for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) {
if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) {
config_assign_processedint(param, param->chkPptr->s3a.setintval[i]);
return 0;
}
}
print_strvalueerror(param, "config_check_strval", param->chkPptr->s3a.okstrval, param->chkPptr->s3a.num_okstrval);
return -1; return -1;
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -38,24 +38,34 @@ ...@@ -38,24 +38,34 @@
extern "C" extern "C"
{ {
#endif #endif
#define DEFAULT_CFGFILENAME "oaisoftmodem.conf"
#define DEFAULT_CFGMODE "libconfig"
#define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode )
#define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP )
#define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] )
#define CONFIG_ISFLAGSET(P) ( (config_get_if()==NULL) ? 0 : !!(config_get_if()->rtflags & P)) #define CONFIG_ISFLAGSET(P) ( (config_get_if()==NULL) ? 0 : !!(config_get_if()->rtflags & P))
#define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F))
/* utility functions, to be used by configuration module and/or configuration libraries */
extern configmodule_interface_t *config_get_if(void); extern configmodule_interface_t *config_get_if(void);
extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
extern void config_printhelp(paramdef_t *,int numparams); extern void config_printhelp(paramdef_t *,int numparams);
extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix); extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix);
extern int config_get(paramdef_t *params,int numparams, char *prefix); extern void config_assign_processedint(paramdef_t *cfgoption, int val);
extern int config_isparamset(paramdef_t *params,int paramidx);
extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val); extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val);
extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix);
extern int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx); /* apis to get parameters, to be used by oai modules, at configuration time */
extern int config_get(paramdef_t *params,int numparams, char *prefix);
#define config_getlist config_get_if()->getlist #define config_getlist config_get_if()->getlist
/* apis to retrieve parameters info after calling get or getlist functions */
extern int config_isparamset(paramdef_t *params,int paramidx);
extern int config_get_processedint(paramdef_t *cfgoption);
/* functions to be used in parameters definition, to check parameters values */
extern int config_check_intval(paramdef_t *param);
extern int config_check_modify_integer(paramdef_t *param);
extern int config_check_intrange(paramdef_t *param);
extern int config_check_strval(paramdef_t *param);
extern int config_checkstr_assign_integer(paramdef_t *param);
#define CONFIG_GETCONFFILE (config_get_if()->cfgP[0]) #define CONFIG_GETCONFFILE (config_get_if()->cfgP[0])
#ifdef __cplusplus #ifdef __cplusplus
......
/*
* 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 common/config/libconfig/config_libconfig.c
* \brief: implementation libconfig configuration library
* \author Francois TABURET
* \date 2017
* \version 0.1
* \company NOKIA BellLabs France
* \email: francois.taburet@nokia-bell-labs.com
* \note
* \warning
*/
#define _GNU_SOURCE #define _GNU_SOURCE
#include <libconfig.h> #include <libconfig.h>
...@@ -21,21 +51,23 @@ int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath ...@@ -21,21 +51,23 @@ int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath
{ {
const char *str; const char *str;
int st; int st;
int numelt;
cfgoptions->numelt=config_setting_length(setting); numelt=config_setting_length(setting);
cfgoptions->strlistptr=malloc(sizeof(char *) * (cfgoptions->numelt)); config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt);
st=0; st=0;
for (int i=0; i< cfgoptions->numelt && cfgoptions->strlistptr != NULL; i++) { for (int i=0; i< numelt ; i++) {
str=config_setting_get_string_elem(setting,i); str=config_setting_get_string_elem(setting,i);
if (str==NULL) { if (str==NULL) {
printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i); printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i);
} else { } else {
cfgoptions->strlistptr[i]=malloc(strlen(str)+1); config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1);
sprintf(cfgoptions->strlistptr[i],"%s",str); sprintf(cfgoptions->strlistptr[i],"%s",str);
st++; st++;
printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]); printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]);
} }
} }
cfgoptions->numelt=numelt;
return st; return st;
} }
...@@ -98,6 +130,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) ...@@ -98,6 +130,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
{ {
case TYPE_STRING: case TYPE_STRING:
printf("call config_lookup_string for '%s' %p\n", cfgpath, &(libconfig_privdata.cfg)); fflush(stdout);
if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) { if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) {
fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n", fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n",
...@@ -108,10 +141,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) ...@@ -108,10 +141,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
sprintf( *(cfgoptions[i].strptr) , "%s", str); sprintf( *(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) ); printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) );
} else { } else {
sprintf( (char *)(cfgoptions[i].strptr) , "%s", str); sprintf( (char *)(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: %s\n", cfgpath,(char *)cfgoptions[i].strptr ); printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr );
} }
} else { } else {
if( cfgoptions[i].defstrval != NULL) { if( cfgoptions[i].defstrval != NULL) {
...@@ -121,10 +154,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) ...@@ -121,10 +154,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr)); printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, *(cfgoptions[i].strptr));
} else { } else {
sprintf((char *)(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); sprintf((char *)*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, (char *)cfgoptions[i].strptr); printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, (char *)*(cfgoptions[i].strptr));
} }
} else { } else {
notfound=1; notfound=1;
...@@ -374,6 +407,7 @@ void config_libconfig_end(void ) ...@@ -374,6 +407,7 @@ void config_libconfig_end(void )
config_destroy(&(libconfig_privdata.cfg)); config_destroy(&(libconfig_privdata.cfg));
if ( libconfig_privdata.configfile != NULL ) { if ( libconfig_privdata.configfile != NULL ) {
free(libconfig_privdata.configfile); free(libconfig_privdata.configfile);
libconfig_privdata.configfile=NULL;
} }
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -35,11 +35,12 @@ ...@@ -35,11 +35,12 @@
#include <pthread.h> #include <pthread.h>
#include "COMMON/platform_constants.h" #include "COMMON/platform_constants.h"
#include "PHY/defs.h" #include "PHY/defs_eNB.h"
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/impl_defs_top.h" #include "PHY/impl_defs_top.h"
#include "PHY/impl_defs_lte.h" #include "PHY/impl_defs_lte.h"
#include "RRC/LITE/defs.h" #include "RRC/LTE/rrc_defs.h"
#include "flexran_agent_defs.h"
#include "gtpv1u.h" #include "gtpv1u.h"
#include "NwGtpv1u.h" #include "NwGtpv1u.h"
...@@ -47,6 +48,8 @@ ...@@ -47,6 +48,8 @@
#include "NwGtpv1uPrivate.h" #include "NwGtpv1uPrivate.h"
#include "gtpv1u_eNB_defs.h" #include "gtpv1u_eNB_defs.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "RRC/LTE/defs_NB_IoT.h"
typedef struct { typedef struct {
/// RAN context config file name /// RAN context config file name
char *config_file_name; char *config_file_name;
...@@ -54,22 +57,36 @@ typedef struct { ...@@ -54,22 +57,36 @@ typedef struct {
int nb_inst; int nb_inst;
/// Number of Component Carriers per instance in this node /// Number of Component Carriers per instance in this node
int *nb_CC; int *nb_CC;
/// Number of NB_IoT instances in this node
int nb_nb_iot_rrc_inst;
/// Number of MACRLC instances in this node /// Number of MACRLC instances in this node
int nb_macrlc_inst; int nb_macrlc_inst;
/// Number of NB_IoT MACRLC instances in this node
int nb_nb_iot_macrlc_inst;
/// Number of component carriers per instance in this node /// Number of component carriers per instance in this node
int *nb_mac_CC; int *nb_mac_CC;
/// Number of L1 instances in this node /// Number of L1 instances in this node
int nb_L1_inst; int nb_L1_inst;
/// Number of NB_IoT L1 instances in this node
int nb_nb_iot_L1_inst;
/// Number of Component Carriers per instance in this node /// Number of Component Carriers per instance in this node
int *nb_L1_CC; int *nb_L1_CC;
/// Number of RU instances in this node /// Number of RU instances in this node
int nb_RU; int nb_RU;
/// FlexRAN context variables
flexran_agent_info_t **flexran;
/// eNB context variables /// eNB context variables
struct PHY_VARS_eNB_s ***eNB; struct PHY_VARS_eNB_s ***eNB;
/// NB_IoT L1 context variables
struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT;
/// RRC context variables /// RRC context variables
struct eNB_RRC_INST_s **rrc; struct eNB_RRC_INST_s **rrc;
/// RRC context variables /// NB_IoT RRC context variables
//struct eNB_RRC_INST_NB_IoT_s **nb_iot_rrc;
/// MAC context variables
struct eNB_MAC_INST_s **mac; struct eNB_MAC_INST_s **mac;
/// NB_IoT MAC context variables
struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac;
/// GTPu descriptor /// GTPu descriptor
gtpv1u_data_t *gtpv1u_data_g; gtpv1u_data_t *gtpv1u_data_g;
/// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces
......
...@@ -88,7 +88,7 @@ static void new_thread(void *(*f)(void *), void *data) ...@@ -88,7 +88,7 @@ static void new_thread(void *(*f)(void *), void *data)
/* defined in local_tracer.c */ /* defined in local_tracer.c */
void T_local_tracer_main(int remote_port, int wait_for_tracer, void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket); int local_socket, char *shm_file);
/* We monitor the tracee and the local tracer processes. /* We monitor the tracee and the local tracer processes.
* When one dies we forcefully kill the other. * When one dies we forcefully kill the other.
...@@ -113,6 +113,9 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) ...@@ -113,6 +113,9 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
int s; int s;
int T_shm_fd; int T_shm_fd;
int child1, child2; int child1, child2;
char shm_file[128];
sprintf(shm_file, "/%s%d", T_SHM_FILENAME, getpid());
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
{ perror("socketpair"); abort(); } { perror("socketpair"); abort(); }
...@@ -122,7 +125,8 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) ...@@ -122,7 +125,8 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
child1 = fork(); if (child1 == -1) abort(); child1 = fork(); if (child1 == -1) abort();
if (child1 == 0) { if (child1 == 0) {
close(socket_pair[1]); close(socket_pair[1]);
T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]); T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0],
shm_file);
exit(0); exit(0);
} }
close(socket_pair[0]); close(socket_pair[0]);
...@@ -142,13 +146,13 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork) ...@@ -142,13 +146,13 @@ void T_init(int remote_port, int wait_for_tracer, int dont_fork)
T_socket = s; T_socket = s;
/* setup shared memory */ /* setup shared memory */
T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666); T_shm_fd = shm_open(shm_file, O_RDWR /*| O_SYNC*/, 0666);
shm_unlink(T_SHM_FILENAME); shm_unlink(shm_file);
if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); } if (T_shm_fd == -1) { perror(shm_file); abort(); }
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0); PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0);
if (T_cache == NULL) if (T_cache == MAP_FAILED)
{ perror(T_SHM_FILENAME); abort(); } { perror(shm_file); abort(); }
close(T_shm_fd); close(T_shm_fd);
new_thread(T_receive_thread, NULL); new_thread(T_receive_thread, NULL);
......
...@@ -110,6 +110,16 @@ typedef struct { ...@@ -110,6 +110,16 @@ typedef struct {
extern volatile int *T_freelist_head; extern volatile int *T_freelist_head;
extern T_cache_t *T_cache; extern T_cache_t *T_cache;
/* When running the basic simulator, we may fill the T cache too fast.
* Let's not crash if it's full, just wait.
*/
#if BASIC_SIMULATOR
# define T_BASIC_SIMULATOR_WAIT \
while (T_cache[T_LOCAL_slot].busy) usleep(100)
#else
# define T_BASIC_SIMULATOR_WAIT /* */
#endif
/* used at header of Tn, allocates buffer */ /* used at header of Tn, allocates buffer */
#define T_LOCAL_DATA \ #define T_LOCAL_DATA \
char *T_LOCAL_buf; \ char *T_LOCAL_buf; \
...@@ -118,6 +128,7 @@ extern T_cache_t *T_cache; ...@@ -118,6 +128,7 @@ extern T_cache_t *T_cache;
T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \ T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \
& (T_CACHE_SIZE - 1); \ & (T_CACHE_SIZE - 1); \
(void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \ (void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \
T_BASIC_SIMULATOR_WAIT; \
if (T_cache[T_LOCAL_slot].busy) { \ if (T_cache[T_LOCAL_slot].busy) { \
printf("%s:%d:%s: T cache is full - consider increasing its size\n", \ printf("%s:%d:%s: T cache is full - consider increasing its size\n", \
__FILE__, __LINE__, __FUNCTION__); \ __FILE__, __LINE__, __FUNCTION__); \
......
...@@ -8,10 +8,20 @@ ...@@ -8,10 +8,20 @@
#define T_MAX_ARGS 16 #define T_MAX_ARGS 16
/* maximum size of a message - increase if needed */ /* maximum size of a message - increase if needed */
#define T_BUFFER_MAX (1024*64) #if BASIC_SIMULATOR
/* let's have 100 RBs functional for the basic simulator */
# define T_BUFFER_MAX (1024*64*2)
#else
# define T_BUFFER_MAX (1024*64)
#endif
/* size of the local cache for messages (must be pow(2,something)) */ /* size of the local cache for messages (must be pow(2,something)) */
#define T_CACHE_SIZE (8192 * 2) #if BASIC_SIMULATOR
/* we don't need much space for the basic simulator */
# define T_CACHE_SIZE 1024
#else
# define T_CACHE_SIZE (8192 * 2)
#endif
/* maximum number of bytes a message can contain */ /* maximum number of bytes a message can contain */
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
...@@ -32,7 +42,7 @@ typedef struct { ...@@ -32,7 +42,7 @@ typedef struct {
#define VCD_NUM_FUNCTIONS 187 #define VCD_NUM_FUNCTIONS 187
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */ /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES 128 #define VCD_NUM_VARIABLES 131
/* first VCD function (to be kept up to date! see in T_messages.txt) */ /* first VCD function (to be kept up to date! see in T_messages.txt) */
#define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
......
...@@ -1442,6 +1442,18 @@ ID = VCD_VARIABLE_UE0_TRX_WRITE_NS_MISSING ...@@ -1442,6 +1442,18 @@ ID = VCD_VARIABLE_UE0_TRX_WRITE_NS_MISSING
DESC = VCD variable UE0_TRX_WRITE_NS_MISSING DESC = VCD variable UE0_TRX_WRITE_NS_MISSING
GROUP = ALL:VCD:UE:VCD_VARIABLE GROUP = ALL:VCD:UE:VCD_VARIABLE
FORMAT = ulong,value FORMAT = ulong,value
ID = VCD_VARIABLE_CPUID_ENB_THREAD_RXTX
DESC = VCD variable CPUID_ENB_THREAD_RXTX
GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value
ID = VCD_VARIABLE_CPUID_RU_THREAD
DESC = VCD variable CPUID_RU_THREAD
GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value
ID = VCD_VARIABLE_CPUID_RU_THREAD_TX
DESC = VCD variable CPUID_RU_THREAD_TX
GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value
#functions #functions
......
...@@ -300,6 +300,20 @@ static void forward(void *_forwarder, char *buf, int size) ...@@ -300,6 +300,20 @@ static void forward(void *_forwarder, char *buf, int size)
if (f->tail != NULL) f->tail->next = new; if (f->tail != NULL) f->tail->next = new;
f->tail = new; f->tail = new;
#if BASIC_SIMULATOR
/* When runnng the basic simulator, the tracer may be too slow.
* Let's not take too much memory in the tracee and
* wait if there is too much data to send. 200MB is
* arbitrary.
*/
while (f->memusage > 200 * 1024 * 1024) {
if (pthread_cond_signal(&f->cond)) abort();
if (pthread_mutex_unlock(&f->lock)) abort();
usleep(1000);
if (pthread_mutex_lock(&f->lock)) abort();
}
#endif /* BASIC_SIMULATOR */
f->memusage += size+4; f->memusage += size+4;
/* warn every 100MB */ /* warn every 100MB */
if (f->memusage > f->last_warning_memusage && if (f->memusage > f->last_warning_memusage &&
...@@ -326,17 +340,17 @@ static void wait_message(void) ...@@ -326,17 +340,17 @@ static void wait_message(void)
while (T_local_cache[T_busylist_head].busy == 0) usleep(1000); while (T_local_cache[T_busylist_head].busy == 0) usleep(1000);
} }
static void init_shm(void) static void init_shm(char *shm_file)
{ {
int i; int i;
int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666); int s = shm_open(shm_file, O_RDWR | O_CREAT /*| O_SYNC*/, 0666);
if (s == -1) { perror(T_SHM_FILENAME); abort(); } if (s == -1) { perror(shm_file); abort(); }
if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t))) if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t)))
{ perror(T_SHM_FILENAME); abort(); } { perror(shm_file); abort(); }
T_local_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t), T_local_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED, s, 0); PROT_READ | PROT_WRITE, MAP_SHARED, s, 0);
if (T_local_cache == NULL) if (T_local_cache == MAP_FAILED)
{ perror(T_SHM_FILENAME); abort(); } { perror(shm_file); abort(); }
close(s); close(s);
/* let's garbage the memory to catch some potential problems /* let's garbage the memory to catch some potential problems
...@@ -347,7 +361,7 @@ static void init_shm(void) ...@@ -347,7 +361,7 @@ static void init_shm(void)
} }
void T_local_tracer_main(int remote_port, int wait_for_tracer, void T_local_tracer_main(int remote_port, int wait_for_tracer,
int local_socket) int local_socket, char *shm_file)
{ {
int s; int s;
int port = remote_port; int port = remote_port;
...@@ -357,7 +371,7 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer, ...@@ -357,7 +371,7 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer,
/* write on a socket fails if the other end is closed and we get SIGPIPE */ /* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
init_shm(); init_shm(shm_file);
s = local_socket; s = local_socket;
if (dont_wait) { if (dont_wait) {
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "gui/gui.h" #include "gui/gui.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "utils.h" #include "utils.h"
#include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "openair_logo.h" #include "openair_logo.h"
#include "config.h" #include "config.h"
...@@ -875,6 +874,8 @@ int main(int n, char **v) ...@@ -875,6 +874,8 @@ int main(int n, char **v)
if (pthread_mutex_init(&enb_data.lock, NULL)) abort(); if (pthread_mutex_init(&enb_data.lock, NULL)) abort();
setup_event_selector(g, database, is_on, is_on_changed, &enb_data); setup_event_selector(g, database, is_on, is_on_changed, &enb_data);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
restart: restart:
clear_remote_config(); clear_remote_config();
enb_data.socket = connect_to(ip, port); enb_data.socket = connect_to(ip, port);
...@@ -884,9 +885,8 @@ restart: ...@@ -884,9 +885,8 @@ restart:
/* read messages */ /* read messages */
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(enb_data.socket, v, database); e = get_event(enb_data.socket, &ebuf, database);
if (e.type == -1) goto restart; if (e.type == -1) goto restart;
if (pthread_mutex_lock(&enb_data.lock)) abort(); if (pthread_mutex_lock(&enb_data.lock)) abort();
handle_event(h, e); handle_event(h, e);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
event get_event(int socket, char *event_buffer, void *database) event get_event(int socket, OBUF *event_buffer, void *database)
{ {
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
struct timespec t; struct timespec t;
...@@ -29,17 +29,23 @@ again: ...@@ -29,17 +29,23 @@ again:
#endif #endif
if (fullread(socket, &type, sizeof(int)) == -1) goto read_error; if (fullread(socket, &type, sizeof(int)) == -1) goto read_error;
length -= sizeof(int); length -= sizeof(int);
if (fullread(socket, event_buffer, length) == -1) goto read_error; if (event_buffer->omaxsize < length) {
event_buffer->omaxsize = (length + 65535) & ~65535;
event_buffer->obuf = realloc(event_buffer->obuf, event_buffer->omaxsize);
if (event_buffer->obuf == NULL) { printf("out of memory\n"); exit(1); }
}
if (fullread(socket, event_buffer->obuf, length) == -1) goto read_error;
event_buffer->osize = length;
if (type == -1) append_received_config_chunk(event_buffer, length); if (type == -1) append_received_config_chunk(event_buffer->obuf, length);
if (type == -2) verify_config(); if (type == -2) verify_config();
if (type == -1 || type == -2) goto again; if (type == -1 || type == -2) goto again;
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
return new_event(t, type, length, event_buffer, database); return new_event(t, type, length, event_buffer->obuf, database);
#else #else
return new_event(type, length, event_buffer, database); return new_event(type, length, event_buffer->obuf, database);
#endif #endif
read_error: read_error:
......
#ifndef _EVENT_H_ #ifndef _EVENT_H_
#define _EVENT_H_ #define _EVENT_H_
#include "utils.h"
#include "../T_defs.h" #include "../T_defs.h"
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
#include <time.h> #include <time.h>
...@@ -37,7 +38,7 @@ typedef struct { ...@@ -37,7 +38,7 @@ typedef struct {
int ecount; int ecount;
} event; } event;
event get_event(int s, char *v, void *d); event get_event(int s, OBUF *v, void *d);
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
event new_event(struct timespec sending_time, int type, event new_event(struct timespec sending_time, int type,
......
...@@ -99,10 +99,11 @@ int main(int n, char **v) ...@@ -99,10 +99,11 @@ int main(int n, char **v)
found = 0; found = 0;
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(fd, v, database); e = get_event(fd, &ebuf, database);
if (e.type == -1) break; if (e.type == -1) break;
if (e.type != input_event_id) continue; if (e.type != input_event_id) continue;
for (i = 0; i < filter_count; i++) for (i = 0; i < filter_count; i++)
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "utils.h"
#include "../T_defs.h" #include "../T_defs.h"
void usage(void) void usage(void)
...@@ -35,14 +36,22 @@ int main(int n, char **v) ...@@ -35,14 +36,22 @@ int main(int n, char **v)
in = fopen(input_filename, "r"); in = fopen(input_filename, "r");
if (in == NULL) { perror(input_filename); abort(); } if (in == NULL) { perror(input_filename); abort(); }
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
while (1) { while (1) {
int type; int type;
int32_t length; int32_t length;
char v[T_BUFFER_MAX]; char *v;
int vpos = 0; int vpos = 0;
/* read event from file */ /* read event from file */
if (fread(&length, 4, 1, in) != 1) break; if (fread(&length, 4, 1, in) != 1) break;
if (ebuf.omaxsize < length) {
ebuf.omaxsize = (length + 65535) & ~65535;
ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize);
if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); }
}
v = ebuf.obuf;
memcpy(v+vpos, &length, 4); memcpy(v+vpos, &length, 4);
vpos += 4; vpos += 4;
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
......
...@@ -104,11 +104,12 @@ err: ...@@ -104,11 +104,12 @@ err:
fd = open(file, O_RDONLY); fd = open(file, O_RDONLY);
if (fd == -1) { perror(file); exit(1); } if (fd == -1) { perror(file); exit(1); }
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
/* get wanted frame/subframe */ /* get wanted frame/subframe */
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(fd, v, database); e = get_event(fd, &ebuf, database);
if (e.type == -1) break; if (e.type == -1) break;
if (e.type != input_event_id) continue; if (e.type != input_event_id) continue;
if (verbose) if (verbose)
......
...@@ -100,10 +100,12 @@ err: ...@@ -100,10 +100,12 @@ err:
int last_frame = -1; int last_frame = -1;
int last_subframe = -1; int last_subframe = -1;
int subframe_written = 0; int subframe_written = 0;
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(fd, v, database); e = get_event(fd, &ebuf, database);
if (e.type == -1) break; if (e.type == -1) break;
if (e.type != output_event_id) continue; if (e.type != output_event_id) continue;
if (verbose) if (verbose)
......
...@@ -73,17 +73,22 @@ int main(int n, char **v) ...@@ -73,17 +73,22 @@ int main(int n, char **v)
socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
abort(); abort();
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
char dump[10][T_BUFFER_MAX]; char dump[10][T_BUFFER_MAX];
event dump_ev[10]; event dump_ev[10];
FILE *z = fopen("/tmp/dd", "w"); if (z == NULL) abort(); FILE *z = fopen("/tmp/dd", "w"); if (z == NULL) abort();
while (1) { while (1) {
char v[T_BUFFER_MAX]; char *v;
event e; event e;
e = get_event(socket, v, database); e = get_event(socket, &ebuf, database);
v = ebuf.obuf;
if (e.type == -1) break; if (e.type == -1) break;
if (e.type == ev_input) { if (e.type == ev_input) {
int sf = e.e[2].i; int sf = e.e[2].i;
memcpy(dump[sf], v, T_BUFFER_MAX); if (ebuf.osize > T_BUFFER_MAX)
{ printf("event size too big\n"); exit(1); }
memcpy(dump[sf], ebuf.obuf, ebuf.osize);
dump_ev[sf] = e; dump_ev[sf] = e;
printf("input %d/%d\n", e.e[1].i, sf); printf("input %d/%d\n", e.e[1].i, sf);
if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort(); if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort();
......
...@@ -84,11 +84,12 @@ int main(int n, char **v) ...@@ -84,11 +84,12 @@ int main(int n, char **v)
socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
abort(); abort();
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
int on_off; int on_off;
e = get_event(socket, v, database); e = get_event(socket, &ebuf, database);
if (e.type == -1) break; if (e.type == -1) break;
if (e.type != ev_fun) if (e.type != ev_fun)
{ printf("unhandled event %d\n", e.type); continue; } { printf("unhandled event %d\n", e.type); continue; }
......
...@@ -246,11 +246,12 @@ int main(int n, char **v) ...@@ -246,11 +246,12 @@ int main(int n, char **v)
new_thread(receiver, &d); new_thread(receiver, &d);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
/* read messages */ /* read messages */
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(in, v, database); e = get_event(in, &ebuf, database);
if (e.type == -1) break; if (e.type == -1) break;
if (!(e.type == ul_id || e.type == dl_id)) continue; if (!(e.type == ul_id || e.type == dl_id)) continue;
handle_event(h, e); handle_event(h, e);
......
...@@ -123,14 +123,22 @@ int main(int n, char **v) ...@@ -123,14 +123,22 @@ int main(int n, char **v)
if (signal(SIGINT, force_stop) == SIG_ERR) abort(); if (signal(SIGINT, force_stop) == SIG_ERR) abort();
if (signal(SIGTSTP, force_stop) == SIG_ERR) abort(); if (signal(SIGTSTP, force_stop) == SIG_ERR) abort();
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
/* read messages */ /* read messages */
while (run) { while (run) {
int type; int type;
int32_t length; int32_t length;
char v[T_BUFFER_MAX]; char *v;
int vpos = 0; int vpos = 0;
if (fullread(socket, &length, 4) == -1) goto read_error; if (fullread(socket, &length, 4) == -1) goto read_error;
if (ebuf.omaxsize < length) {
ebuf.omaxsize = (length + 65535) & ~65535;
ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize);
if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); }
}
v = ebuf.obuf;
memcpy(v+vpos, &length, 4); memcpy(v+vpos, &length, 4);
vpos += 4; vpos += 4;
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
......
...@@ -136,14 +136,22 @@ int main(int n, char **v) ...@@ -136,14 +136,22 @@ int main(int n, char **v)
new_thread(get_message_thread, &socket); new_thread(get_message_thread, &socket);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
while (1) { while (1) {
int type; int type;
int32_t length; int32_t length;
char v[T_BUFFER_MAX]; char *v;
int vpos = 0; int vpos = 0;
/* read event from file */ /* read event from file */
if (fread(&length, 4, 1, in) != 1) break; if (fread(&length, 4, 1, in) != 1) break;
if (ebuf.omaxsize < length) {
ebuf.omaxsize = (length + 65535) & ~65535;
ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize);
if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); }
}
v = ebuf.obuf;
memcpy(v+vpos, &length, 4); memcpy(v+vpos, &length, 4);
vpos += 4; vpos += 4;
#ifdef T_SEND_TIME #ifdef T_SEND_TIME
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "view/view.h" #include "view/view.h"
#include "gui/gui.h" #include "gui/gui.h"
#include "utils.h" #include "utils.h"
#include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "config.h" #include "config.h"
...@@ -182,11 +181,12 @@ int main(int n, char **v) ...@@ -182,11 +181,12 @@ int main(int n, char **v)
/* send the first message - activate selected traces */ /* send the first message - activate selected traces */
is_on_changed(&textlog_data); is_on_changed(&textlog_data);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
/* read messages */ /* read messages */
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(textlog_data.socket, v, database); e = get_event(textlog_data.socket, &ebuf, database);
if (e.type == -1) abort(); if (e.type == -1) abort();
handle_event(h, e); handle_event(h, e);
} }
......
...@@ -287,11 +287,12 @@ int main(int n, char **v) ...@@ -287,11 +287,12 @@ int main(int n, char **v)
if (signal(SIGINT, force_stop) == SIG_ERR) abort(); if (signal(SIGINT, force_stop) == SIG_ERR) abort();
if (signal(SIGTSTP, force_stop) == SIG_ERR) abort(); if (signal(SIGTSTP, force_stop) == SIG_ERR) abort();
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
/* read messages */ /* read messages */
while (run) { while (run) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(socket, v, database); e = get_event(socket, &ebuf, database);
if (e.type == -1) { printf("disconnected? let's quit gently\n"); break; } if (e.type == -1) { printf("disconnected? let's quit gently\n"); break; }
handle_event(h, e); handle_event(h, e);
} }
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "gui/gui.h" #include "gui/gui.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "utils.h" #include "utils.h"
#include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "openair_logo.h" #include "openair_logo.h"
#include "config.h" #include "config.h"
...@@ -854,6 +853,8 @@ int main(int n, char **v) ...@@ -854,6 +853,8 @@ int main(int n, char **v)
if (pthread_mutex_init(&ue_data.lock, NULL)) abort(); if (pthread_mutex_init(&ue_data.lock, NULL)) abort();
setup_event_selector(g, database, is_on, is_on_changed, &ue_data); setup_event_selector(g, database, is_on, is_on_changed, &ue_data);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
restart: restart:
clear_remote_config(); clear_remote_config();
ue_data.socket = connect_to(ip, port); ue_data.socket = connect_to(ip, port);
...@@ -863,9 +864,8 @@ restart: ...@@ -863,9 +864,8 @@ restart:
/* read messages */ /* read messages */
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(ue_data.socket, v, database); e = get_event(ue_data.socket, &ebuf, database);
if (e.type == -1) goto restart; if (e.type == -1) goto restart;
if (pthread_mutex_lock(&ue_data.lock)) abort(); if (pthread_mutex_lock(&ue_data.lock)) abort();
handle_event(h, e); handle_event(h, e);
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "view/view.h" #include "view/view.h"
#include "gui/gui.h" #include "gui/gui.h"
#include "utils.h" #include "utils.h"
#include "../T_defs.h"
#include "event_selector.h" #include "event_selector.h"
#include "config.h" #include "config.h"
...@@ -188,11 +187,12 @@ int main(int n, char **v) ...@@ -188,11 +187,12 @@ int main(int n, char **v)
/* send the first message - activate selected traces */ /* send the first message - activate selected traces */
is_on_changed(&vcd_data); is_on_changed(&vcd_data);
OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
/* read messages */ /* read messages */
while (1) { while (1) {
char v[T_BUFFER_MAX];
event e; event e;
e = get_event(vcd_data.socket, v, database); e = get_event(vcd_data.socket, &ebuf, database);
if (e.type == -1) abort(); if (e.type == -1) abort();
handle_event(h, e); handle_event(h, e);
} }
......
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
#include "signals.h" #include "signals.h"
#include "timer.h" #include "timer.h"
#include "log.h"
/* ITTI DEBUG groups */ /* ITTI DEBUG groups */
#define ITTI_DEBUG_POLL (1<<0) #define ITTI_DEBUG_POLL (1<<0)
...@@ -73,6 +72,9 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS); ...@@ -73,6 +72,9 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS);
/* Global message size */ /* Global message size */
#define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size) #define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size)
extern int emulate_rf;
typedef enum task_state_s { typedef enum task_state_s {
TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX, TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX,
} task_state_t; } task_state_t;
...@@ -326,8 +328,112 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me ...@@ -326,8 +328,112 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
/* Increment the global message number */ /* Increment the global message number */
message_number = itti_increment_message_number (); message_number = itti_increment_message_number ();
#if 0
/* itti dump is disabled */
itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
#endif
if (destination_task_id != TASK_UNKNOWN) {
if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) {
ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n",
itti_desc.messages_info[message_id].name,
message_number,
priority,
itti_get_task_name(origin_task_id),
destination_task_id,
itti_get_task_name(destination_task_id));
} else {
if(!emulate_rf){
/* We cannot send a message if the task is not running */
AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY,
"Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n",
itti_get_task_name(origin_task_id),
itti_desc.messages_info[message_id].name,
message_id,
destination_thread_id,
itti_desc.threads[destination_thread_id].task_state);
}
/* Allocate new list element */
new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s));
/* Fill in members */
new->msg = message;
new->message_number = message_number;
new->message_priority = priority;
/* Enqueue message in destination task queue */
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n");
}
{
/* Only use event fd for tasks, subtasks will pool the queue */
if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) {
ssize_t write_ret;
eventfd_t sem_counter = 1;
/* Call to write for an event fd must be of 8 bytes */
write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n",
destination_thread_id, (int) write_ret, (int) sizeof(sem_counter));
}
}
ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n",
itti_desc.messages_info[message_id].name,
message_number,
priority,
itti_get_task_name(origin_task_id),
destination_task_id,
itti_get_task_name(destination_task_id));
}
} else {
/* This is a debug message to TASK_UNKNOWN, we can release safely release it */
int result = itti_free(origin_task_id, message);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
return 0;
}
/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */
/* TODO: this is a hack - the whole logic needs a proper rework. */
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message)
{
thread_id_t destination_thread_id;
task_id_t origin_task_id;
message_list_t *new;
uint32_t priority;
message_number_t message_number;
uint32_t message_id;
AssertFatal (message != NULL, "Message is NULL!\n");
AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max);
destination_thread_id = TASK_GET_THREAD_ID(destination_task_id);
message->ittiMsgHeader.destinationTaskId = destination_task_id;
message->ittiMsgHeader.instance = instance;
message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame;
message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot;
message_id = message->ittiMsgHeader.messageId;
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
origin_task_id = ITTI_MSG_ORIGIN_ID(message);
priority = itti_get_message_priority (message_id);
/* Increment the global message number */
message_number = itti_increment_message_number ();
#if 0
/* itti dump is disabled */
itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
#endif
if (destination_task_id != TASK_UNKNOWN) { if (destination_task_id != TASK_UNKNOWN) {
...@@ -359,18 +465,8 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me ...@@ -359,18 +465,8 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
/* Enqueue message in destination task queue */ /* Enqueue message in destination task queue */
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
LOG_I(UDP_, " Assertion Message %s(id:%d), number %lu with priority %d can not be sent from (%u:%s) to queue (%u:%s). discarding...\n", itti_free(origin_task_id, new);
itti_desc.messages_info[message_id].name, return -1;
message_id,
message_number,
priority,
origin_task_id,
itti_get_task_name(origin_task_id),
destination_task_id,
itti_get_task_name(destination_task_id));
int result = itti_free(origin_task_id, message);
AssertFatal( result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
return 0;
} }
{ {
...@@ -524,10 +620,7 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t ...@@ -524,10 +620,7 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t
if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) { if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) {
/* No element in list -> this should not happen */ /* No element in list -> this should not happen */
LOG_I(UDP_, "Assertion No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret); AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
/* Mark that the event has been processed */
itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN;
return;
} }
AssertFatal(message != NULL, "Message from message queue is NULL!\n"); AssertFatal(message != NULL, "Message from message queue is NULL!\n");
...@@ -634,8 +727,11 @@ void itti_mark_task_ready(task_id_t task_id) ...@@ -634,8 +727,11 @@ void itti_mark_task_ready(task_id_t task_id)
AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max); AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max);
#if 0
/* itti dump is disabled */
/* Register the thread in itti dump */ /* Register the thread in itti dump */
itti_dump_thread_use_ring_buffer(); itti_dump_thread_use_ring_buffer();
#endif
/* Mark the thread as using LFDS queue */ /* Mark the thread as using LFDS queue */
lfds611_queue_use(itti_desc.tasks[task_id].message_queue); lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
...@@ -661,6 +757,19 @@ void itti_mark_task_ready(task_id_t task_id) ...@@ -661,6 +757,19 @@ void itti_mark_task_ready(task_id_t task_id)
void itti_exit_task(void) void itti_exit_task(void)
{ {
task_id_t task_id = itti_get_current_task_id();
thread_id_t thread_id = TASK_GET_THREAD_ID(task_id);
#if defined(OAI_EMU) || defined(RTAI)
if (task_id > TASK_UNKNOWN) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG,
__sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id)));
}
#endif
itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED;
itti_desc.created_tasks--;
ITTI_DEBUG(ITTI_DEBUG_EXIT, "Thread for task %s (%d) exits\n", itti_get_task_name(task_id), task_id);
pthread_exit (NULL); pthread_exit (NULL);
} }
...@@ -762,7 +871,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i ...@@ -762,7 +871,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i
itti_desc.wait_tasks = 0; itti_desc.wait_tasks = 0;
itti_desc.created_tasks = 0; itti_desc.created_tasks = 0;
itti_desc.ready_tasks = 0; itti_desc.ready_tasks = 0;
#if 0
/* itti dump is disabled */
itti_dump_init (messages_definition_xml, dump_file_name); itti_dump_init (messages_definition_xml, dump_file_name);
#endif
CHECK_INIT_RETURN(timer_init ()); CHECK_INIT_RETURN(timer_init ());
...@@ -829,7 +941,10 @@ void itti_wait_tasks_end(void) ...@@ -829,7 +941,10 @@ void itti_wait_tasks_end(void)
exit (0); exit (0);
} }
#if 0
/* itti dump is disabled */
itti_dump_exit(); itti_dump_exit();
#endif
} }
void itti_send_terminate_message(task_id_t task_id) void itti_send_terminate_message(task_id_t task_id)
......
...@@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p); ...@@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p);
**/ **/
int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks
* the return value so it has been changed to crash the program in case
* of failure instead of returning -1 as the documentation above says.
* The RLC UM code may receive too much data when doing UDP at a higher
* throughput than the link allows and so for this specific case we need
* a version that actually returns -1 on failure.
*
* This needs to be cleaned at some point.
*/
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
/** \brief Add a new fd to monitor. /** \brief Add a new fd to monitor.
* NOTE: it is up to the user to read data associated with the fd * NOTE: it is up to the user to read data associated with the fd
* \param task_id Task ID of the receiving task * \param task_id Task ID of the receiving task
......
...@@ -27,7 +27,18 @@ ...@@ -27,7 +27,18 @@
#ifndef _ITTI_TYPES_H_ #ifndef _ITTI_TYPES_H_
#define _ITTI_TYPES_H_ #define _ITTI_TYPES_H_
#include <stdint.h> /* The current file is included in the ue_ip.ko compilation.
* For it to work we need to include linux/types.h and
* not stdint.h.
* A solution to this problem is to use #ifndef __KERNEL__.
* Maybe a better solution would be to clean things up
* so that ue_ip.ko does not include the current file.
*/
#ifndef __KERNEL__
# include <stdint.h>
#else
# include <linux/types.h>
#endif
#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1)) #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1))
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -34,9 +34,10 @@ ...@@ -34,9 +34,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <dlfcn.h> #include <dlfcn.h>
#include "openair1/PHY/defs.h" #include "openair1/PHY/defs_common.h"
#define LOAD_MODULE_SHLIB_MAIN #define LOAD_MODULE_SHLIB_MAIN
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
...@@ -44,68 +45,162 @@ ...@@ -44,68 +45,162 @@
void loader_init(void) { void loader_init(void) {
paramdef_t LoaderParams[] = LOADER_PARAMS_DESC; paramdef_t LoaderParams[] = LOADER_PARAMS_DESC;
loader_data.mainexec_buildversion = PACKAGE_VERSION;
int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX); int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX);
if (ret <0) { if (ret <0) {
fprintf(stderr,"[LOADER] configuration couldn't be performed"); printf("[LOADER] configuration couldn't be performed via config module, parameters set to default values\n");
if (loader_data.shlibpath == NULL) { if (loader_data.shlibpath == NULL) {
loader_data.shlibpath=DEFAULT_PATH; loader_data.shlibpath=DEFAULT_PATH;
} }
return; loader_data.maxshlibs = DEFAULT_MAXSHLIBS;
} }
loader_data.shlibs = malloc(loader_data.maxshlibs * sizeof(loader_shlibdesc_t));
if(loader_data.shlibs == NULL) {
fprintf(stderr,"[LOADER] %s %d memory allocation error %s\n",__FILE__, __LINE__,strerror(errno));
exit_fun("[LOADER] unrecoverable error");
}
memset(loader_data.shlibs,0,loader_data.maxshlibs * sizeof(loader_shlibdesc_t));
}
/* build the full shared lib name from the module name */
char *loader_format_shlibpath(char *modname)
{
char *tmpstr;
char *shlibpath =NULL;
char *shlibversion=NULL;
char *cfgprefix;
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0},
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}};
int ret;
/* looks for specific path for this module in the config file */
/* specific value for a module path and version is located in a modname subsection of the loader section */
/* shared lib name is formatted as lib<module name><module version>.so */
cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16);
if (cfgprefix == NULL) {
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
exit_fun("[LOADER] unrecoverable error");
} else {
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
if (ret <0) {
fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
}
}
/* no specific path, use loader default shared lib path */
if (shlibpath == NULL) {
shlibpath = loader_data.shlibpath ;
}
/* no specific shared lib version */
if (shlibversion == NULL) {
shlibversion = "" ;
}
/* alloc memory for full module shared lib file name */
tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16);
if (tmpstr == NULL) {
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
exit_fun("[LOADER] unrecoverable error");
}
if(shlibpath[0] != 0) {
ret=sprintf(tmpstr,"%s/",shlibpath);
} else {
ret = 0;
}
sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion);
return tmpstr;
} }
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
{ {
void *lib_handle; void *lib_handle;
initfunc_t fpi; initfunc_t fpi;
char *tmpstr; checkverfunc_t fpc;
getfarrayfunc_t fpg;
char *shlib_path;
char *afname=NULL;
int ret=0; int ret=0;
if (loader_data.shlibpath == NULL) { if (loader_data.shlibpath == NULL) {
loader_init(); loader_init();
} }
tmpstr = malloc(strlen(loader_data.shlibpath)+strlen(modname)+16);
if (tmpstr == NULL) {
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
return -1;
}
if(loader_data.shlibpath[0] != 0) { shlib_path = loader_format_shlibpath(modname);
ret=sprintf(tmpstr,"%s/",loader_data.shlibpath);
}
if(strstr(modname,".so") == NULL) {
sprintf(tmpstr+ret,"lib%s.so",modname);
} else {
sprintf(tmpstr+ret,"%s",modname);
}
ret = 0; ret = 0;
lib_handle = dlopen(tmpstr, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
if (!lib_handle) { if (!lib_handle) {
fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", tmpstr,dlerror()); fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror());
ret = -1; ret = -1;
} else { } else {
printf("[LOADER] library %s uccessfully loaded loaded\n", tmpstr); printf("[LOADER] library %s successfully loaded\n", shlib_path);
sprintf(tmpstr,"%s_autoinit",modname); afname=malloc(strlen(modname)+15);
fpi = dlsym(lib_handle,tmpstr); sprintf(afname,"%s_checkbuildver",modname);
fpc = dlsym(lib_handle,afname);
if (fpc != NULL ){
int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion));
if (chkver_ret < 0) {
fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname);
exit_fun("[LOADER] unrecoverable error");
}
}
sprintf(afname,"%s_autoinit",modname);
fpi = dlsym(lib_handle,afname);
if (fpi != NULL ) if (fpi != NULL ) {
{
fpi(); fpi();
} }
if (farray != NULL) { if (farray != NULL) {
loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t));
loader_data.shlibs[loader_data.numshlibs].numfunc=0;
for (int i=0; i<numf; i++) { for (int i=0; i<numf; i++) {
farray[i].fptr = dlsym(lib_handle,farray[i].fname); farray[i].fptr = dlsym(lib_handle,farray[i].fname);
if (farray[i].fptr == NULL ) { if (farray[i].fptr == NULL ) {
fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname);
ret= -1; ret= -1;
} } else { /* farray[i].fptr == NULL */
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname);
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr;
loader_data.shlibs[loader_data.numshlibs].numfunc++;
}/* farray[i].fptr != NULL */
} /* for int i... */ } /* for int i... */
} /* farray ! NULL */ } else { /* farray ! NULL */
} sprintf(afname,"%s_getfarray",modname);
fpg = dlsym(lib_handle,afname);
if (fpg != NULL ) {
loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray));
}
} /* farray ! NULL */
loader_data.shlibs[loader_data.numshlibs].name=strdup(modname);
loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path);
(loader_data.numshlibs)++;
} /* lib_handle != NULL */
if (tmpstr != NULL) free(tmpstr); if ( shlib_path!= NULL) free(shlib_path);
if ( afname!= NULL) free(afname);
if (lib_handle != NULL) dlclose(lib_handle); if (lib_handle != NULL) dlclose(lib_handle);
return ret; return ret;
} }
void * get_shlibmodule_fptr(char *modname, char *fname)
{
for (int i=0; i<loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) {
if ( strcmp(loader_data.shlibs[i].name, modname) == 0) {
for (int j =0; j<loader_data.shlibs[i].numfunc ; j++) {
if (strcmp(loader_data.shlibs[i].funcarray[j].fname, fname) == 0) {
return loader_data.shlibs[i].funcarray[j].fptr;
}
} /* for j loop on module functions*/
}
} /* for i loop on modules */
return NULL;
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -33,33 +33,60 @@ ...@@ -33,33 +33,60 @@
#define LOAD_SHLIB_H #define LOAD_SHLIB_H
typedef int(*initfunc_t)(void);
typedef struct {
char *shlibpath;
}loader_data_t;
typedef struct { typedef struct {
char *fname; char *fname;
int (*fptr)(void); int (*fptr)(void);
}loader_shlibfunc_t; }loader_shlibfunc_t;
typedef struct {
char *name;
char *shlib_version; //
char *shlib_buildversion;
char *thisshlib_path;
uint32_t numfunc;
loader_shlibfunc_t *funcarray;
}loader_shlibdesc_t;
typedef struct {
char *mainexec_buildversion;
char *shlibpath;
uint32_t maxshlibs;
uint32_t numshlibs;
loader_shlibdesc_t *shlibs;
}loader_data_t;
/* function type of functions which may be implemented by a module */
/* 1: init function, called when loading, if found in the shared lib */
typedef int(*initfunc_t)(void);
/* 2: version checking function, called when loading, if it returns -1, trigger main exec abort */
typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version);
/* 3: get function array function, called when loading when a module doesn't provide */
/* the function array when calling load_module_shlib (farray param NULL) */
typedef int(*getfarrayfunc_t)(loader_shlibfunc_t **funcarray);
#ifdef LOAD_MODULE_SHLIB_MAIN #ifdef LOAD_MODULE_SHLIB_MAIN
#define LOADER_CONFIG_PREFIX "loader" #define LOADER_CONFIG_PREFIX "loader"
#define DEFAULT_PATH "" #define DEFAULT_PATH ""
#define DEFAULT_MAXSHLIBS 10
loader_data_t loader_data; loader_data_t loader_data;
/*--------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------------*/
/* LOADER parameters */ /* LOADER parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */ /* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------------*/
#define LOADER_PARAMS_DESC { \ #define LOADER_PARAMS_DESC { \
{"shlibpath", NULL, 0, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0} \ {"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0}, \
{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0}, \
} }
/*-------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------*/
#else #else /* LOAD_MODULE_SHLIB_MAIN */
extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf); extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf);
#endif extern void * get_shlibmodule_fptr(char *modname, char *fname);
extern loader_data_t loader_data;
#endif /* LOAD_MODULE_SHLIB_MAIN */
#endif #endif
...@@ -99,6 +99,7 @@ void *msc_task(void *args_p) ...@@ -99,6 +99,7 @@ void *msc_task(void *args_p)
break; break;
case TERMINATE_MESSAGE: { case TERMINATE_MESSAGE: {
fprintf(stderr, " *** Exiting MSC thread\n");
timer_remove(timer_id); timer_remove(timer_id);
msc_end(); msc_end();
itti_exit_task(); itti_exit_task();
......
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
IF(DEFINED ENV{OPENAIR_DIR})
message("...using oai source files in $ENV{OPENAIR_DIR}")
ELSE()
message("OPENAIR_DIR is not defined. You must run \"source oaienv\" from the oai root dir")
# exit early
return()
ENDIF()
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
set(APPROOT ${OPENAIR_DIR}/common/utils/telnetsrv )
set(OPENAIR_BUILD_DIR $ENV{OPENAIR_DIR}/cmake_targets)
set(OPENAIR1_DIR $ENV{OPENAIR1_DIR})
set(OPENAIR2_DIR $ENV{OPENAIR2_DIR})
set(OPENAIR3_DIR $ENV{OPENAIR3_DIR})
set(OPENAIR_PHY_DIR $ENV{OPENAIR1_DIR}/PHY)
set(OPENAIR_TARGET_DIR $ENV{OPENAIR_DIR}/targets)
set(OPENAIR_COMMONUTILS_DIR $ENV{OPENAIR_DIR}/common/utils)
set(OPENAIR2_COMMON_DIR $ENV{OPENAIR_DIR}/openair2/COMMON)
set(OPENAIR_ASN1INC ${OPENAIR_BUILD_DIR}/lte_build_oai/build/CMakeFiles/Rel14)
set(OPENAIR_NFAPIINC $ENV{NFAPI_DIR} )
set(CMAKE_INSTALL_PREFIX $ENV{OPENAIR_TARGETS})
add_definitions (-DRel14 -DCMAKER -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY -DENABLE_USE_CPU_EXECUTION_TIME -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1 -DEXMIMO_IOT -DJUMBO_FRAME -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1 -DNAS_BUILT_IN_UE -DNAS_UE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR2 -DOPENAIR_LTE -DPHYSIM -DPHY_CONTEXT -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3)
add_compile_options( -fPIC -march=native -Ofast)
include_directories( ./ ${OPENAIR_COMMON_DIR} ${OPENAIR_DIR} ${OPENAIR1_DIR} ${OPENAIR2_DIR} ${OPENAIR2_COMMON_DIR} ${OPENAIR2_DIR}/UTIL/LOG
${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC}
${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0 ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC}
${OPENAIR2_DIR}/LAYER2/RLC ${OPENAIR2_DIR}/UTIL/LISTS ${OPENAIR2_DIR}/UTIL/MEM ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0
${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0 ${OPENAIR2_DIR}/RRC/LITE ${OPENAIR_TARGET_DIR}/COMMON ${OPENAIR_TARGET_DIR}/ARCH/COMMON
${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK ${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG/ ${OPENAIR3_DIR}/NAS/COMMON/IES/ ${OPENAIR3_DIR}/NAS/COMMON/UTIL
${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG/ ${OPENAIR3_DIR}/GTPV1-U ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/shared ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/include
${OPENAIR3_DIR}/UTILS ${OPENAIR_NFAPIINC})
set(TELNETSRV_SOURCE
${APPROOT}/telnetsrv.c
${APPROOT}/telnetsrv_phycmd.c
${APPROOT}/telnetsrv_proccmd.c
)
#set(TELNETSRV_ETHDEVCMD_SOURCE
# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c
# )
add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} )
#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} )
install(TARGETS telnetsrv DESTINATION bin)
if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build)
endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file common/utils/telnetsrv/telnetsrv.h /*! \file common/utils/telnetsrv/telnetsrv.h
* \brief: include file for telnet server implementation * \brief: include file for telnet server implementation
* \author Francois TABURET * \author Francois TABURET
...@@ -38,7 +37,7 @@ ...@@ -38,7 +37,7 @@
#define TELNET_MAX_MSGLENGTH 2048 #define TELNET_MAX_MSGLENGTH 2048
#define TELNET_PROMPT "softmodem> " #define TELNET_PROMPT "softmodem> "
#define TELNET_MAXCMD 20 #define TELNET_MAXCMD 20
#define TELNET_CMD_MAXSIZE 10 #define TELNET_CMD_MAXSIZE 20
#define TELNET_HELPSTR_SIZE 80 #define TELNET_HELPSTR_SIZE 80
/* status return by the command parser after it analysed user input */ /* status return by the command parser after it analysed user input */
...@@ -70,7 +69,7 @@ typedef struct cmddef { ...@@ -70,7 +69,7 @@ typedef struct cmddef {
#define TELNET_VARTYPE_INT64 3 #define TELNET_VARTYPE_INT64 3
#define TELNET_VARTYPE_STRING 4 #define TELNET_VARTYPE_STRING 4
#define TELNET_VARTYPE_DOUBLE 5 #define TELNET_VARTYPE_DOUBLE 5
#define TELNET_VARTYPE_PTR 6 //#define TELNET_VARTYPE_PTR 6
typedef struct variabledef { typedef struct variabledef {
char varname[TELNET_CMD_MAXSIZE]; char varname[TELNET_CMD_MAXSIZE];
char vartype; char vartype;
...@@ -96,6 +95,8 @@ typedef struct { ...@@ -96,6 +95,8 @@ typedef struct {
pthread_t telnet_pthread; // thread id of the telnet server pthread_t telnet_pthread; // thread id of the telnet server
int telnetdbg; // debug level of the server int telnetdbg; // debug level of the server
int priority; // server running priority int priority; // server running priority
char *histfile; // command history
int histsize; // command history length
int new_socket; // socket of the client connection int new_socket; // socket of the client connection
int logfilefd; // file id of the log file when log output is redirected to a file int logfilefd; // file id of the log file when log output is redirected to a file
int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout
...@@ -130,10 +131,12 @@ VT escape sequence definition, for smarter display.... ...@@ -130,10 +131,12 @@ VT escape sequence definition, for smarter display....
#define STDFMT "\x1b[0m" #define STDFMT "\x1b[0m"
/*---------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------*/
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
#ifdef TELNETSERVERCODE #ifdef TELNETSERVERCODE
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
void set_sched(pthread_t tid, int pid,int priority); void set_sched(pthread_t tid, int pid,int priority);
void set_affinity(pthread_t tid, int pid, int coreid); void set_affinity(pthread_t tid, int pid, int coreid);
extern int get_phybsize(); extern int get_phybsize(void);
#endif #endif
#endif #endif
set(TELNETROOT ${OPENAIR_DIR}/common/utils/telnetsrv )
set(TELNETSRV_SOURCE
${TELNETROOT}/telnetsrv.c
${TELNETROOT}/telnetsrv_phycmd.c
${TELNETROOT}/telnetsrv_proccmd.c
${TELNETROOT}/telnetsrv_loader.c
)
#set(TELNETSRV_ETHDEVCMD_SOURCE
# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c
# )
add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} )
#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} )
target_link_libraries(telnetsrv PRIVATE history)
install(TARGETS telnetsrv DESTINATION bin)
if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build)
endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
/*
* 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 common/utils/telnetsrv/telnetsrv_loader.c
* \brief: implementation of telnet commands related to softmodem linux process
* \author Francois TABURET
* \date 2018
* \version 0.1
* \company NOKIA BellLabs France
* \email: francois.taburet@nokia-bell-labs.com
* \note
* \warning
*/
#define _GNU_SOURCE
#include <string.h>
#include <pthread.h>
#define TELNETSERVERCODE
#include "telnetsrv.h"
#define TELNETSRV_LOADER_MAIN
#include "telnetsrv_loader.h"
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
telnetshell_cmddef_t loader_cmdarray[] = {
{"show","[params,modules]",loader_show_cmd},
{"","",NULL},
};
/*-------------------------------------------------------------------------------------*/
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
{
if (debug > 0)
prnt( "loader_show_cmd received %s\n",buff);
if (strcasestr(buff,"params") != NULL) {
prnt( "loader parameters:\n");
prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion);
prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath);
prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs);
}
else if (strcasestr(buff,"modules") != NULL) {
prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs);
for (int i=0 ; i<loader_data.numshlibs ; i++) {
prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name);
prnt( " Shared library build version: \"%s\"\n",((loader_data.shlibs[i].shlib_buildversion == NULL )?"":loader_data.shlibs[i].shlib_buildversion));
prnt( " Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path);
prnt( " %i function pointers registered:\n", loader_data.shlibs[i].numfunc);
for(int j=0 ; j<loader_data.shlibs[i].numfunc;j++) {
prnt( " function %i %s at %p\n",j,
loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr);
}
}
} else {
prnt("%s: wrong loader command...\n",buff);
}
return 0;
}
void add_loader_cmds(void)
{
add_telnetcmd("loader", loader_globalvardef, loader_cmdarray);
}
/*
* 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 common/utils/telnetsrv_proccmd.h
* \brief: Include file defining telnet commands related to softmodem linux process
* \author Francois TABURET
* \date 2018
* \version 0.1
* \company NOKIA BellLabs France
* \email: francois.taburet@nokia-bell-labs.com
* \note
* \warning
*/
#ifdef TELNETSRV_LOADER_MAIN
#include "UTIL/LOG/log.h"
#include "common/utils/load_module_shlib.h"
telnetshell_vardef_t loader_globalvardef[] = {
{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)},
{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)},
{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)},
{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)},
{"",0,NULL}
};
telnetshell_vardef_t *loader_modulesvardef;
extern void add_loader_cmds(void);
#endif
/*-------------------------------------------------------------------------------------*/
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
char *prnbuff; char *prnbuff;
extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length); extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length);
void init_phytelnet() void init_phytelnet(void)
{ {
prnbuff=malloc(get_phybsize() ); prnbuff=malloc(get_phybsize() );
if (prnbuff == NULL) if (prnbuff == NULL)
...@@ -134,7 +134,7 @@ telnetshell_cmddef_t phy_cmdarray[] = { ...@@ -134,7 +134,7 @@ telnetshell_cmddef_t phy_cmdarray[] = {
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
void add_phy_cmds() void add_phy_cmds(void)
{ {
init_phytelnet(); init_phytelnet();
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -42,8 +42,6 @@ ...@@ -42,8 +42,6 @@
#define TELNETVAR_PHYCC1 1 #define TELNETVAR_PHYCC1 1
telnetshell_vardef_t phy_vardef[] = { telnetshell_vardef_t phy_vardef[] = {
{"phycc1",TELNET_VARTYPE_PTR,NULL},
{"phycc2",TELNET_VARTYPE_PTR,NULL},
//{"iqmax",TELNET_VARTYPE_INT16,NULL}, //{"iqmax",TELNET_VARTYPE_INT16,NULL},
//{"iqmin",TELNET_VARTYPE_INT16,NULL}, //{"iqmin",TELNET_VARTYPE_INT16,NULL},
//{"loglvl",TELNET_VARTYPE_INT32,NULL}, //{"loglvl",TELNET_VARTYPE_INT32,NULL},
...@@ -57,7 +55,7 @@ telnetshell_vardef_t phy_vardef[] = { ...@@ -57,7 +55,7 @@ telnetshell_vardef_t phy_vardef[] = {
#else #else
extern void add_phy_cmds(); extern void add_phy_cmds(void);
#endif #endif
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. * except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file common/utils/telnetsrv/telnetsrv_proccmd.h /*! \file common/utils/telnetsrv/telnetsrv_proccmd.h
* \brief: Include file defining telnet commands related to this linux process * \brief: Include file defining telnet commands related to this linux process
* \author Francois TABURET * \author Francois TABURET
...@@ -43,15 +44,33 @@ extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt); ...@@ -43,15 +44,33 @@ extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt);
telnetshell_vardef_t proc_vardef[] = { telnetshell_vardef_t proc_vardef[] = {
{"",0,NULL} {"",0,NULL}
}; };
#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\
show: display current log configuration \n\
online, noonline: enable or disable console logs \n\
enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\
level_<level> id1-id2: set log level to <level> for components index id1 to id2 \n\
level_<verbosity> id1-id2: set log verbosity to <verbosity> for components index id1 to id2 \n\
use the show command to get the values for <level>, <verbosity> and the list of component indexes \
that can be used for id1 and id2 \n"
#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\
<thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\
<thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\
if prio < -20: linux scheduling policy set to FIFO, \n\
with priority = -20 - prio \n\
if prio > 19: linux scheduling policy set to OTHER, \n\
with priority (nice value) = prio \n\
use \"softmodem show thread\" to get <thread id> \n"
telnetshell_cmddef_t proc_cmdarray[] = { telnetshell_cmddef_t proc_cmdarray[] = {
{"show","loglvl|thread", proccmd_show}, {"show","loglvl|thread|config", proccmd_show},
{"log","[enable,disable]", proccmd_log}, {"log","(enter help for details)", proccmd_log},
{"thread","<id> aff|prio <aff|prio>", proccmd_thread}, {"thread","(enter help for details)", proccmd_thread},
{"exit","", proccmd_exit}, {"exit","", proccmd_exit},
{"","",NULL}, {"","",NULL},
}; };
#else #else
extern void add_proccmd_cmds(); extern void add_proccmd_cmds(void);
#endif /* TELNETSRV_PROCCMD_MAIN */ #endif /* TELNETSRV_PROCCMD_MAIN */
Scenario 1 : Off-network UE2UE link
SynchREF UE (UE1)
UE1(eth0 - 10.10.10.1)--------UE2(eno1 - 10.10.10.2)
Here's an example of /etc/network/interfaces configuration for UE1
auto eth0
iface eth0 inet static
address 10.10.10.1
netmask 255.255.255.0
gateway 10.10.10.1
Prepare the environment:
- git clone https://gitlab.eurecom.fr/matzakos/LTE-D2D.git #branch: master
This branch contains all the current development for DDPS
- UE MAC<-> UE MAC for Scenario 1
- eNB MAC<->UE MAC (NFAPI Transport)
- RRC Extensions for “on-network” cases
NFAPI configuration (required even for Scenario 1 target)
- git clone https://github.com/cisco/open-nFAPI.git
- cd open-nfapi
- patch -p1 --dry-run < $OPENAIR_HOME/open-nfapi.oai.patch
Validate that there are no errors
- patch -p1 < $OPENAIR_HOME/open-nfapi.oai.patch
OAI build/execute
- export NFAPI_DIR=XXX (place where NFAPI was installed)
- cd cmake_targets
- ./build_oai --UE
(if necessary, use ./build_oai -I --UE to install required packages)
- cd lte_build_oai/build/
- cp ../../../targets/bin/.ue* .
- cp ../../../targets/bin/.usim* .
- sudo insmod ../../../targets/bin/ue_ip.ko
UE1:
- sudo ifconfig oip0 10.0.0.1
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3
- (if necessary) sudo route add default gw 10.10.10.1 eth0
UE2:
- sudo ifconfig oip0 10.0.0.2
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3
- (if necessary) sudo route add default gw 10.10.10.1 eno1
UE1 and UE2: Get and build vencore_app from d2d-l3-stub (branch: l3_stub)
- gcc -I . vencore_app.c -o vencore_app -lpthread
--------------------------------
TEST ONE-TO-MANY
Run UE1 then UE2, for example:
UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
Test with Ping
- Sender - UE1: ping -I oip0 224.0.0.3
- Receiver - UE2: using wireshark
Test with Iperf
- Sender - UE1: iperf -c 224.0.0.3 -u -b 0.1M --bind 10.0.0.1 -t 100
- Receiver - UE2: sudo ./mcreceive 224.0.0.3 5001
Filter the incomming packets according to GroupL2Id: receiver (one-to-many) can discard the packets if it doesn't belong to this group.
For the moment, both sender and receiver use the same set of Ids (hardcoded)
UE1 (sender)
- sudo ./lte-softmodem-stub -U --emul-iface eth0
- ./vencore_app #send the sourceL2Id, groupL2Id to OAI
- ping -I oip0 224.0.0.3
UE2(receiver)
- sudo ./lte-softmodem-stub -U --emul-iface eno1
#we can see the incomming packets from OAI log, however, cannot see from Wireshark -> they are discarded at MAC layer
- ./vencore_app #we can see the packets appearing in Wireshark
--------------------------------------
TEST PC5-S (UE1 -sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario
Configure UE1/UE2
UE1:
- sudo ifconfig oip0 10.0.0.1
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3
- sudo route add default gw 10.10.10.1 eth0
UE2:
- sudo ifconfig oip0 10.0.0.2
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3
- sudo route add default gw 10.10.10.1 eno1
step 1:
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
step 2:
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE2: ./vencore_app -r #listen to incomming message from PC5-S
step 3:
- UE1: ./vencore_app -s #send a message via PC5-S (e.g., DirectCommunicationRequest)
Generate unicast traffic
UE1: ping -I oip0 10.0.0.2
--------------------------------------
TEST PC5-D
step 1:
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
- UE1: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
step 2:
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE2: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
This diff is collapsed.
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#if !defined(NFAPI_PNF_H__) #if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__ #define NFAPI_PNF_H__
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
#endif #endif
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
#include "vendor_ext.h" #include "vendor_ext.h"
#include "nfapi_vnf.h" #include "nfapi_vnf.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "common/ran_context.h" #include "common/ran_context.h"
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
...@@ -201,8 +202,8 @@ void oai_create_enb(void) { ...@@ -201,8 +202,8 @@ void oai_create_enb(void) {
eNB->CC_id = bodge_counter; eNB->CC_id = bodge_counter;
eNB->abstraction_flag = 0; eNB->abstraction_flag = 0;
eNB->single_thread_flag = 0;//single_thread_flag; eNB->single_thread_flag = 0;//single_thread_flag;
eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; eNB->td = ulsch_decoding_data_all;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; eNB->te = dlsch_encoding_all;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding;
RC.nb_CC[bodge_counter] = 1; RC.nb_CC[bodge_counter] = 1;
......
...@@ -1247,9 +1247,14 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) ...@@ -1247,9 +1247,14 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf); int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta); //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta);
if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1)
// Panos: Careful here!!!
//if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1)
if (vnf_pnf_sfnsf_delta>0 || vnf_pnf_sfnsf_delta < 0)
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf)); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf));
// Panos: Careful here!!!
vnf_p7->p7_connections[0].sfn_sf = ind.last_sfn_sf;
} }
} }
} }
......
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
#ifndef TC_MAIN #ifndef TC_MAIN
//#include "defs.h" //#include "defs.h"
#endif #endif
#include <stdint.h>
#include <stdio.h>
#include "PHY/CODING/coding_defs.h"
#include "extern_3GPPinterleaver.h" #include "extern_3GPPinterleaver.h"
//#define DEBUG_TURBO_ENCODER 1 //#define DEBUG_TURBO_ENCODER 1
...@@ -35,7 +37,7 @@ ...@@ -35,7 +37,7 @@
uint32_t threegpplte_interleaver_output; uint32_t threegpplte_interleaver_output;
uint32_t threegpplte_interleaver_tmp; uint32_t threegpplte_interleaver_tmp;
inline void threegpplte_interleaver_reset() inline void threegpplte_interleaver_reset(void)
{ {
threegpplte_interleaver_output = 0; threegpplte_interleaver_output = 0;
threegpplte_interleaver_tmp = 0; threegpplte_interleaver_tmp = 0;
...@@ -82,7 +84,7 @@ uint8_t output_lut[16],state_lut[16]; ...@@ -82,7 +84,7 @@ uint8_t output_lut[16],state_lut[16];
inline uint8_t threegpplte_rsc_lut(uint8_t input,uint8_t *state) inline uint8_t threegpplte_rsc_lut(uint8_t input,uint8_t *state)
{ {
uint8_t output;
uint8_t off; uint8_t off;
off = (*state<<1)|input; off = (*state<<1)|input;
...@@ -146,7 +148,7 @@ void threegpplte_turbo_encoder(uint8_t *input, ...@@ -146,7 +148,7 @@ void threegpplte_turbo_encoder(uint8_t *input,
for (i=0; f1f2mat[i].nb_bits!= input_length_bits && i <188; i++); for (i=0; f1f2mat[i].nb_bits!= input_length_bits && i <188; i++);
if ( i == 188 ) { if ( i == 188 ) {
msg("Illegal frame length!\n"); printf("Illegal frame length!\n");
return; return;
} else { } else {
base_interleaver=il_tb+f1f2mat[i].beg_index; base_interleaver=il_tb+f1f2mat[i].beg_index;
......
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
date: 09.2012 date: 09.2012
*/ */
#ifndef TC_MAIN #ifndef TC_MAIN
#include "defs.h" #include "coding_defs.h"
#include "extern_3GPPinterleaver.h" #include "extern_3GPPinterleaver.h"
#else #else
#include "vars.h" #include "coding_vars.h"
#include <stdint.h> #include <stdint.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
...@@ -96,7 +96,7 @@ static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z ...@@ -96,7 +96,7 @@ static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z
*state = (*state)>>1; *state = (*state)>>1;
} }
void treillis_table_init(void) static void treillis_table_init(void)
{ {
//struct treillis t[][]=all_treillis; //struct treillis t[][]=all_treillis;
//t=memalign(16,sizeof(struct treillis)*8*256); //t=memalign(16,sizeof(struct treillis)*8*256);
...@@ -536,12 +536,12 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns ...@@ -536,12 +536,12 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns
} }
*/ */
void threegpplte_turbo_encoder(unsigned char *input, void threegpplte_turbo_encoder_sse(unsigned char *input,
unsigned short input_length_bytes, unsigned short input_length_bytes,
unsigned char *output, unsigned char *output,
unsigned char F, unsigned char F,
unsigned short interleaver_f1, unsigned short interleaver_f1,
unsigned short interleaver_f2) unsigned short interleaver_f2)
{ {
int i; int i;
...@@ -641,7 +641,24 @@ void threegpplte_turbo_encoder(unsigned char *input, ...@@ -641,7 +641,24 @@ void threegpplte_turbo_encoder(unsigned char *input,
#endif #endif
} }
void init_encoder_sse (void) {
treillis_table_init();
}
/* function which will be called by the shared lib loader, to check shared lib version
against main exec version. version mismatch no considered as fatal (interfaces not supposed to change)
*/
int coding_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion)
{
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__
#endif
*shlib_buildversion = PACKAGE_VERSION;
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
mainexec_buildversion,*shlib_buildversion);
}
return 0;
}
#ifdef TC_MAIN #ifdef TC_MAIN
#define INPUT_LENGTH 20 #define INPUT_LENGTH 20
...@@ -679,7 +696,7 @@ int main(int argc,char **argv) ...@@ -679,7 +696,7 @@ int main(int argc,char **argv)
printf("Input %d : %d\n",i,input[i]); printf("Input %d : %d\n",i,input[i]);
} }
threegpplte_turbo_encoder(&input[0], threegpplte_turbo_encoder_sse(&input[0],
INPUT_LENGTH, INPUT_LENGTH,
&output[0], &output[0],
0, 0,
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
*/ */
#include "PHY/defs.h" #include "PHY/defs_common.h"
#include "PHY/CODING/defs.h" #include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/sse_intrin.h" #include "PHY/sse_intrin.h"
...@@ -550,7 +550,7 @@ void compute_alpha_s(llr_t* alpha,llr_t* m_11,llr_t* m_10,unsigned short frame_l ...@@ -550,7 +550,7 @@ void compute_alpha_s(llr_t* alpha,llr_t* m_11,llr_t* m_10,unsigned short frame_l
void compute_beta_s(llr_t* beta,llr_t *m_11,llr_t* m_10,llr_t* alpha,unsigned short frame_length,unsigned char F) void compute_beta_s(llr_t* beta,llr_t *m_11,llr_t* m_10,llr_t* alpha,unsigned short frame_length,unsigned char F)
{ {
int k,i; int k;
llr_t old0, old1, old2, old3, old4, old5, old6, old7; llr_t old0, old1, old2, old3, old4, old5, old6, old7;
llr_t new0, new1, new2, new3, new4, new5, new6, new7; llr_t new0, new1, new2, new3, new4, new5, new6, new7;
llr_t m_b0, m_b1, m_b2, m_b3, m_b4,m_b5, m_b6, m_b7; llr_t m_b0, m_b1, m_b2, m_b3, m_b4,m_b5, m_b6, m_b7;
...@@ -874,14 +874,22 @@ void compute_ext_s(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, ...@@ -874,14 +874,22 @@ void compute_ext_s(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext,
unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y,
llr_t *y2,
unsigned char *decoded_bytes, unsigned char *decoded_bytes,
unsigned char *decoded_bytes2,
unsigned short n, unsigned short n,
unsigned short f1, unsigned short f1,
unsigned short f2, unsigned short f2,
unsigned char max_iterations, unsigned char max_iterations,
unsigned char crc_type, unsigned char crc_type,
unsigned char F, unsigned char F,
unsigned char inst) time_stats_t *init_stats,
time_stats_t *alpha_stats,
time_stats_t *beta_stats,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats)
{ {
/* y is a pointer to the input /* y is a pointer to the input
...@@ -897,7 +905,7 @@ unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, ...@@ -897,7 +905,7 @@ unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y,
unsigned char crc_len,temp; unsigned char crc_len,temp;
if (crc_type > 3) { if (crc_type > 3) {
msg("Illegal crc length!\n"); fprintf(stderr,"Illegal crc length!\n");
return 255; return 255;
} }
......
...@@ -1907,6 +1907,18 @@ void compute_ext(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, ll ...@@ -1907,6 +1907,18 @@ void compute_ext(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, ll
//int pi2[n],pi3[n+8],pi5[n+8],pi4[n+8],pi6[n+8], //int pi2[n],pi3[n+8],pi5[n+8],pi4[n+8],pi6[n+8],
int *pi2tab[188],*pi5tab[188],*pi4tab[188],*pi6tab[188]; int *pi2tab[188],*pi5tab[188],*pi4tab[188],*pi6tab[188];
void free_td()
{
int ind;
for (ind = 0; ind < 188; ind++) {
free_and_zero(pi2tab[ind]);
free_and_zero(pi5tab[ind]);
free_and_zero(pi4tab[ind]);
free_and_zero(pi6tab[ind]);
}
}
void init_td() void init_td()
{ {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
author: raymond.knopp@eurecom.fr, based on similar code for 3GPP convolutional code (UMTS) by P. Humblet (2000) author: raymond.knopp@eurecom.fr, based on similar code for 3GPP convolutional code (UMTS) by P. Humblet (2000)
date: 10.2004 date: 10.2004
*/ */
#include "defs.h" #include "coding_defs.h"
unsigned short gdot11[] = { 0133, 0171 }; // {A,B} unsigned short gdot11[] = { 0133, 0171 }; // {A,B}
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
author: raymond.knopp@eurecom.fr author: raymond.knopp@eurecom.fr
date: 21.10.2009 date: 21.10.2009
*/ */
#include "defs.h" #include "coding_defs.h"
//#define DEBUG_CCODE 1 //#define DEBUG_CCODE 1
......
...@@ -20,5 +20,9 @@ ...@@ -20,5 +20,9 @@
*/ */
extern unsigned short f1f2mat_old[2*188]; extern unsigned short f1f2mat_old[2*188];
extern double cpuf;
extern decoder_if_t decoder16;
extern decoder_if_t decoder8;
extern encoder_if_t encoder;
extern int load_codinglib(void);
extern int free_codinglib(void);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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