From 87a8cb28a5280a6673aaae1f09c0d50ba85c2ab7 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 4 Mar 2019 22:07:32 +0100 Subject: [PATCH 01/26] basic and rf simulators as config option to allow noS1 datapath debug. --- cmake_targets/CMakeLists.txt | 14 +- cmake_targets/build_oai | 383 +++++++++++++------------ openair1/PHY/INIT/lte_param_init.c | 8 +- openair1/PHY/LTE_TRANSPORT/dci.c | 17 +- openair1/PHY/LTE_TRANSPORT/pss.c | 6 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 6 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 6 +- openair2/RRC/LTE/rrc_UE.c | 25 +- openair2/RRC/LTE/rrc_eNB.c | 18 +- openair2/RRC/NAS/nas_config.c | 10 +- openair2/RRC/NAS/nas_config.h | 2 +- targets/ARCH/COMMON/common_lib.c | 14 +- targets/ARCH/COMMON/common_lib.h | 5 +- targets/RT/USER/lte-ru.c | 4 +- targets/RT/USER/lte-softmodem-common.c | 12 + targets/RT/USER/lte-softmodem.c | 2 +- targets/RT/USER/lte-softmodem.h | 10 +- targets/RT/USER/lte-ue.c | 44 ++- targets/RT/USER/lte-uesoftmodem.c | 9 +- 19 files changed, 316 insertions(+), 279 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6c176a75c2..810d3465c2 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -21,7 +21,7 @@ # Author: laurent THOMAS, Lionel GAUTHIER -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) ############################################# # Base directories, compatible with legacy OAI building @@ -169,11 +169,12 @@ endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ") # add autotools definitions that were maybe used! +set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'") set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" + "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}" ) set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" + "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}" ) add_definitions("-DASN_DISABLE_OER_SUPPORT") @@ -477,7 +478,8 @@ add_dependencies(X2AP_ENB rrc_flag x2_flag) add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") -add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR") +add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU") + add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET") #NOKIA config enhancement @@ -585,6 +587,8 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} ) set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") +add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c) + ########################################################## include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") @@ -1949,6 +1953,8 @@ add_executable(lte-softmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index d14bd3ec6e..e77dbab049 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -76,7 +76,7 @@ trap handle_ctrl_c INT function print_help() { echo_info " This program installs OpenAirInterface Software -You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14 +You should have ubuntu 16.xx or 18.04 updated Options -h This help @@ -167,6 +167,9 @@ Options --basic-simulator Generates a basic [1 UE + 1 eNB + no channel] simulator. See targets/ARCH/tcp_bridge/README.tcp_bridge_oai for documentation. +--rfsimulator + Generate virtual RF driver + to use it, set the environement variable RFSIMULATOR to \"enb\" in the eNB and to the eNB IP address in the UEs Usage (first build): NI/ETTUS B201 + COTS UE : ./build_oai -I --eNB -x --install-system-files -w USRP Usage (Regular): @@ -234,25 +237,21 @@ function main() { echo_info "Setting release to: $REL" shift 2;; -w | --hardware) - HW="$2" #"${i#*=}" - # Use OAI_USRP as the key word USRP is used inside UHD driver - if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "IRIS" ] ; then - echo_fatal "Unknown HW type $HW will exit..." - else - if [ "$HW" == "USRP" ] ; then - HW="OAI_USRP" - fi - if [ "$HW" == "BLADERF" ] ; then - HW="OAI_BLADERF" - fi - if [ "$HW" == "LMSSDR" ] ; then - HW="OAI_LMSSDR" - fi - if [ "$HW" == "IRIS" ] ; then - HW="OAI_IRIS" - fi - echo_info "Setting hardware to: $HW" - fi + # Use OAI_USRP as the key word USRP is used inside UHD driver + case "$2" in + "EXMIMO") + HW="EXMIMO" + ;; + "USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU") + HW="OAI_"$2 + ;; + "None") + HW="None" + ;; + *) + echo_fatal "Unknown HW type $HW: exit..." + esac + echo_info "Setting hardware to: $HW" shift 2;; -t | --transport_protocol) TP="$2" #"${i#*=}" @@ -374,6 +373,10 @@ function main() { BASIC_SIMULATOR=1 echo_info "Compiling the basic simulator" shift 1;; + --rfsimulator) + RFSIMULATOR=true + echo_info "Compiling the RF simulator" + shift 1;; -h | --help) print_help exit 1;; @@ -386,56 +389,35 @@ function main() { CMAKE_CMD="$CMAKE_CMD .." echo_info "CMAKE_CMD=$CMAKE_CMD" - if [ "$eNB" = "1" ] && [ "$UE" = "1" ]; then - echo_error "Cannot build UE and eNB on one build_oai execution" - echo_error "use 2 build_oai invocations" - exit - fi - ######################################################### - # check validity of HW and TP parameters for eNB - ######################################################### - # to be discussed - - if [ "$eNB" = "1" ] ; then - if [ "$HW" = "None" -a "$TP" = "None" ] ; then - echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!" - fi - if [ "$HW" = "None" ] ; then - echo_info "No radio head has been selected (HW set to $HW)" - fi - if [ "$TP" = "None" ] ; then - echo_info "No transport protocol has been selected (TP set to $TP)" - fi - fi - - echo_info "RF HW set to $HW" - #Now we set flags to enable deadline scheduler settings - #By default: USRP: disable, - #By default: BLADERF: enable, - #By default: EXMIMO: enable - if [ "$FORCE_DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then - if [ "$HW" = "EXMIMO" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="True" - elif [ "$HW" = "ETHERNET" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_USRP" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_BLADERF" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_LMSSDR" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_IRIS" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "None" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - else - echo_error "Unknown HW type $HW. Exiting now..." - exit - fi - else - DEADLINE_SCHEDULER_FLAG_USER=$FORCE_DEADLINE_SCHEDULER_FLAG_USER - fi - + ######################################################### + # check validity of HW and TP parameters for eNB + ######################################################### + # to be discussed + + if [ "$eNB" = "1" ] ; then + if [ "$HW" = "None" -a "$TP" = "None" ] ; then + echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!" + fi + if [ "$HW" = "None" ] ; then + echo_info "No radio head has been selected (HW set to $HW)" + fi + if [ "$TP" = "None" ] ; then + echo_info "No transport protocol has been selected (TP set to $TP)" + fi + fi + + echo_info "RF HW set to $HW" + # If the user doesn't specify the Linux scheduler to use, we set a value + if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then + case "$HW" in + "EXMIMO") + DEADLINE_SCHEDULER_FLAG_USER="True" + ;; + *) + DEADLINE_SCHEDULER_FLAG_USER="False" + ;; + esac + fi #Disable CPU Affinity for deadline scheduler if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then CPU_AFFINITY_FLAG_USER="False" @@ -515,27 +497,20 @@ function main() { echo_info "3. building the compilation directives ..." - DIR=$OPENAIR_DIR/cmake_targets - if [ "$NOS1" = "1" ] ; then - lte_build_dir=lte_noS1_build_oai - if [ "$eNB" = "1" ] ; then - lte_exec=lte-softmodem-nos1 - fi - if [ "$UE" = "1" ] ; then - lte_exec=lte-uesoftmodem-nos1 - fi - else - lte_build_dir=lte_build_oai - if [ "$eNB" = "1" ] ; then - lte_exec=lte-softmodem - fi - if [ "$UE" = "1" ] ; then - lte_exec=lte-uesoftmodem - fi - fi - if [ "$T_TRACER" = "False" ] ; then - lte_build_dir=${lte_build_dir}_noLOG - fi + DIR=$OPENAIR_DIR/cmake_targets + + if [ "$T_TRACER" = "False" ] ; then + noLOGDirsuffix="_noLOG" + fi + if [ "$NOS1" = "1" ] ; then + noS1Dir="_noS1" + bin_suffix="-nos1" + else + lte_build_dir=lte_build_oai + bin_suffix="" + fi + + lte_build_dir="lte${noS1Dir}_build_oai${noLOGDirsuffix}" # configuration module libraries, one currently available, using libconfig config_libconfig_shlib=params_libconfig @@ -580,8 +555,8 @@ function main() { eval $CMAKE_CMD fi - if [ "$eNB" = "1" -o "$UE" = "1" ] ; then - echo_info "Compiling $lte_exec" + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem${bin_suffix} compilations \ $lte_build_dir $lte_exec \ $lte_exec $dbin/$lte_exec.$REL @@ -605,7 +580,29 @@ function main() { fi fi - if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then + if [ "$UE" = 1 ] ; then + lte_exec=lte-uesoftmodem${bin_suffix} + compilations \ + $lte_build_dir $lte_exec \ + $lte_exec $dbin/$lte_exec.$REL + + # mandatory shared lib + compilations \ + $lte_build_dir $config_libconfig_shlib \ + lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so + compilations \ + $lte_build_dir coding \ + libcoding.so $dbin/libcoding.so + + if [ "$NOS1" = "1" ] ; then + compilations \ + $lte_build_dir nasmesh \ + CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko + compilations \ + $lte_build_dir rb_tool \ + rb_tool $dbin/rb_tool + cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin + else # ue_ip driver compilation echo_info "Compiling UE specific part" compilations \ @@ -645,6 +642,7 @@ function main() { echo_warning "not generated UE NAS files: binaries not found" fi fi + fi if [ "$SIMUS_PHY" = "1" -o "$SIMUS_CORE" = "1" ] ; then cd $OPENAIR_DIR/cmake_targets/lte-simulators @@ -709,103 +707,108 @@ function main() { cp $OPENAIR_DIR/cmake_targets/tools/init_exmimo2 $dbin fi + # Telnet server compilation + ##################### + if [ "$BUILD_TELNETSRV" = "1" ] ; then + compilations \ + $lte_build_dir telnetsrv \ + libtelnetsrv.so $dbin/libtelnetsrv.so + + fi + # msc library compilation + ##################### + if [ "$MSC_GEN" = "1" ] ; then + compilations \ + $lte_build_dir msc \ + libmsc.so $dbin/libmsc.so + + fi + # build RF device and transport protocol libraries + ##################################### + if [ "$eNB" = "1" -o "$UE" = "1" ] ; then + + # build RF device libraries + if [ "$HW" != "None" ] ; then + rm -f liboai_device.so + rm -f $dbin/liboai_device.so + + # link liboai_device.so with the selected RF device library + if [ "$HW" == "EXMIMO" ] ; then + compilations \ + $lte_build_dir oai_exmimodevif \ + liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL + + ln -sf liboai_exmimodevif.so liboai_device.so + ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so + echo_info "liboai_device.so is linked to EXMIMO device library" + elif [ "$HW" == "OAI_USRP" ] ; then + compilations \ + $lte_build_dir oai_usrpdevif \ + liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL + + ln -sf liboai_usrpdevif.so liboai_device.so + ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so + echo_info "liboai_device.so is linked to USRP device library" + elif [ "$HW" == "OAI_BLADERF" ] ; then + if [ -f "/usr/include/libbladeRF.h" ] ; then + compilations \ + $lte_build_dir oai_bladerfdevif \ + liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL + fi + + ln -sf liboai_bladerfdevif.so liboai_device.so + ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so + echo_info "liboai_device.so is linked to BLADERF device library" + elif [ "$HW" == "OAI_LMSSDR" ] ; then + # if [ -f "/usr/include/libbladeRF.h" ] ; then + compilations \ + $lte_build_dir oai_lmssdrdevif \ + liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL + # fi + + ln -sf liboai_lmssdrdevif.so liboai_device.so + ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so + echo_info "liboai_device.so is linked to LMSSDR device library" + elif [ "$HW" == "OAI_IRIS" ] ; then + compilations \ + $lte_build_dir oai_irisdevif \ + liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL + + ln -s liboai_irisdevif.so liboai_device.so + ln -s $dbin/liboai_irisdevif.so.$REL $dbin/liboai_device.so + echo_info "liboai_device.so is linked to IRIS device library" + else + echo_info "liboai_device.so is not linked to any device library" + fi + fi + + # build simulators devices + echo_info "Compiling rfsimulator" + compilations \ + $lte_build_dir rfsimulator \ + librfsimulator.so $dbin/librfsimulator.so.$REL + echo_info "Compiling basicsimulator" + compilations \ + $lte_build_dir tcp_bridge_oai \ + libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL + # build transport protocol libraries (currently only ETHERNET is available) - - # Telnet server compilation - ##################### - if [ "$BUILD_TELNETSRV" = "1" ] ; then - build_dir=$lte_build_dir - compilations \ - $build_dir telnetsrv \ - libtelnetsrv.so $dbin/libtelnetsrv.so - - fi - # Telnet server compilation - ##################### - if [ "$MSC_GEN" = "1" ] ; then - build_dir=$lte_build_dir - compilations \ - $build_dir msc \ - libmsc.so $dbin/libmsc.so - - fi - # build RF device and transport protocol libraries - ##################################### - if [ "$eNB" = "1" -o "$UE" = "1" ] ; then - - build_dir=$lte_build_dir - - # build RF device libraries - if [ "$HW" != "None" ] ; then - rm -f liboai_device.so - rm -f $dbin/liboai_device.so - - # link liboai_device.so with the selected RF device library - if [ "$HW" == "EXMIMO" ] ; then - compilations \ - $build_dir oai_exmimodevif \ - liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL - - ln -sf liboai_exmimodevif.so liboai_device.so - ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so - echo_info "liboai_device.so is linked to EXMIMO device library" - elif [ "$HW" == "OAI_USRP" ] ; then - compilations \ - $build_dir oai_usrpdevif \ - liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL - - ln -sf liboai_usrpdevif.so liboai_device.so - ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so - echo_info "liboai_device.so is linked to USRP device library" - elif [ "$HW" == "OAI_BLADERF" ] ; then - if [ -f "/usr/include/libbladeRF.h" ] ; then - compilations \ - $build_dir oai_bladerfdevif \ - liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL - fi - - ln -sf liboai_bladerfdevif.so liboai_device.so - ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so - echo_info "liboai_device.so is linked to BLADERF device library" - elif [ "$HW" == "OAI_LMSSDR" ] ; then -# if [ -f "/usr/include/libbladeRF.h" ] ; then - compilations \ - $build_dir oai_lmssdrdevif \ - liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL -# fi - - ln -sf liboai_lmssdrdevif.so liboai_device.so - ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so - echo_info "liboai_device.so is linked to LMSSDR device library" - elif [ "$HW" == "OAI_IRIS" ] ; then - compilations \ - $build_dir oai_irisdevif \ - liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL - - ln -s liboai_irisdevif.so liboai_device.so - ln -s $dbin/liboai_irisdevif.so.$REL $dbin/liboai_device.so - echo_info "liboai_device.so is linked to IRIS device library" - else - echo_info "liboai_device.so is not linked to any device library" - fi - fi - - # build trasport protocol libraries (currently only ETHERNET is available) - if [ "$TP" != "None" ] ; then - rm -f liboai_transpro.so - rm -f $dbin/liboai_transpro.so - - if [ "$TP" == "ETHERNET" ] ; then - compilations \ - $build_dir oai_eth_transpro \ - liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL - ln -sf liboai_eth_transpro.so liboai_transpro.so - ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so - echo_info "liboai_transpro.so is linked with ETHERNET library" - fi - fi -fi - + rm -f liboai_transpro.so + rm -f $dbin/liboai_transpro.so + compilations \ + $lte_build_dir oai_eth_transpro \ + liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL + ln -sf liboai_eth_transpro.so liboai_transpro.so + ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so + echo_info "liboai_transpro.so is linked to ETHERNET transport" + fi + + if [ "$RFSIMULATOR" == "true" -o "$HW" == "OAI_SIMU" ] ; then + echo_info "Compiling rfsimulator" + compilations \ + $lte_build_dir rfsimulator \ + librfsimulator.so $dbin/librfsimulator.so.$REL + fi # Doxygen Support ##################### diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index dd8c2e54db..dc8ac26d0d 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -33,7 +33,7 @@ #include "phy_init.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h" - +#include "targets/RT/USER/lte-softmodem.h" extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; extern RU_t *ru; @@ -169,12 +169,12 @@ void lte_param_init(PHY_VARS_eNB **eNBp, } else ru->N_TA_offset=0; -#if BASIC_SIMULATOR + if (IS_SOFTMODEM_BASICSIM) /* this is required for the basic simulator in TDD mode * TODO: find a proper cleaner solution */ - UE->N_TA_offset = 0; -#endif + UE->N_TA_offset = 0; + printf("Done lte_param_init\n"); diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 6b5863edc9..d4e870fb0c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -45,7 +45,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/LTE_TRANSPORT/transport_extern.h" #include "PHY/LTE_REFSIG/lte_refsig.h" - +#include "targets/RT/USER/lte-softmodem.h" //#define DEBUG_DCI_ENCODING 1 //#define DEBUG_DCI_DECODING 1 //#define DEBUG_PHY @@ -328,26 +328,25 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, y[0] = &yseq0[0]; y[1] = &yseq1[0]; -#if BASIC_SIMULATOR + if (IS_SOFTMODEM_BASICSIM){ /* this should be the normal case * but it has to be validated for all the various cases * so let's just do it for the basic simulator */ - memset(e, 2, DCI_BITS_MAX); -#else -#if 1 +// memset(e, 2, DCI_BITS_MAX); + } else { // reset all bits to , here we set elements as 2 // memset(e, 2, DCI_BITS_MAX); // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. - for (i=0; inb_antenna_ports_eNB == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15; //printf("[PSS] amp=%d, a=%d\n",amp,a); -#if BASIC_SIMULATOR + if (IS_SOFTMODEM_BASICSIM) /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */ - a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15; -#endif + a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15; Nsymb = (frame_parms->Ncp==NORMAL)?14:12; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 64a41e8298..4af273b8b0 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2139,5 +2139,7 @@ int main(int argc, char **argv) { else return(0); } - - +/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +uint64_t get_softmodem_optmask(void) { + return 0; +} diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 0c17e21acc..221cc708f3 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -1509,5 +1509,7 @@ int main(int argc, char **argv) { return(0); } - - +/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +uint64_t get_softmodem_optmask(void) { + return 0; +} diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index cddd409922..d70d7030ab 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -810,32 +810,33 @@ rrc_ue_establish_drb( (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, RADIO_ACCESS_BEARER,Rlc_info_um); */ - if(PDCP_USE_NETLINK) { -# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) + if(!EPC_MODE_ENABLED) { +//# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) ip_addr_offset3 = 0; ip_addr_offset4 = 1; LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); - oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP, // interface_id + oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id ip_addr_offset3+ue_mod_idP+1, // third_octet - ip_addr_offset4+ue_mod_idP+1); // fourth_octet + ip_addr_offset4+ue_mod_idP+1, // fourth_octet + "ue"); // interface suffix - if (oip_ifup == 0 ) { // interface is up --> send a config the DRB - LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", + if (oip_ifup == 0 && (!IS_SOFTMODEM_NOKRNMOD)) { // interface is up --> send a config the DRB + LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, - (long int)((eNB_index * maxDRB) + DRB_config->drb_Identity)); + (long int)((eNB_index * LTE_maxDRB) + DRB_config->drb_Identity)); rb_conf_ipv4(0,//add ue_mod_idP,//cx align with the UE index ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index - (eNB_index * maxDRB) + DRB_config->drb_Identity,//rb + (eNB_index * LTE_maxDRB) + DRB_config->drb_Identity,//rb 0,//dscp ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); } -# endif +//# endif } return(0); @@ -1930,7 +1931,7 @@ rrc_ue_process_rrcConnectionReconfiguration( for (i=0; ( icriticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) - && (i < maxDRB); i++) { + && (i < LTE_maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reestablishment_ind.drb_id[i] = rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; @@ -2241,7 +2242,7 @@ rrc_ue_decode_dcch( for (i=0; ( imessage.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) - && (i < maxDRB); i++) { + && (i < LTE_maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reconfiguration_ho_ind.drb_id[i] = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; @@ -2295,7 +2296,7 @@ rrc_ue_decode_dcch( for (i=0; ( imessage.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) - && (i < maxDRB); i++) { + && (i < LTE_maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reconfiguration_ind.drb_id[i] = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 3503956b10..d377f3a8d6 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6272,30 +6272,30 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); - - if (PDCP_USE_NETLINK && (!LINK_ENB_PDCP_TO_GTPV1U)) { + if (!EPC_MODE_ENABLED) { +// if (PDCP_USE_NETLINK && (!LINK_ENB_PDCP_TO_GTPV1U)) { // can mean also IPV6 since ether -> ipv6 autoconf -# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) +//# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", ctxt_pP->module_id, ctxt_pP->module_id); oip_ifup = nas_config( ctxt_pP->module_id, // interface index - ctxtReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA_pP->module_id + 1, // thrid octet - ctxt_pP->module_id + 1); // fourth octet - + ctxt_pP->module_id + 1, // thrid octet + ctxt_pP->module_id + 1, // fourth octet + "enb"); if (oip_ifup == 0) { // interface is up --> send a config the DRB module_id_t ue_module_id; dest_ip_offset = 8; LOG_I(OIP, "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ctxt_pP->module_id, ctxt_pP->module_id, - (long int)((ue_context_pP->local_uid * maxDRB) + DRB_configList->list.array[i]->drb_Identity)); + (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity)); ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; rb_conf_ipv4(0, //add ue_module_id, //cx ctxt_pP->module_id, //inst - (ue_module_id * maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB + (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB 0, //dscp ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr @@ -6303,7 +6303,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); } -# endif +//# endif } LOG_D(RRC, diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index c0f6d622aa..96ef60c13a 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -44,7 +44,7 @@ #include "nas_config.h" #include "common/utils/LOG/log.h" - +#include "targets/RT/USER/lte-softmodem.h" //default values according to the examples, @@ -236,18 +236,20 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br } // non blocking full configuration of the interface (address, and the two lest octets of the address) -int nas_config(int interface_id, int thirdOctet, int fourthOctet) +int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix) { //char buf[5]; char ipAddress[20]; char broadcastAddress[20]; - char interfaceName[8]; + char interfaceName[20]; int returnValue; sprintf(ipAddress, "10.0.%d.%d", thirdOctet,fourthOctet); sprintf(broadcastAddress, "10.0.%d.255", thirdOctet); - sprintf(interfaceName, "oai%d", interface_id); + + sprintf(interfaceName, "%s%s%d", UE_NAS_USE_TUN?"oaitun_":"oip", + UE_NAS_USE_TUN?ifsuffix:"",interface_id); bringInterfaceUp(interfaceName, 0); // sets the machine address diff --git a/openair2/RRC/NAS/nas_config.h b/openair2/RRC/NAS/nas_config.h index 4426ca9a1a..c6c60baf0b 100644 --- a/openair2/RRC/NAS/nas_config.h +++ b/openair2/RRC/NAS/nas_config.h @@ -54,7 +54,7 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br * \note * @ingroup ????? */ -int nas_config(int interface_id, int thirdOctet, int fourthOctet); +int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix); /*! \fn int blocking_NAS_config(char*, char*, char*, char*) * \brief This function initializes the nasmesh interface, in a blocking way, diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index b62eb9d2df..06b08dfc40 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -37,6 +37,7 @@ #include "common_lib.h" #include "common/utils/load_module_shlib.h" +#include "targets/RT/USER/lte-softmodem.h" int set_device(openair0_device *device) { @@ -96,13 +97,20 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param loader_shlibfunc_t shlib_fdesc[1]; int ret=0; char *libname; - if (flag == RAU_LOCAL_RADIO_HEAD) { + if ( IS_SOFTMODEM_BASICSIM ) { + libname=OAI_BASICSIM_LIBNAME; + shlib_fdesc[0].fname="device_init"; + } else + if ( IS_SOFTMODEM_RFSIM ) { + libname=OAI_RFSIM_LIBNAME; + shlib_fdesc[0].fname="device_init"; + } else if (flag == RAU_LOCAL_RADIO_HEAD) { libname=OAI_RF_LIBNAME; shlib_fdesc[0].fname="device_init"; - } else { + } else { libname=OAI_TP_LIBNAME; shlib_fdesc[0].fname="transport_init"; - } + } ret=load_module_shlib(libname,shlib_fdesc,1,NULL); if (ret < 0) { fprintf(stderr,"Library %s couldn't be loaded\n",libname); diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 084ef9fcd9..de9acc3ab5 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -39,7 +39,10 @@ #define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ #define OAI_TP_LIBNAME "oai_transpro" - +/* name of shared library implementing the basic/rf simulator */ +#define OAI_RFSIM_LIBNAME "rfsimulator" +/* name of shared library implementing the basic/rf simulator */ +#define OAI_BASICSIM_LIBNAME "tcp_bridge_oai" /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 #define RAU_REMOTE_RADIO_HEAD 1 diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 89ca097bb5..fd84c66c75 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1381,12 +1381,12 @@ int setup_RU_buffers(RU_t *ru) { else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; -#if BASIC_SIMULATOR + if(IS_SOFTMODEM_BASICSIM) /* this is required for the basic simulator in TDD mode * TODO: find a proper cleaner solution */ ru->N_TA_offset = 0; -#endif + } if (ru->openair0_cfg.mmapped_dma == 1) { diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index 0a63797536..e121e31a39 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -58,6 +58,8 @@ void get_common_options(void) { uint32_t noS1; uint32_t nokrnmod; uint32_t nonbiot; + uint32_t rfsim; + uint32_t basicsim; paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC; @@ -90,6 +92,16 @@ void get_common_options(void) { set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT); } + if (rfsim) { + set_softmodem_optmask(SOFTMODEM_RFSIM_BIT); + } + + if (basicsim) { + set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); + } +#if BASIC_SIMULATOR + set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); +#endif if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 9c736f8172..60920eb401 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -653,7 +653,7 @@ int main( int argc, char **argv ) { LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); - pdcp_module_init( ( IS_SOFTMODEM_NOS1 && !(IS_SOFTMODEM_NOKRNMOD))? (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT); + pdcp_module_init( ( IS_SOFTMODEM_NOS1 && !(IS_SOFTMODEM_NOKRNMOD))? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT); # if (RC.nb_inst > 0) { diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 39f997a71f..9b820e6e19 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -87,6 +87,7 @@ #define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" #define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" #define CONFIG_HLP_NOS1 "Disable s1 interface\n" +#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" @@ -199,7 +200,9 @@ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \ + {"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \ {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ } @@ -238,8 +241,8 @@ #define SOFTMODEM_NOS1_BIT (1<<0) #define SOFTMODEM_NOKRNMOD_BIT (1<<1) #define SOFTMODEM_NONBIOT_BIT (1<<2) -#define SOFTMODEM_BASICSIM_BIT (1<<10) - +#define SOFTMODEM_RFSIM_BIT (1<<10) +#define SOFTMODEM_BASICSIM_BIT (1<<11) typedef struct { uint64_t optmask; THREAD_STRUCT thread_struct; @@ -260,6 +263,7 @@ typedef struct { #define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) #define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) #define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) +#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) #define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT) extern uint64_t get_softmodem_optmask(void); extern uint64_t set_softmodem_optmask(uint64_t bitmask); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index f67dbeca7e..c8709f87c5 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -344,12 +344,12 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti } else UE->N_TA_offset = 0; -#if BASIC_SIMULATOR + if( IS_SOFTMODEM_BASICSIM) /* this is required for the basic simulator in TDD mode * TODO: find a proper cleaner solution */ - UE->N_TA_offset = 0; -#endif + UE->N_TA_offset = 0; + if (simL1flag == 1) init_ue_devices(UE); LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); @@ -875,9 +875,9 @@ static void *UE_thread_rxn_txnp4(void *arg) { exit_fun("noting to add"); } proc->instance_cnt_rxtx--; -#if BASIC_SIMULATOR - if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); -#endif + if ( IS_SOFTMODEM_BASICSIM ) { + if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); + } if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); exit_fun("noting to add"); @@ -1570,12 +1570,12 @@ void *UE_thread(void *arg) { } while (!oai_exit) { -#if BASIC_SIMULATOR - while (!(UE->proc.instance_cnt_synch < 0)) { - printf("ue sync not ready\n"); - usleep(500*1000); - } -#endif + if (IS_SOFTMODEM_BASICSIM) + while (!(UE->proc.instance_cnt_synch < 0)) { + printf("ue sync not ready\n"); + usleep(500*1000); + } + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); int instance_cnt_synch = UE->proc.instance_cnt_synch; @@ -1665,17 +1665,15 @@ void *UE_thread(void *arg) { // update thread index for received subframe UE->current_thread_id[sub_frame] = thread_idx; -#if BASIC_SIMULATOR - { - int t; - for (t = 0; t < 2; t++) { - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; - pthread_mutex_lock(&proc->mutex_rxtx); - while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - pthread_mutex_unlock(&proc->mutex_rxtx); - } - } -#endif + if (IS_SOFTMODEM_BASICSIM) { + int t; + for (t = 0; t < 2; t++) { + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; + pthread_mutex_lock(&proc->mutex_rxtx); + while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + pthread_mutex_unlock(&proc->mutex_rxtx); + } + } LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); thread_idx++; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index b19d440b0d..78d5bebc43 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -441,10 +441,6 @@ static void get_options(void) { if (dumpframe > 0) mode = rx_dump_frame; -# if BASIC_SIMULATOR - set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); //this BASIC_SIMULATOR should be a config option -# endif - for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0]; } @@ -769,10 +765,11 @@ int main( int argc, char **argv ) { init_opt(); uint32_t pdcp_initmask = ((!IS_SOFTMODEM_NOS1) || IS_SOFTMODEM_NOKRNMOD)? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); - if ( IS_SOFTMODEM_BASICSIM || (nfapi_mode == 3) ) { + if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_mode == 3) ) { pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; } - + if ( IS_SOFTMODEM_NOKRNMOD) + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; pdcp_module_init( pdcp_initmask ); //TTN for D2D #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) From 17e36b3a65dc6d9d3b199f86f12c502974764629 Mon Sep 17 00:00:00 2001 From: frtabu Date: Tue, 5 Mar 2019 08:06:23 +0100 Subject: [PATCH 02/26] add ocp/frf/enhanced basic simulator sources --- targets/ARCH/rfsimulator/README.md | 68 ++++ targets/ARCH/rfsimulator/simulator.c | 475 +++++++++++++++++++++++++++ 2 files changed, 543 insertions(+) create mode 100644 targets/ARCH/rfsimulator/README.md create mode 100644 targets/ARCH/rfsimulator/simulator.c diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md new file mode 100644 index 0000000000..89964decd5 --- /dev/null +++ b/targets/ARCH/rfsimulator/README.md @@ -0,0 +1,68 @@ +#General +This is a RF simulator that allows to test OAI without a RF board. +It replaces a actual RF board driver. + +As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound) + +#build + +## From build_oai +You can build it the same way, and together with actual RF driver + +Example: +```bash +./build_oai --ue-nas-use-tun --UE --eNB -w SIMU +``` +It is also possible to build actual RF and use choose on each run: +```bash +./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator +``` +Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem) +We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver. + +## Add the rfsimulator after initial build +After any regular build, you can compile the driver +```bash +cd /build +make rfsimulator +``` +Then, you can use it freely + +# Usage +Setting the env variable RFSIMULATOR enables the RF board simulator +It should the set to "enb" in the eNB + +## 4G case +For the UE, it should be set to the IP address of the eNB +example: +```bash +sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 +``` +Except this, the UE and the eNB can be used as it the RF is real + +If you reach 'RA not active' on UE, be careful to generate a valid SIM +```bash +$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . +``` +## 5G case +After regular build, add the simulation driver +(don't use ./build_oai -w SIMU until we merge 4G and 5G branches) +```bash +cd ran_build/build +make rfsimulator +``` +### Launch gNB in one window +```bash +sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD +``` +### Launch UE in another window +```bash +sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 +``` +Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine +In UE, you can add "-d" to get the softscope + +#Caveacts +Still issues in power control: txgain, rxgain are not used + +no S1 mode is currently broken, so we were not able to test the simulator in noS1 mode diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c new file mode 100644 index 0000000000..a17327b03e --- /dev/null +++ b/targets/ARCH/rfsimulator/simulator.c @@ -0,0 +1,475 @@ +/* + Author: Laurent THOMAS, Open Cells for Nokia + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "common_lib.h" +#include +#include "openair1/PHY/defs_UE.h" + +#define PORT 4043 //TCP port for this simulator +#define CirSize 3072000 // 100ms is enough +#define sample_t uint32_t // 2*16 bits complex number +#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) +#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) +#define MAGICeNB 0xA5A5A5A5A5A5A5A5 +#define MAGICUE 0x5A5A5A5A5A5A5A5A + +typedef struct { + uint64_t magic; + uint32_t size; + uint32_t nbAnt; + uint64_t timestamp; +} transferHeader; + +typedef struct buffer_s { + int conn_sock; + bool alreadyRead; + uint64_t lastReceivedTS; + bool headerMode; + transferHeader th; + char *transferPtr; + uint64_t remainToTransfer; + char *circularBufEnd; + sample_t *circularBuf; +} buffer_t; + +typedef struct { + int listen_sock, epollfd; + uint64_t nextTimestamp; + uint64_t typeStamp; + uint64_t initialAhead; + char *ip; + buffer_t buf[FD_SETSIZE]; +} rfsimulator_state_t; + +void allocCirBuf(rfsimulator_state_t *bridge, int sock) { + buffer_t *ptr=&bridge->buf[sock]; + AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); + ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); + ptr->conn_sock=sock; + ptr->headerMode=true; + ptr->transferPtr=(char *)&ptr->th; + ptr->remainToTransfer=sizeof(transferHeader); + int sendbuff=1000*1000*10; + AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); + struct epoll_event ev= {0}; + ev.events = EPOLLIN | EPOLLRDHUP; + ev.data.fd = sock; + AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, ""); +} + +void removeCirBuf(rfsimulator_state_t *bridge, int sock) { + AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); + close(sock); + free(bridge->buf[sock].circularBuf); + memset(&bridge->buf[sock], 0, sizeof(buffer_t)); + bridge->buf[sock].conn_sock=-1; +} + +void socketError(rfsimulator_state_t *bridge, int sock) { + if (bridge->buf[sock].conn_sock!=-1) { + LOG_W(HW,"Lost socket \n"); + removeCirBuf(bridge, sock); + + if (bridge->typeStamp==MAGICUE) + exit(1); + } +} + + +#define helpTxt "\ +\x1b[31m\ +rfsimulator: error: you have to run one UE and one eNB\n\ +For this, export RFSIMULATOR=enb (eNB case) or \n\ + RFSIMULATOR= (UE case)\n\ +\x1b[m" + +enum blocking_t { + notBlocking, + blocking +}; + +void setblocking(int sock, enum blocking_t active) { + int opts; + AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,""); + + if (active==blocking) + opts = opts & ~O_NONBLOCK; + else + opts = opts | O_NONBLOCK; + + AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); +} + +static bool flushInput(rfsimulator_state_t *t); + +void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { + char *buf = _buf; + int l; + setblocking(fd, notBlocking); + + while (count) { + l = write(fd, buf, count); + + if (l <= 0) { + if (errno==EINTR) + continue; + + if(errno==EAGAIN) { + flushInput(t); + continue; + } else + return; + } + + count -= l; + buf += l; + } +} + +int server_start(openair0_device *device) { + rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; + t->typeStamp=MAGICeNB; + AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + int enable = 1; + AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: + htons(PORT), +sin_addr: + { s_addr: INADDR_ANY } + }; + bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr)); + AssertFatal(listen(t->listen_sock, 5) == 0, ""); + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = t->listen_sock; + AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, ""); + return 0; +} + +int start_ue(openair0_device *device) { + rfsimulator_state_t *t = device->priv; + t->typeStamp=MAGICUE; + int sock; + AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: + htons(PORT), +sin_addr: + { s_addr: INADDR_ANY } + }; + addr.sin_addr.s_addr = inet_addr(t->ip); + bool connected=false; + + while(!connected) { + LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", t->ip, PORT); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + LOG_I(HW,"rfsimulator: connection established\n"); + connected=true; + } + + perror("rfsimulator"); + sleep(1); + } + + setblocking(sock, notBlocking); + allocCirBuf(t, sock); + t->buf[sock].alreadyRead=true; // UE will start blocking on read + return 0; +} + +int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { + rfsimulator_state_t *t = device->priv; + + for (int i=0; ibuf[i]; + + if (ptr->conn_sock >= 0 ) { + transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp}; + fullwrite(ptr->conn_sock,&header, sizeof(header), t); + sample_t tmpSamples[nsamps][nbAnt]; + + for(int a=0; aconn_sock >= 0 ) + fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t); + } + } + + LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", + nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); + return nsamps; +} + +static bool flushInput(rfsimulator_state_t *t) { + // Process all incoming events on sockets + // store the data in lists + struct epoll_event events[FD_SETSIZE]= {0}; + int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200); + + if ( nfds==-1 ) { + if ( errno==EINTR || errno==EAGAIN ) + return false; + else + AssertFatal(false,"error in epoll_wait\n"); + } + + for (int nbEv = 0; nbEv < nfds; ++nbEv) { + int fd=events[nbEv].data.fd; + + if (events[nbEv].events & EPOLLIN && fd == t->listen_sock) { + int conn_sock; + AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); + setblocking(conn_sock, notBlocking); + allocCirBuf(t, conn_sock); + LOG_I(HW,"A ue connected\n"); + } else { + if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) { + socketError(t,fd); + continue; + } + + buffer_t *b=&t->buf[fd]; + + if ( b->circularBuf == NULL ) { + LOG_E(HW, "received data on not connected socket %d\n", events[nbEv].data.fd); + continue; + } + + int blockSz; + + if ( b->headerMode) + blockSz=b->remainToTransfer; + else + blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ? + b->remainToTransfer : + b->circularBufEnd - 1 - b->transferPtr ; + + int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT); + + if ( sz < 0 ) { + if ( errno != EAGAIN ) { + LOG_E(HW,"socket failed %s\n", strerror(errno)); + abort(); + } + } else if ( sz == 0 ) + continue; + + AssertFatal((b->remainToTransfer-=sz) >= 0, ""); + b->transferPtr+=sz; + + if (b->transferPtr==b->circularBufEnd - 1) + b->transferPtr=(char *)b->circularBuf; + + // check the header and start block transfer + if ( b->headerMode==true && b->remainToTransfer==0) { + AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) || + (t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol"); + b->headerMode=false; + b->alreadyRead=true; + + if ( b->lastReceivedTS != b->th.timestamp) { + int nbAnt= b->th.nbAnt; + + for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) + for (int a=0; a < nbAnt; a++) + b->circularBuf[(index*nbAnt+a)%CirSize]=0; + + LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); + } + + b->lastReceivedTS=b->th.timestamp; + b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize]; + b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt); + } + + if ( b->headerMode==false ) { + b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt); + + if ( b->remainToTransfer==0) { + LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS); + + // First block in UE, resync with the eNB current TS + if ( t->nextTimestamp == 0 ) + t->nextTimestamp=b->lastReceivedTS-b->th.size; + + b->headerMode=true; + b->transferPtr=(char *)&b->th; + b->remainToTransfer=sizeof(transferHeader); + b->th.magic=-1; + } + } + } + } + + return nfds>0; +} + +int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { + if (nbAnt != 1) { + LOG_E(HW, "rfsimulator: only 1 antenna tested\n"); + exit(1); + } + + rfsimulator_state_t *t = device->priv; + LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); + // deliver data from received data + // check if a UE is connected + int first_sock; + + for (first_sock=0; first_sockbuf[first_sock].circularBuf != NULL ) + break; + + if ( first_sock == FD_SETSIZE ) { + // no connected device (we are eNB, no UE is connected) + if (!flushInput(t)) { + for (int x=0; x < nbAnt; x++) + memset(samplesVoid[x],0,sampleToByte(nsamps,1)); + + t->nextTimestamp+=nsamps; + LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp); + *ptimestamp = t->nextTimestamp-nsamps; + return nsamps; + } + } else { + bool have_to_wait; + + do { + have_to_wait=false; + + for ( int sock=0; sockbuf[sock].circularBuf && + t->buf[sock].alreadyRead && //>= t->initialAhead && + (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) { + have_to_wait=true; + break; + } + + if (have_to_wait) + /*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n", + ptr->lastReceivedTS, + t->nextTimestamp+nsamps); + */ + flushInput(t); + } while (have_to_wait); + } + + // Clear the output buffer + for (int a=0; abuf[sock]; + + if ( ptr->circularBuf && ptr->alreadyRead ) { + for (int a=0; acircularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1; + } + } + } + + *ptimestamp = t->nextTimestamp; // return the time of the first sample + t->nextTimestamp+=nsamps; + LOG_D(HW,"Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n", + nsamps, + *ptimestamp, t->nextTimestamp, + signal_energy(samplesVoid[0], nsamps)); + return nsamps; +} + + +int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { + abort(); + return 0; +} +int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) { + abort(); + return 0; +} +int rfsimulator_get_stats(openair0_device *device) { + return 0; +} +int rfsimulator_reset_stats(openair0_device *device) { + return 0; +} +void rfsimulator_end(openair0_device *device) {} +int rfsimulator_stop(openair0_device *device) { + return 0; +} +int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { + return 0; +} +int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + return 0; +} + + +__attribute__((__visibility__("default"))) +int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + //set_log(HW,OAILOG_DEBUG); + rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); + + if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) { + LOG_E(HW,helpTxt); + exit(1); + } + + rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? + MAGICeNB: + MAGICUE; + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE"); + device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ? + server_start : + start_ue; + device->trx_get_stats_func = rfsimulator_get_stats; + device->trx_reset_stats_func = rfsimulator_reset_stats; + device->trx_end_func = rfsimulator_end; + device->trx_stop_func = rfsimulator_stop; + device->trx_set_freq_func = rfsimulator_set_freq; + device->trx_set_gains_func = rfsimulator_set_gains; + device->trx_write_func = rfsimulator_write; + device->trx_read_func = rfsimulator_read; + /* let's pretend to be a b2x0 */ + device->type = USRP_B200_DEV; + device->openair0_cfg=&openair0_cfg[0]; + device->priv = rfsimulator; + + for (int i=0; ibuf[i].conn_sock=-1; + + AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,""); + rfsimulator->initialAhead=openair0_cfg[0].sample_rate/1000; // One sub frame + return 0; +} From eb59c2cd689f93e68e1b170a3e4315e6007ac72e Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Thu, 31 Jan 2019 14:54:46 +0100 Subject: [PATCH 03/26] bugfix: fix realtime issues with RRC (race condition) When testing x2 handover, we found a race issue between the RRC thread and the phy/mac thread (which is calling rrc_rx_tx). The UE context was updated by the RRC thread but in the middle of the update (which consists of several function calls and variables' updates) the context was accessed by rrc_rx_tx. At this point, the context was in an inconsistent state. The solution is to access RRC data in the RRC thread only. The function rrc_rx_tx now just sends an ITTI message to the RRC thread. When receiving this message, the RRC thread does the processing that was done by the function rrc_rx_tx (in the new function rrc_subframe_process). This way, the race condition disappears. However we now send an ITTI message from the phy/mac thread to the RRC thread at each subframe. That might increase the processing time of the eNB. So maybe it's not the best solution. It may also improve the realtime performance because less work is done by the phy/mac realtime thread. To be checked somehow. Also, it may be possible that some other RRC functions are still called by the phy/mac thread, which should also be checked and replaced by ITTI messages (if this solution is considered to be correct). --- openair2/COMMON/rrc_messages_def.h | 3 + openair2/COMMON/rrc_messages_types.h | 8 + openair2/RRC/LTE/rrc_eNB.c | 478 ++++++++++++++------------- 3 files changed, 258 insertions(+), 231 deletions(-) diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 08ea93f427..4000545966 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -72,3 +72,6 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstab MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind) MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind) + +// eNB: realtime -> RRC messages +MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index f6e2216c1b..3880604e61 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -81,6 +81,8 @@ #define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind +#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process + //-------------------------------------------------------------------------------------------// typedef struct RrcStateInd_s { Rrc_State_t state; @@ -399,4 +401,10 @@ typedef nas_release_ind_t NasConnReleaseInd; typedef ul_info_transfer_cnf_t NasUlDataCnf; typedef dl_info_transfer_ind_t NasDlDataInd; +// eNB: realtime -> RRC messages +typedef struct rrc_subframe_process_s { + protocol_ctxt_t ctxt; + int CC_id; +} RrcSubframeProcess; + #endif /* RRC_MESSAGES_TYPES_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 3503956b10..50aa9d67d5 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -7897,6 +7897,241 @@ void rrc_enb_init(void) { memset(&rrc_release_info,0,sizeof(RRC_release_list_t)); } +//----------------------------------------------------------------------------- +void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) +{ + int32_t current_timestamp_ms = 0; + int32_t ref_timestamp_ms = 0; + struct timeval ts; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL; +#ifdef LOCALIZATION + double estimated_distance = 0; + protocol_ctxt_t ctxt; +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN); + check_handovers(ctxt_pP); // counter, get the value and aggregate + // check for UL failure or for UE to be released + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt_pP->rnti = ue_context_p->ue_id_rnti; + + if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.ul_failure_timer); + } else { + LOG_I(RRC, "UE rnti %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ul_failure_timer); + } + } + + if (ue_context_p->ue_context.ul_failure_timer > 0) { + ue_context_p->ue_context.ul_failure_timer++; + + if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + // remove UE after 20 seconds after MAC (or else) has indicated UL failure + LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", + ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { + ue_context_p->ue_context.ue_release_timer_s1++; + + if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { + LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ue_release_timer_thres_s1); + + if (EPC_MODE_ENABLED) + rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); + else + ue_to_be_removed = ue_context_p; + + ue_context_p->ue_context.ue_release_timer_s1 = 0; + break; // break RB_FOREACH + } // end if timer_s1 timeout + } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) + + if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { + ue_context_p->ue_context.ue_release_timer_rrc++; + + if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + pthread_mutex_lock(&rrc_release_freelist); + + if (rrc_release_info.num_UEs > 0) { + uint16_t release_total = 0; + + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { + release_total++; + } + + if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && + (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { + ue_context_p->ue_context.ue_release_timer_rrc = 1; + ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; + + if (EPC_MODE_ENABLED) { + int e_rab = 0; + MessageDef *msg_complete_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); + msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; + itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); + } + + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + // do not wait response + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); + + if (rrc_ue_s1ap_ids != NULL) { + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); + } + } /* EPC_MODE_ENABLED */ + + rrc_release_info.RRC_release_ctrl[release_num].flag = 0; + rrc_release_info.num_UEs--; + break; // break for (release_num) + } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... + + if (release_total >= rrc_release_info.num_UEs) { + break; // break for (release_num) + } + } // end for (release_num) + } // end if (rrc_release_info.num_UEs > 0) + + pthread_mutex_unlock(&rrc_release_freelist); + + if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { + ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer + + if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", + ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { + ue_context_p->ue_context.ue_reestablishment_timer++; + + if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_release_timer > 0) { + ue_context_p->ue_context.ue_release_timer++; + + if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", + ue_context_p->ue_context.rnti); + /* + * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. + * It is no more the case. + * The timer should be renamed. + */ + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_release_timer = 0; + break; // break RB_FOREACH + } + } + } // end RB_FOREACH + + if (ue_to_be_removed) { + if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || + ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { + ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; + ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; + ue_to_be_removed->ue_context.ue_release_timer = 0; + ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; + } + + rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); + + if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { + ue_to_be_removed->ue_context.ul_failure_timer = 0; + } + + if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { + ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent + } + } + +#ifdef RRC_LOCALIZATION + /* for the localization, only primary CC_id might be relevant*/ + gettimeofday(&ts, NULL); + current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; + ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt = *ctxt_pP; + ctxt.rnti = ue_context_p->ue_context.rnti; + estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); + + if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && + estimated_distance != -1) { + LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", + ctxt.rnti, + ctxt_pP->module_id, + current_timestamp_ms, + ctxt_pP->frame, + estimated_distance); + LOG_D(LOCALIZE, "RRC status %d\n", + ue_context_p->ue_context.Status); + push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); + RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; + } // end if + } // end RB_FOREACH +#endif + (void)ts; /* remove gcc warning "unused variable" */ + (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ + (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); +} + //----------------------------------------------------------------------------- void *rrc_enb_process_itti_msg(void *notUsed) { MessageDef *msg_p; @@ -7910,7 +8145,9 @@ void *rrc_enb_process_itti_msg(void *notUsed) { itti_receive_msg(TASK_RRC_ENB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); instance = ITTI_MSG_INSTANCE(msg_p); - LOG_I(RRC,"Received message %s\n",msg_name_p); + /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ + if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) + LOG_I(RRC,"Received message %s\n",msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -8059,6 +8296,10 @@ void *rrc_enb_process_itti_msg(void *notUsed) { openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p)); break; + case RRC_SUBFRAME_PROCESS: + rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); + break; + default: LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p); break; @@ -8434,236 +8675,11 @@ rrc_rx_tx( ) //----------------------------------------------------------------------------- { - int32_t current_timestamp_ms = 0; - int32_t ref_timestamp_ms = 0; - struct timeval ts; - struct rrc_eNB_ue_context_s *ue_context_p = NULL; - struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL; -#ifdef LOCALIZATION - double estimated_distance = 0; - protocol_ctxt_t ctxt; -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN); - check_handovers(ctxt_pP); // counter, get the value and aggregate - // check for UL failure or for UE to be released - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt_pP->rnti = ue_context_p->ue_id_rnti; - - if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { - LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.ul_failure_timer); - } else { - LOG_I(RRC, "UE rnti %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ul_failure_timer); - } - } - - if (ue_context_p->ue_context.ul_failure_timer > 0) { - ue_context_p->ue_context.ul_failure_timer++; - - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC (or else) has indicated UL failure - LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", - ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { - ue_context_p->ue_context.ue_release_timer_s1++; - - if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { - LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ue_release_timer_thres_s1); - - if (EPC_MODE_ENABLED) - rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); - else - ue_to_be_removed = ue_context_p; - - ue_context_p->ue_context.ue_release_timer_s1 = 0; - break; // break RB_FOREACH - } // end if timer_s1 timeout - } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) - - if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { - ue_context_p->ue_context.ue_release_timer_rrc++; - - if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { - LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", - ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - pthread_mutex_lock(&rrc_release_freelist); - - if (rrc_release_info.num_UEs > 0) { - uint16_t release_total = 0; - - for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { - if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { - release_total++; - } - - if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && - (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { - ue_context_p->ue_context.ue_release_timer_rrc = 1; - ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; - - if (EPC_MODE_ENABLED) { - int e_rab = 0; - MessageDef *msg_complete_p = NULL; - MessageDef *msg_delete_tunnels_p = NULL; - uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - - if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); - S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); - } - - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - // do not wait response - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - - for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = - ue_context_p->ue_context.enb_gtp_ebi[e_rab]; - // erase data - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } - - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); - - if (rrc_ue_s1ap_ids != NULL) { - rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); - } - } /* EPC_MODE_ENABLED */ - - rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; - break; // break for (release_num) - } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... - - if (release_total >= rrc_release_info.num_UEs) { - break; // break for (release_num) - } - } // end for (release_num) - } // end if (rrc_release_info.num_UEs > 0) - - pthread_mutex_unlock(&rrc_release_freelist); - - if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { - ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer - - if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", - ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { - ue_context_p->ue_context.ue_reestablishment_timer++; - - if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", - ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_release_timer > 0) { - ue_context_p->ue_context.ue_release_timer++; - - if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", - ue_context_p->ue_context.rnti); - /* - * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. - * It is no more the case. - * The timer should be renamed. - */ - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_release_timer = 0; - break; // break RB_FOREACH - } - } - } // end RB_FOREACH - - if (ue_to_be_removed) { - if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || - ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && - (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { - ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; - ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; - ue_to_be_removed->ue_context.ue_release_timer = 0; - ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; - } - - rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); - - if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { - ue_to_be_removed->ue_context.ul_failure_timer = 0; - } - - if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && - (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { - ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent - } - } - -#ifdef RRC_LOCALIZATION - /* for the localization, only primary CC_id might be relevant*/ - gettimeofday(&ts, NULL); - current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; - ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt = *ctxt_pP; - ctxt.rnti = ue_context_p->ue_context.rnti; - estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); - - if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && - estimated_distance != -1) { - LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", - ctxt.rnti, - ctxt_pP->module_id, - current_timestamp_ms, - ctxt_pP->frame, - estimated_distance); - LOG_D(LOCALIZE, "RRC status %d\n", - ue_context_p->ue_context.Status); - push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); - RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; - } // end if - } // end RB_FOREACH -#endif - (void)ts; /* remove gcc warning "unused variable" */ - (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ - (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_SUBFRAME_PROCESS); + RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt_pP; + RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; + itti_send_msg_to_task(TASK_RRC_ENB, ctxt_pP->module_id, message_p); return RRC_OK; } From ca19953200ec0e54cf476f141f524f8193c2647f Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Thu, 31 Jan 2019 15:15:56 +0100 Subject: [PATCH 04/26] x2ap: bugfixes Store UE Capability at target, Key derivation (keNB star) at source --- openair2/RRC/LTE/rrc_eNB.c | 78 ++++++++++++++++++++------------ openair2/RRC/LTE/rrc_eNB_S1AP.c | 4 +- openair2/X2AP/x2ap_eNB_handler.c | 4 +- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 50aa9d67d5..4754abfe53 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -105,6 +105,9 @@ extern uint16_t two_tier_hexagonal_cellIds[7]; mui_t rrc_eNB_mui = 0; extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); +extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP); +extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP); +extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t * kenb_star); void openair_rrc_on( @@ -3800,6 +3803,9 @@ rrc_eNB_process_MeasurementReport( int neighboring_cells=-1; int ncell_index = 0; long ncell_max = -150; + uint32_t earfcn_dl; + uint8_t KeNB_star[32] = { 0 }; + T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -3929,9 +3935,11 @@ rrc_eNB_process_MeasurementReport( // Don't know how to get this ID? X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id; X2AP_HANDOVER_REQ(msg).security_capabilities = ue_context_pP->ue_context.security_capabilities; - memcpy (X2AP_HANDOVER_REQ(msg).kenb, - ue_context_pP->ue_context.kenb, - 32); + // compute keNB* + earfcn_dl = (uint32_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq, + RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL); + derive_keNB_star(ue_context_pP->ue_context.kenb, X2AP_HANDOVER_REQ(msg).target_physCellId, earfcn_dl, true, KeNB_star); + memcpy(X2AP_HANDOVER_REQ(msg).kenb, KeNB_star, 32); X2AP_HANDOVER_REQ(msg).kenb_ncc = ue_context_pP->ue_context.kenb_ncc; //X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr; X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ue_context_pP->ue_context.setup_e_rabs; @@ -4078,9 +4086,9 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re int rnti = taus() & 0xffff; int i; //global_rnti = rnti; - //HandoverPreparationInformation_t *ho = NULL; - //HandoverPreparationInformation_r8_IEs_t *ho_info; - //asn_dec_rval_t dec_rval; + LTE_HandoverPreparationInformation_t *ho = NULL; + LTE_HandoverPreparationInformation_r8_IEs_t *ho_info; + asn_dec_rval_t dec_rval; ue_context_target_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (ue_context_target_p != NULL) { @@ -4114,16 +4122,20 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re ue_context_target_p->ue_context.kenb_ncc = m->kenb_ncc; ue_context_target_p->ue_context.security_capabilities.encryption_algorithms = m->security_capabilities.encryption_algorithms; ue_context_target_p->ue_context.security_capabilities.integrity_algorithms = m->security_capabilities.integrity_algorithms; - /* + dec_rval = uper_decode(NULL, - &asn_DEF_HandoverPreparationInformation, + &asn_DEF_LTE_HandoverPreparationInformation, (void **)&ho, m->rrc_buffer, m->rrc_buffer_size, 0, 0); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_HandoverPreparationInformation, ho); + } + if (dec_rval.code != RC_OK || - ho->criticalExtensions.present != HandoverPreparationInformation__criticalExtensions_PR_c1 || - ho->criticalExtensions.choice.c1.present != HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) { + ho->criticalExtensions.present != LTE_HandoverPreparationInformation__criticalExtensions_PR_c1 || + ho->criticalExtensions.choice.c1.present != LTE_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) { LOG_E(RRC, "could not decode Handover Preparation\n"); abort(); } @@ -4132,13 +4144,13 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re if (ue_context_target_p->ue_context.UE_Capability) { LOG_I(RRC, "freeing old UE capabilities for UE %x\n", rnti); - ASN_STRUCT_FREE(asn_DEF_UE_EUTRA_Capability, + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability); ue_context_target_p->ue_context.UE_Capability = 0; } dec_rval = uper_decode(NULL, - &asn_DEF_UE_EUTRA_Capability, + &asn_DEF_LTE_UE_EUTRA_Capability, (void **)&ue_context_target_p->ue_context.UE_Capability, ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.buf, ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size, 0, 0); @@ -4146,16 +4158,16 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re ue_context_target_p->ue_context.UE_Capability_size = ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability); + xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability); } if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(RRC, "Failed to decode UE capabilities (%zu bytes)\n", dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_UE_EUTRA_Capability, + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability); ue_context_target_p->ue_context.UE_Capability = 0; } - */ + ue_context_target_p->ue_context.nb_of_e_rabs = m->nb_e_rabs_tobesetup; ue_context_target_p->ue_context.setup_e_rabs = m->nb_e_rabs_tobesetup; ue_context_target_p->ue_context.mme_ue_s1ap_id = m->mme_ue_s1ap_id; @@ -4239,7 +4251,6 @@ check_handovers( ) //----------------------------------------------------------------------------- { - int result; struct rrc_eNB_ue_context_s *ue_context_p; RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { ctxt_pP->rnti = ue_context_p->ue_id_rnti; @@ -4256,19 +4267,15 @@ check_handovers( LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n", ctxt_pP->module_id, ctxt_pP->frame, ue_context_p->ue_context.rnti); - result = pdcp_data_req(ctxt_pP, - SRB_FLAG_YES, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - ue_context_p->ue_context.handover_info->size, - ue_context_p->ue_context.handover_info->buf, - PDCP_TRANSMISSION_MODE_CONTROL -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - AssertFatal(result == TRUE, "PDCP data request failed!\n"); + rrc_data_req( + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + ue_context_p->ue_context.handover_info->size, + ue_context_p->ue_context.handover_info->buf, + PDCP_TRANSMISSION_MODE_CONTROL); + ue_context_p->ue_context.handover_info->state = HO_COMPLETE; LOG_I(RRC, "RRC Sends RRCConnectionReconfiguration to UE %d at frame %d and subframe %d \n", ue_context_p->ue_context.rnti, ctxt_pP->frame,ctxt_pP->subframe); } @@ -5306,6 +5313,19 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc , 0, 0 #endif ); + rrc_eNB_process_security ( + ctxt_pP, + ue_context_p, + &ue_context_p->ue_context.security_capabilities); + process_eNB_security_key ( + ctxt_pP, + ue_context_p, + ue_context_p->ue_context.kenb); + rrc_pdcp_config_security( + ctxt_pP, + ue_context_p, + FALSE); + // Add a new user (called during the HO procedure) LOG_I(RRC, "rrc_eNB_target_add_ue_handover module_id %d rnti %d\n", ctxt_pP->module_id, ctxt_pP->rnti); // Configure MAC for the target diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index e07a4bd5d2..84f166e9e3 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -426,7 +426,7 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte *\param security_capabilities The security capabilities received from S1AP. *\return TRUE if at least one algorithm has been changed else FALSE. */ -static int +int rrc_eNB_process_security( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, @@ -477,7 +477,7 @@ rrc_eNB_process_security( *\param security_key_pP The security key received from S1AP. */ //------------------------------------------------------------------------------ -static void process_eNB_security_key ( +void process_eNB_security_key ( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 52b14f1d23..b3b83a7e69 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -671,8 +671,8 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s*/) { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } - memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); - X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; + memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); + X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg); From 4b5c42115d0679341b88d0bbb649807cc0474aee Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Tue, 5 Feb 2019 12:24:30 +0100 Subject: [PATCH 05/26] bugfix: Path switch request ack (manage re-established/released E-RABs) --- openair2/RRC/LTE/rrc_eNB_S1AP.c | 76 ++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 84f166e9e3..d80c45d699 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1958,7 +1958,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr = create_tunnel_resp.enb_addr; LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d): nb_of_e_rabs %d, e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ", e_rabs_done, e_rab, ue_context_pP->ue_context.e_rab[inde_list[e_rab]].status, - ue_context_pP->ue_context.nb_of_e_rabs, + S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id, S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid, S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[0], @@ -1970,7 +1970,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, // NN: add conditions for e_rabs_failed if (e_rabs_done > 0) { LOG_I(RRC,"S1AP_PATH_SWITCH_REQ: sending the message: nb_of_erabstobeswitched %d, total e_rabs %d, index %d\n", - ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); + S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_S1AP_ENB, @@ -2017,46 +2017,64 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg ue_context_p->ue_context.mme_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).mme_ue_s1ap_id; /* Save e RAB information for later */ { + ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased; + for (i = 0; - i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg - i++) { - // assume that we are releasing all the DRBs - ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE; + i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg + i++) { + // assume that we are releasing all the DRBs + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED; + if (ue_context_p->ue_context.nb_release_of_e_rabs==0) { + LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); + } } //memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); - //uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched; + uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched; // keep the previous bearer // the index for the rec - for (i = 0; - i < 1;//nb_e_rabs_tobeswitched; // go over total number of e_rabs received through x2_ho_req msg - i++) { - LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); - /* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */ - ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED; - //ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].e_rab_id; - //ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].sgw_addr; - //ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].gtp_teid; - /* Tunnel must have been already created in X2_HO_REQ procedure */ + if (nb_e_rabs_tobeswitched>0) { + int e_rab_switch_index=0; + for (i = 0; + i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg + i++) { + /* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */ + if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id) { + ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id; + ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].sgw_addr; + ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].gtp_teid; + e_rab_switch_index++; + } + } } - - ue_context_p->ue_context.setup_e_rabs=i; - ue_context_p->ue_context.nb_of_e_rabs=i; } ue_context_p->ue_context.ue_ambr=S1AP_PATH_SWITCH_REQ_ACK (msg_p).ue_ambr; - ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased; - memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req)); - for (i = 0; - i < ue_context_p->ue_context.nb_release_of_e_rabs; - i++) { - LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); - ue_context_p->ue_context.e_rabs_tobereleased[i]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[i].e_rab_id; - delete_tunnel_req.eps_bearer_id[i] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[i].e_rab_id; - } + ue_context_p->ue_context.setup_e_rabs = ue_context_p->ue_context.setup_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs; + ue_context_p->ue_context.nb_of_e_rabs = ue_context_p->ue_context.nb_of_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs; + + memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req)); if (ue_context_p->ue_context.nb_release_of_e_rabs>0) { + int e_rab_release_index=0; + for (i = 0; + i < ue_context_p->ue_context.setup_e_rabs; + i++) { + if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id) { + LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE; + ue_context_p->ue_context.e_rabs_tobereleased[e_rab_release_index]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id; + delete_tunnel_req.eps_bearer_id[e_rab_release_index] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id; + e_rab_release_index++; + } + else { + LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); + } + } + } + + if (ue_context_p->ue_context.nb_release_of_e_rabs>0){ delete_tunnel_req.rnti= ue_context_p->ue_context.rnti; delete_tunnel_req.num_erab= ue_context_p->ue_context.nb_release_of_e_rabs; /* this could also be done through ITTI message */ From 52a52eefb9eafa51dcc3d9af020974304897921c Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Fri, 8 Feb 2019 17:25:24 +0100 Subject: [PATCH 06/26] X2AP UE Context Release (generate/handle message), Release eNB resources --- openair2/COMMON/x2ap_messages_def.h | 3 ++ openair2/COMMON/x2ap_messages_types.h | 9 ++++ openair2/RRC/LTE/rrc_defs.h | 3 +- openair2/RRC/LTE/rrc_eNB.c | 63 +++++++++++++++++++++- openair2/RRC/LTE/rrc_eNB_S1AP.c | 55 ++++++++++++++++++- openair2/RRC/LTE/rrc_eNB_S1AP.h | 4 ++ openair2/X2AP/x2ap_eNB.c | 27 ++++++++++ openair2/X2AP/x2ap_eNB_decoder.c | 4 ++ openair2/X2AP/x2ap_eNB_generate_messages.c | 12 ++--- openair2/X2AP/x2ap_eNB_generate_messages.h | 3 +- openair2/X2AP/x2ap_eNB_handler.c | 52 +++++++++++++++++- 11 files changed, 223 insertions(+), 12 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index d5555c1839..65fa9c801d 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -40,3 +40,6 @@ MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_der /* handover messages X2AP <-> RRC */ MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req) MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack) + +/* handover messages X2AP <-> S1AP */ +MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 7cdd0ff0ff..d43057dbdf 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -33,11 +33,20 @@ #define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack #define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf #define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind +#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 // eNB application layer -> X2AP messages + +/* X2AP UE CONTEXT RELEASE */ +typedef struct x2ap_ue_context_release_s { + int old_eNB_ue_x2ap_id; + int new_eNB_ue_x2ap_id; + int target_mod_id; +} x2ap_ue_context_release_t; + typedef struct x2ap_register_enb_req_s { /* Unique eNB_id to identify the eNB within EPC. * For macro eNB ids this field should be 20 bits long. diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 38fc7b7262..d5faf89bc7 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -343,7 +343,8 @@ typedef enum HO_STATE_e { HO_COMPLETE, // initiated by the target eNB HO_REQUEST, HO_ACK, - HO_CONFIGURED + HO_CONFIGURED, + HO_RELEASE } HO_STATE_t; typedef enum SL_TRIGGER_e { diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 4754abfe53..d5631ef155 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4223,6 +4223,42 @@ void rrc_eNB_process_handoverCommand( ue_context->ue_context.handover_info->size = size; } +void rrc_eNB_handover_ue_context_release( +protocol_ctxt_t *const ctxt_pP, +struct rrc_eNB_ue_context_s *ue_context_p) { + int e_rab = 0; + //MessageDef *msg_release_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + + //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE); + //itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_release_p); + s1ap_ue_context_release(ctxt_pP->instance, ue_context_p->ue_context.eNB_ue_s1ap_id); + + //MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); + + if (rrc_ue_s1ap_ids != NULL) { + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); + } +} + #if 0 //----------------------------------------------------------------------------- void @@ -7990,6 +8026,14 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) } } + if (ue_context_p->ue_context.handover_info != NULL) { + if (ue_context_p->ue_context.handover_info->state == HO_RELEASE) { + ue_to_be_removed = ue_context_p; + rrc_eNB_handover_ue_context_release(ctxt_pP, ue_context_p); + break; //break RB_FOREACH (why to break ?) + } + } + pthread_mutex_lock(&rrc_release_freelist); if (rrc_release_info.num_UEs > 0) { @@ -8161,6 +8205,9 @@ void *rrc_enb_process_itti_msg(void *notUsed) { SRB_INFO *srb_info_p; int CC_id; protocol_ctxt_t ctxt; + +// memset(&ctxt, 0, sizeof(ctxt)); + // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); @@ -8278,7 +8325,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) { //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n", //instance, msg_name_p); if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti) - && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) { + && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0 + && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.handover_info->state != HO_RELEASE) { rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc = rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc; } @@ -8310,6 +8358,19 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; } + case X2AP_UE_CONTEXT_RELEASE: { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti); + LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s at frame %d subframe %d \n", instance, msg_name_p, + ctxt.frame,ctxt.subframe); + DevAssert(ue_context_p != NULL); + + if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort(); + + ue_context_p->ue_context.handover_info->state = HO_RELEASE; + break; + } + /* Messages from eNB app */ case RRC_CONFIGURATION_REQ: LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p,&RRC_CONFIGURATION_REQ(msg_p)); diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index d80c45d699..ce5bdc7d54 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -2087,9 +2087,60 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg /* Security key */ ue_context_p->ue_context.next_hop_chain_count=S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_hop_chain_count; memcpy ( ue_context_p->ue_context.next_security_key, - S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_security_key, - SECURITY_KEY_LENGTH); + S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_security_key, + SECURITY_KEY_LENGTH); + + rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(&ctxt, ue_context_p); + return (0); } } +int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP) { + + MessageDef *msg_p = NULL; + + msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE); + + X2AP_UE_CONTEXT_RELEASE (msg_p).old_eNB_ue_x2ap_id = 0; + X2AP_UE_CONTEXT_RELEASE (msg_p).new_eNB_ue_x2ap_id = 0; + X2AP_UE_CONTEXT_RELEASE (msg_p).target_mod_id = ue_context_pP->ue_context.handover_info->modid_t; + itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); + return (0); +} + +int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id){ + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + LOG_W(RRC,"Failed to find ue context associated with eNB ue s1ap id: %u\n", + eNB_ue_s1ap_id); + return -1; + } + + // release UE context + struct s1ap_eNB_ue_context_s *ue_context2_p = NULL; + + if ((ue_context2_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_context_p)) + != NULL) { + LOG_W(RRC,"Removed UE context eNB_ue_s1ap_id %u\n", + ue_context2_p->eNB_ue_s1ap_id); + s1ap_eNB_free_ue_context(ue_context2_p); + } else { + LOG_W(RRC,"Removing UE context eNB_ue_s1ap_id %u: did not find context\n", + ue_context_p->eNB_ue_s1ap_id); + } + /*RB_FOREACH(ue_context_p, s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head) { + S1AP_WARN("in s1ap_ue_map: UE context eNB_ue_s1ap_id %u mme_ue_s1ap_id %u state %u\n", + ue_context_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id, + ue_context_p->ue_state); + }*/ + + return 0; +} diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index 33a0caabc8..da63fc68a3 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -270,4 +270,8 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP); int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance); +int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP); + +int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id); + #endif /* RRC_ENB_S1AP_H_ */ diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index db29f32d7b..eb79401153 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -79,6 +79,11 @@ static void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_handover_req_ack_t *x2ap_handover_req_ack); +static +void x2ap_eNB_handle_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release); + + static void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { int result; @@ -423,6 +428,23 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, //x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size); } +static +void x2ap_eNB_handle_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release) +{ + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + int target_enb_id = x2ap_ue_context_release->target_mod_id; + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + target = x2ap_is_eNB_id_in_list(target_enb_id); + DevAssert(target != NULL); + + x2ap_eNB_generate_x2_ue_context_release(target, x2ap_ue_context_release); +} + void *x2ap_task(void *arg) { MessageDef *received_msg = NULL; int result; @@ -454,6 +476,11 @@ void *x2ap_task(void *arg) { &X2AP_HANDOVER_REQ_ACK(received_msg)); break; + case X2AP_UE_CONTEXT_RELEASE: + x2ap_eNB_handle_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_UE_CONTEXT_RELEASE(received_msg)); + break; + case SCTP_INIT_MSG_MULTI_CNF: x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 553cf8e559..a5b19fe2cc 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -48,6 +48,10 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); break; + case X2AP_ProcedureCode_id_uEContextRelease: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); + break; default: X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 76d6053b59..65dc3ae9d8 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -619,8 +619,8 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t)); ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_ignore; - ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = 0; + ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1; + ie->value.choice.UE_X2AP_ID_1 = 0; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -668,7 +668,7 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, return ret; } -int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p) +int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release) { X2AP_X2AP_PDU_t pdu; @@ -701,15 +701,15 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p) ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = 0; + ie->value.choice.UE_X2AP_ID = x2ap_ue_context_release->old_eNB_ue_x2ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ ie = (X2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(X2AP_UEContextRelease_IEs_t)); ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; - ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = 0; + ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1; + ie->value.choice.UE_X2AP_ID_1 = x2ap_ue_context_release->new_eNB_ue_x2ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 9028d8cd05..df599c60ab 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -53,6 +53,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p, int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_ack_t *x2ap_handover_req_ack); -int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p); +int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_ue_context_release_t *x2ap_ue_context_release); #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index b3b83a7e69..c751239095 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -71,6 +71,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_eNB_handle_ue_context_release (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */ @@ -78,7 +84,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* loadIndication */ { 0, 0, 0 }, /* errorIndication */ { 0, 0, 0 }, /* snStatusTransfer */ - { 0, 0, 0 }, /* uEContextRelease */ + { x2ap_eNB_handle_ue_context_release, 0, 0 }, /* uEContextRelease */ { x2ap_eNB_handle_x2_setup_request, x2ap_eNB_handle_x2_setup_response, x2ap_eNB_handle_x2_setup_failure }, /* x2Setup */ { 0, 0, 0 }, /* reset */ { 0, 0, 0 }, /* eNBConfigurationUpdate */ @@ -726,3 +732,47 @@ int x2ap_eNB_handle_handover_response (instance_t instance, itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg); return 0; } + + +static +int x2ap_eNB_handle_ue_context_release (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + X2AP_UEContextRelease_t *x2UEContextRelease; + X2AP_UEContextRelease_IEs_t *ie; + + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + + DevAssert (pdu != NULL); + x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 ue context release on stream == 0\n"); + /* TODO: send a x2 failure response */ + return 0; + } + + X2AP_DEBUG ("Received a new X2 ue context release\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + + X2AP_UE_CONTEXT_RELEASE(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, + X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + + X2AP_UE_CONTEXT_RELEASE(msg).new_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; + + itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg); + + return 0; +} From 3179722161b123cbf6a0487839fb5d795dfa1208 Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Wed, 13 Feb 2019 11:54:19 +0100 Subject: [PATCH 07/26] x2: bug fixes - free correctly in rrc_eNB_free_mem_UE_context - check for existence of ue_context.handover_info in rrc_enb_process_itti_msg - check return value sctp_peeloff in sctp_handle_new_association_req_multi and exit in case of failure --- openair2/ENB_APP/enb_config.c | 300 +++++++++++++++++----------------- openair2/RRC/LTE/rrc_eNB.c | 19 +-- openair3/SCTP/sctp_eNB_task.c | 7 +- 3 files changed, 166 insertions(+), 160 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 478f14f07c..d4439ab349 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -1923,162 +1923,164 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { if (ENBParamList.numelt > 0) { for (k = 0; k < ENBParamList.numelt; k++) { - if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { - // Calculate a default eNB ID + if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { + // Calculate a default eNB ID if (EPC_MODE_ENABLED) { - uint32_t hash; - hash = s1ap_generate_eNB_id (); - enb_id = k + (hash & 0xFFFF8); + uint32_t hash; + hash = s1ap_generate_eNB_id (); + enb_id = k + (hash & 0xFFFF8); } else { - enb_id = k; + enb_id = k; } - } else { - enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr); - } - - // search if in active list - for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { - if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { - paramdef_t PLMNParams[] = PLMNPARAMS_DESC; - paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; - /* map parameter checking array instances to parameter definition array instances */ - checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; - - for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) - PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - - paramdef_t X2Params[] = X2PARAMS_DESC; - paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; - paramdef_t SCTPParams[] = SCTPPARAMS_DESC; - paramdef_t NETParams[] = NETPARAMS_DESC; - /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */ - /* this is most probably a problem with the config module */ - char aprefix[MAX_OPTNAME_SIZE*80 + 8]; - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); - /* Some default/random parameters */ - X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; - - if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB; - } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", - RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); - } - - X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); - X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; - config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); - - if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) - AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", - PLMNParamList.numelt); - - if (PLMNParamList.numelt > 1) - LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n"); - - X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; - X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; - X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 - || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, - "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", - X2AP_REGISTER_ENB_REQ(msg_p).mnc); - /* CC params */ - config_getlist(&CCsParamList, NULL, 0, aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; - - if (CCsParamList.numelt > 0) { - //char ccspath[MAX_OPTNAME_SIZE*2 + 16]; - for (J = 0; J < CCsParamList.numelt ; J++) { - sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J); - config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band; - X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency; - X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset; - X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell; - - if (ccparams_lte.Nid_cell>503) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", - RC.config_file_name, k, ccparams_lte.Nid_cell); - } - - X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL; - - if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", - RC.config_file_name, k, ccparams_lte.N_RB_DL); - } - - if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; - } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", - RC.config_file_name, k, ccparams_lte.frame_type); - } - - X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL); - X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL); - } - } - - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); - config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); - AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, - "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", - X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); - X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; - - for (l = 0; l < X2ParamList.numelt; l++) { - X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1; - strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr)); - strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr)); - - if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; - } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; - } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; - } - } - - // SCTP SETTING - X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; - X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; + } else { + enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr); + } + + // search if in active list + for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { + if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { + paramdef_t PLMNParams[] = PLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + + paramdef_t X2Params[] = X2PARAMS_DESC; + paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + paramdef_t NETParams[] = NETPARAMS_DESC; + /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */ + /* this is most probably a problem with the config module */ + char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + /* Some default/random parameters */ + X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; + + if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB; + } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", + RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); + } + + X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); + X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) + AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", + PLMNParamList.numelt); + + if (PLMNParamList.numelt > 1) + LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n"); + + X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 + || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + X2AP_REGISTER_ENB_REQ(msg_p).mnc); + /* CC params */ + config_getlist(&CCsParamList, NULL, 0, aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; + + if (CCsParamList.numelt > 0) { + //char ccspath[MAX_OPTNAME_SIZE*2 + 16]; + for (J = 0; J < CCsParamList.numelt ; J++) { + sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J); + config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band; + X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency; + X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset; + X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell; + + if (ccparams_lte.Nid_cell>503) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", + RC.config_file_name, k, ccparams_lte.Nid_cell); + } + + X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL; + + if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", + RC.config_file_name, k, ccparams_lte.N_RB_DL); + } + + if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; + } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", + RC.config_file_name, k, ccparams_lte.frame_type); + } + + X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL); + X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL); + } + } + + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); + AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, + "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", + X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); + X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; + + for (l = 0; l < X2ParamList.numelt; l++) { + X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1; + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr)); + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr)); + + if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0; + } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; + } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; + } + } + + // SCTP SETTING + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; if (EPC_MODE_ENABLED) { - sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); - config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); - X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); } - sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - // NETWORK_INTERFACES - config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr); - - if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { - LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n"); - exit(1); - } - - cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr); - address = strtok(cidr, "/"); - X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0; - X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1; - strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address); - } - } + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + // NETWORK_INTERFACES + config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr); + + if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { + LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n"); + exit(1); + } + + cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr); + address = strtok(cidr, "/"); + X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0; + X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1; + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address); + } + } } } } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d5631ef155..7fab592448 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -781,7 +781,8 @@ rrc_eNB_free_mem_UE_context( ue_context_pP->ue_context.measGapConfig = NULL; }*/ if (ue_context_pP->ue_context.handover_info) { - ASN_STRUCT_FREE(asn_DEF_LTE_Handover, ue_context_pP->ue_context.handover_info); + /* TODO: be sure free is enough here (check memory leaks) */ + free(ue_context_pP->ue_context.handover_info); ue_context_pP->ue_context.handover_info = NULL; } @@ -8319,19 +8320,17 @@ void *rrc_enb_process_itti_msg(void *notUsed) { rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance); break; - case GTPV1U_ENB_DELETE_TUNNEL_RESP: + case GTPV1U_ENB_DELETE_TUNNEL_RESP: { + rrc_eNB_ue_context_t *ue = rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti); - /* Nothing to do. Apparently everything is done in S1AP processing */ - //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n", - //instance, msg_name_p); - if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti) - && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0 - && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.handover_info->state != HO_RELEASE) { - rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc = - rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc; + if (ue != NULL + && ue->ue_context.ue_release_timer_rrc > 0 + && (ue->ue_context.handover_info == NULL || ue->ue_context.handover_info->state != HO_RELEASE)) { + ue->ue_context.ue_release_timer_rrc = ue->ue_context.ue_release_timer_thres_rrc; } break; + } case S1AP_PATH_SWITCH_REQ_ACK: LOG_I(RRC, "[eNB %d] received path switch ack %s\n", instance, msg_name_p); diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index b0c18c3692..f323ba8c62 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -324,7 +324,12 @@ sctp_handle_new_association_req_multi( } } - ns = sctp_peeloff(sd,assoc_id); + ns = sctp_peeloff(sd, assoc_id); + if (ns == -1) { + perror("sctp_peeloff"); + printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id); + exit(1); + } sctp_cnx = calloc(1, sizeof(*sctp_cnx)); From f76f1f1e1c056aed6aab07608a85673ec69cd837 Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Thu, 14 Feb 2019 16:34:57 +0100 Subject: [PATCH 08/26] x2: bugfix: pass correct rach resource type --- openair2/LAYER2/MAC/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 1a334a36b9..312edea2c1 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -883,7 +883,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, rntiP, -1 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , - -1 + 0 #endif )) == -1) { From a8eefbcf5839486ad81c4ce834830fbe120edab0 Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Thu, 14 Feb 2019 16:37:38 +0100 Subject: [PATCH 09/26] sctp: bugfix: use correct instance (not default) for sctp_itti_send_new_message_ind --- openair3/SCTP/sctp_eNB_itti_messaging.c | 4 ++-- openair3/SCTP/sctp_eNB_itti_messaging.h | 2 +- openair3/SCTP/sctp_eNB_task.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.c b/openair3/SCTP/sctp_eNB_itti_messaging.c index d2064c74c0..9c24da7370 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.c +++ b/openair3/SCTP/sctp_eNB_itti_messaging.c @@ -38,7 +38,7 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, in return itti_send_msg_to_task(task_id, instance, message_p); } -int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer, +int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, uint32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream) { MessageDef *message_p; @@ -57,7 +57,7 @@ int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t sctp_data_ind_p->buffer_length = buffer_length; sctp_data_ind_p->assoc_id = assoc_id; - return itti_send_msg_to_task(task_id, INSTANCE_DEFAULT, message_p); + return itti_send_msg_to_task(task_id, instance, message_p); } int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.h b/openair3/SCTP/sctp_eNB_itti_messaging.h index 49d2056a3c..b4f1a0ee69 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.h +++ b/openair3/SCTP/sctp_eNB_itti_messaging.h @@ -24,7 +24,7 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd); -int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer, +int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, uint32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream); int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index f323ba8c62..68fa34f810 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -1008,7 +1008,7 @@ sctp_eNB_read_from_socket( sinfo.sinfo_assoc_id, sctp_cnx->sd, n, ntohs(addr.sin_port), sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid)); - sctp_itti_send_new_message_ind(sctp_cnx->task_id, + sctp_itti_send_new_message_ind(sctp_cnx->task_id, sctp_cnx->instance, sinfo.sinfo_assoc_id, buffer, n, sinfo.sinfo_stream); } From 02193f4babfa4556eba0c046cb7d6c7bd4ac9f91 Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Thu, 14 Feb 2019 16:39:22 +0100 Subject: [PATCH 10/26] x2: some cleanup in instance management - manage target eNB based on target cell id received by measurement report for Handover Request - manage source eNB based on association id for Handover Request Ack - use only x2ap instance and not x2ap data instance points to x2ap instance --- openair2/COMMON/x2ap_messages_types.h | 3 + openair2/RRC/LTE/rrc_defs.h | 1 + openair2/RRC/LTE/rrc_eNB.c | 7 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 2 +- openair2/X2AP/x2ap_eNB.c | 25 +++-- openair2/X2AP/x2ap_eNB_defs.h | 5 +- openair2/X2AP/x2ap_eNB_generate_messages.c | 43 ++------- openair2/X2AP/x2ap_eNB_generate_messages.h | 8 +- openair2/X2AP/x2ap_eNB_handler.c | 92 ++++++++++++------- openair2/X2AP/x2ap_eNB_handler.h | 2 +- .../X2AP/x2ap_eNB_management_procedures.c | 33 ++++--- .../X2AP/x2ap_eNB_management_procedures.h | 4 +- 12 files changed, 118 insertions(+), 107 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index d43057dbdf..b5e73db3ae 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -45,6 +45,7 @@ typedef struct x2ap_ue_context_release_s { int old_eNB_ue_x2ap_id; int new_eNB_ue_x2ap_id; int target_mod_id; + int source_assoc_id; } x2ap_ue_context_release_t; typedef struct x2ap_register_enb_req_s { @@ -178,6 +179,7 @@ typedef struct x2ap_handover_req_s { /* TODO: this parameter has to be removed */ int target_mod_id; + int source_assoc_id; } x2ap_handover_req_t; typedef struct x2ap_handover_req_ack_s { @@ -185,6 +187,7 @@ typedef struct x2ap_handover_req_ack_s { int source_x2id; /* TODO: to be fixed/remove */ /* TODO: this parameter has to be removed */ int target_mod_id; + int source_assoc_id; uint8_t nb_e_rabs_tobesetup; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index d5faf89bc7..e9edce2f21 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -451,6 +451,7 @@ typedef struct HANDOVER_INFO_s { HO_STATE_t state; //current state of handover uint32_t modid_s; //module_idP of serving cell uint32_t modid_t; //module_idP of target cell + int source_assoc_id; uint8_t ueid_s; //UE index in serving cell uint8_t ueid_t; //UE index in target cell LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 7fab592448..16a26fbed8 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4113,8 +4113,9 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; ue_context_target_p->ue_context.handover_info->state = HO_ACK; /* TODO: remove this hack */ + ue_context_target_p->ue_context.handover_info->source_assoc_id = m->source_assoc_id; //ue_context_target_p->ue_context.handover_info->modid_t = mod_id; - ue_context_target_p->ue_context.handover_info->modid_t = m->target_mod_id; + //ue_context_target_p->ue_context.handover_info->modid_t = m->target_mod_id; //ue_context_target_p->ue_context.handover_info->modid_s = 1-mod_id; //ue_context_target_p->ue_context.handover_info->ueid_s = m->source_rnti; memset (ue_context_target_p->ue_context.nh, 0, 32); @@ -4328,8 +4329,10 @@ check_handovers( rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP); /* TODO: remove this hack */ //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = 1 - ctxt_pP->module_id; - X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = ue_context_p->ue_context.handover_info->modid_t; + //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = ue_context_p->ue_context.handover_info->modid_t; //X2AP_HANDOVER_REQ_ACK(msg).source_x2id = ue_context_p->ue_context.handover_info->source_x2id; + + X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->source_assoc_id; /* Call admission control not implemented yet */ X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index ce5bdc7d54..e2e434feb7 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -2104,7 +2104,7 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r X2AP_UE_CONTEXT_RELEASE (msg_p).old_eNB_ue_x2ap_id = 0; X2AP_UE_CONTEXT_RELEASE (msg_p).new_eNB_ue_x2ap_id = 0; - X2AP_UE_CONTEXT_RELEASE (msg_p).target_mod_id = ue_context_pP->ue_context.handover_info->modid_t; + X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->source_assoc_id; itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); return (0); } diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index eb79401153..19031bceaf 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -135,7 +135,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); - x2ap_handle_x2_setup_message(x2ap_enb_data_p, + x2ap_handle_x2_setup_message(instance_p, x2ap_enb_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); return; } @@ -386,20 +386,17 @@ void x2ap_eNB_handle_handover_req(instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; - int target_enb_id = x2ap_handover_req->target_physCellId; + int target_pci = x2ap_handover_req->target_physCellId; - instance_p = x2ap_eNB_pci_get_instance(target_enb_id); + instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - //instance_p = x2ap_eNB_get_instance(instance); - //DevAssert(instance_p != NULL); - - target = x2ap_is_eNB_id_in_list(instance_p->eNB_id); + target = x2ap_is_eNB_pci_in_list(target_pci); DevAssert(target != NULL); /* store rnti at index 0 */ //x2id_to_source_rnti[0] = x2ap_handover_req->source_rnti; - x2ap_eNB_generate_x2_handover_request(target, x2ap_handover_req); + x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req); } static @@ -415,15 +412,15 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, */ x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; - int target_enb_id = x2ap_handover_req_ack->target_mod_id; + int source_assoc_id = x2ap_handover_req_ack->source_assoc_id; instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - target = x2ap_is_eNB_id_in_list(target_enb_id); + target = x2ap_get_eNB(NULL, source_assoc_id, 0); DevAssert(target != NULL); - x2ap_eNB_generate_x2_handover_request_ack(target, x2ap_handover_req_ack); + x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack); //x2ap_eNB_generate_x2_handover_req_ack(instance_p, target, x2ap_handover_req_ack->source_x2id, //x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size); } @@ -434,15 +431,15 @@ void x2ap_eNB_handle_ue_context_release(instance_t instance, { x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; - int target_enb_id = x2ap_ue_context_release->target_mod_id; + int source_assoc_id = x2ap_ue_context_release->source_assoc_id; instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - target = x2ap_is_eNB_id_in_list(target_enb_id); + target = x2ap_get_eNB(NULL, source_assoc_id, 0); DevAssert(target != NULL); - x2ap_eNB_generate_x2_ue_context_release(target, x2ap_ue_context_release); + x2ap_eNB_generate_x2_ue_context_release(instance_p, target, x2ap_ue_context_release); } void *x2ap_task(void *arg) { diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index a5558c42a5..f90176430c 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -114,6 +114,10 @@ typedef struct x2ap_eNB_data_s { /* SCTP association id */ int32_t assoc_id; + /* Nid cells */ + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + /* Only meaningfull in virtual mode */ struct x2ap_eNB_instance_s *x2ap_eNB_instance; } x2ap_eNB_data_t; @@ -163,7 +167,6 @@ typedef struct x2ap_eNB_instance_s { uint32_t downlink_frequency[MAX_NUM_CCs]; int32_t uplink_frequency_offset[MAX_NUM_CCs]; uint32_t Nid_cell[MAX_NUM_CCs]; - uint32_t Nid_target_cell[MAX_NUM_CCs]; int16_t N_RB_DL[MAX_NUM_CCs]; lte_frame_type_t frame_type[MAX_NUM_CCs]; uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 65dc3ae9d8..27fd766614 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -180,7 +180,7 @@ int x2ap_eNB_generate_x2_setup_request( return ret; } -int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p) +int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) { X2AP_X2AP_PDU_t pdu; X2AP_X2SetupResponse_t *out; @@ -189,18 +189,12 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p) ServedCells__Member *servedCellMember; X2AP_GU_Group_ID_t *gu; - x2ap_eNB_instance_t *instance_p; - uint8_t *buffer; uint32_t len; int ret = 0; - DevAssert(x2ap_eNB_data_p != NULL); - - /* get the eNB instance */ - instance_p = x2ap_eNB_data_p->x2ap_eNB_instance; - DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); /* Prepare the X2AP message to encode */ memset(&pdu, 0, sizeof(pdu)); @@ -414,7 +408,7 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, return 0; } -int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p, +int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_t *x2ap_handover_req) { @@ -425,19 +419,12 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p, X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; X2AP_LastVisitedCell_Item_t *lastVisitedCell_Item; - x2ap_eNB_instance_t *instance_p; - uint8_t *buffer; uint32_t len; int ret = 0; - DevAssert(x2ap_eNB_data_p != NULL); - - /* get the eNB instance */ - instance_p = x2ap_eNB_data_p->x2ap_eNB_instance; - DevAssert(instance_p != NULL); - + DevAssert(x2ap_eNB_data_p != NULL); /* Prepare the X2AP handover message to encode */ memset(&pdu, 0, sizeof(pdu)); @@ -471,7 +458,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p, ie->value.present = X2AP_HandoverRequest_IEs__value_PR_ECGI; MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, &ie->value.choice.ECGI.pLMN_Identity); - MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); + MACRO_ENB_ID_TO_CELL_IDENTITY(x2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -576,7 +563,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p, return ret; } -int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, +int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_ack_t *x2ap_handover_req_ack) { @@ -586,18 +573,12 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, X2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; X2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; - x2ap_eNB_instance_t *instance_p; - uint8_t *buffer; uint32_t len; int ret = 0; - DevAssert(x2ap_eNB_data_p != NULL); - - /* get the eNB instance */ - instance_p = x2ap_eNB_data_p->x2ap_eNB_instance; - DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); /* Prepare the X2AP handover message to encode */ memset(&pdu, 0, sizeof(pdu)); @@ -668,25 +649,19 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, return ret; } -int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release) +int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release) { X2AP_X2AP_PDU_t pdu; X2AP_UEContextRelease_t *out; X2AP_UEContextRelease_IEs_t *ie; - x2ap_eNB_instance_t *instance_p; - uint8_t *buffer; uint32_t len; int ret = 0; - DevAssert(x2ap_eNB_data_p != NULL); - - /* get the eNB instance */ - instance_p = x2ap_eNB_data_p->x2ap_eNB_instance; - DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); /* Prepare the X2AP ue context relase message to encode */ memset(&pdu, 0, sizeof(pdu)); diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index df599c60ab..6636413fc6 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -35,7 +35,7 @@ int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); -int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p); +int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); int x2ap_eNB_generate_x2_setup_failure(instance_t instance, uint32_t assoc_id, @@ -47,13 +47,13 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, X2AP_Cause_PR cause_type, long cause_value); -int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p, +int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_t *x2ap_handover_req); -int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p, +int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_ack_t *x2ap_handover_req_ack); -int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p, +int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release); #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index c751239095..cb216dfc81 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -118,7 +118,7 @@ static char *x2ap_direction_String[] = { return(x2ap_direction_String[x2ap_dir]); } -void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown) +void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown) { if (sctp_shutdown) { /* A previously connected eNB has been shutdown */ @@ -127,38 +127,38 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown if (enb_desc_p->state == X2AP_ENB_STATE_CONNECTED) { enb_desc_p->state = X2AP_ENB_STATE_DISCONNECTED; - if (enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb > 0) { + if (instance_p-> x2_target_enb_associated_nb > 0) { /* Decrease associated eNB number */ - enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb --; + instance_p-> x2_target_enb_associated_nb --; } /* If there are no more associated eNB, inform eNB app */ - if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb == 0) { + if (instance_p->x2_target_enb_associated_nb == 0) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_X2AP, X2AP_DEREGISTERED_ENB_IND); X2AP_DEREGISTERED_ENB_IND(message_p).nb_x2 = 0; - itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p); + itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); } } } else { /* Check that at least one setup message is pending */ - DevCheck(enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0, - enb_desc_p->x2ap_eNB_instance->instance, - enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb, 0); + DevCheck(instance_p->x2_target_enb_pending_nb > 0, + instance_p->instance, + instance_p->x2_target_enb_pending_nb, 0); - if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0) { + if (instance_p->x2_target_enb_pending_nb > 0) { /* Decrease pending messages number */ - enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb --; + instance_p->x2_target_enb_pending_nb --; } /* If there are no more pending messages, inform eNB app */ - if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb == 0) { + if (instance_p->x2_target_enb_pending_nb == 0) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_X2AP, X2AP_REGISTER_ENB_CNF); - X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb; - itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p); + X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = instance_p->x2_target_enb_associated_nb; + itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); } } } @@ -282,6 +282,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, X2AP_X2SetupRequest_IEs_t *ie; ServedCells__Member *servedCellMember; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; uint32_t eNB_id = 0; @@ -364,8 +365,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, */ X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id); - DevAssert(x2ap_eNB_data->x2ap_eNB_instance != NULL); - x2ap_eNB_generate_x2_setup_failure (x2ap_eNB_data->x2ap_eNB_instance->instance, + x2ap_eNB_generate_x2_setup_failure (instance, assoc_id, X2AP_Cause_PR_protocol, X2AP_CauseProtocol_unspecified, @@ -380,19 +380,22 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, /* Set proper pci */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupRequest_IEs_t, ie, x2SetupRequest, X2AP_ProtocolIE_ID_id_ServedCells, true); - if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; - } else if (ie->value.choice.ServedCells.list.count > 0) { - x2ap_eNB_data->x2ap_eNB_instance->num_cc = ie->value.choice.ServedCells.list.count; + } + if (ie->value.choice.ServedCells.list.count > 0) { + x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; for (int i=0; ivalue.choice.ServedCells.list.count;i++) { servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; - x2ap_eNB_data->x2ap_eNB_instance->Nid_target_cell[i] = servedCellMember->servedCellInfo.pCI; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; } } - return x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); } static @@ -406,6 +409,7 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, X2AP_X2SetupResponse_IEs_t *ie; ServedCells__Member *servedCellMember; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; uint32_t eNB_id = 0; @@ -484,15 +488,16 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, /* Set proper pci */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse, X2AP_ProtocolIE_ID_id_ServedCells, true); - if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; - } else if (ie->value.choice.ServedCells.list.count > 0) { - x2ap_eNB_data->x2ap_eNB_instance->num_cc = ie->value.choice.ServedCells.list.count; + } + + if (ie->value.choice.ServedCells.list.count > 0) { + x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; for (int i=0; ivalue.choice.ServedCells.list.count;i++) { servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; - x2ap_eNB_data->x2ap_eNB_instance->Nid_target_cell[i] = servedCellMember->servedCellInfo.pCI; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; } } @@ -502,8 +507,12 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, * Mark the association as connected. */ x2ap_eNB_data->state = X2AP_ENB_STATE_READY; - x2ap_eNB_data->x2ap_eNB_instance->x2_target_enb_associated_nb ++; - x2ap_handle_x2_setup_message(x2ap_eNB_data, 0); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + instance_p->x2_target_enb_associated_nb ++; + x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0); return 0; } @@ -518,6 +527,7 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, X2AP_X2SetupFailure_t *x2SetupFailure; X2AP_X2SetupFailure_IEs_t *ie; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; DevAssert(pdu != NULL); @@ -558,7 +568,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, } x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING; - x2ap_handle_x2_setup_message(x2ap_eNB_data, 0); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0); return 0; } @@ -576,6 +590,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, X2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; @@ -625,7 +640,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, } X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID; - X2AP_HANDOVER_REQ(msg).target_mod_id = x2ap_eNB_data->x2ap_eNB_instance->eNB_id; + + /* TODO: properly store Target Cell ID */ + + X2AP_HANDOVER_REQ(msg).source_assoc_id = assoc_id; + X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); X2AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms = @@ -680,7 +699,10 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; - itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; } @@ -694,6 +716,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, X2AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck; X2AP_HandoverRequestAcknowledge_IEs_t *ie; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; @@ -729,7 +752,10 @@ int x2ap_eNB_handle_handover_response (instance_t instance, memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; - itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; } @@ -743,6 +769,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, X2AP_UEContextRelease_t *x2UEContextRelease; X2AP_UEContextRelease_IEs_t *ie; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; @@ -772,7 +799,10 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, X2AP_UE_CONTEXT_RELEASE(msg).new_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; - itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; } diff --git a/openair2/X2AP/x2ap_eNB_handler.h b/openair2/X2AP/x2ap_eNB_handler.h index e4dac14e8e..402212f62d 100644 --- a/openair2/X2AP/x2ap_eNB_handler.h +++ b/openair2/X2AP/x2ap_eNB_handler.h @@ -31,7 +31,7 @@ #include "x2ap_eNB_defs.h" -void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); +void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, const uint8_t * const data, const uint32_t data_length); diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c index 670581406b..137bad40ad 100644 --- a/openair2/X2AP/x2ap_eNB_management_procedures.c +++ b/openair2/X2AP/x2ap_eNB_management_procedures.c @@ -169,23 +169,6 @@ x2ap_eNB_instance_t *x2ap_eNB_get_instance(instance_t instance) return NULL; } -x2ap_eNB_instance_t *x2ap_eNB_pci_get_instance(uint32_t pci) -{ - x2ap_eNB_instance_t *temp = NULL; - - STAILQ_FOREACH(temp, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, - x2ap_eNB_entries) { - for (int i=0; inum_cc;i++) { - if (temp->Nid_target_cell[i] == pci) { - /* Matching occurence */ - return temp; - } - } - } - - return NULL; -} - /// utility functions void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref); @@ -222,6 +205,22 @@ void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref) { indent--; } +x2ap_eNB_data_t * x2ap_is_eNB_pci_in_list (const uint32_t pci) +{ + x2ap_eNB_instance_t *inst; + struct x2ap_eNB_data_s *elm; + + STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { + RB_FOREACH(elm, x2ap_enb_map, &inst->x2ap_enb_head) { + for (int i = 0; inum_cc; i++) { + if (elm->Nid_cell[i] == pci) { + return elm; + } + } + } + } + return NULL; +} x2ap_eNB_data_t * x2ap_is_eNB_id_in_list (const uint32_t eNB_id) { diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.h b/openair2/X2AP/x2ap_eNB_management_procedures.h index 8023415951..bcad728aaa 100644 --- a/openair2/X2AP/x2ap_eNB_management_procedures.h +++ b/openair2/X2AP/x2ap_eNB_management_procedures.h @@ -37,8 +37,6 @@ void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p); x2ap_eNB_instance_t *x2ap_eNB_get_instance(uint8_t mod_id); -x2ap_eNB_instance_t *x2ap_eNB_pci_get_instance(uint32_t pci); - uint16_t x2ap_eNB_fetch_add_global_cnx_id(void); void x2ap_eNB_prepare_internal_data(void); @@ -47,6 +45,8 @@ x2ap_eNB_data_t* x2ap_is_eNB_id_in_list(uint32_t eNB_id); x2ap_eNB_data_t* x2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id); +x2ap_eNB_data_t* x2ap_is_eNB_pci_in_list (const uint32_t pci); + struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p, int32_t assoc_id, uint16_t cnx_id); From c394188e73c16de6498245741416548e4deffb3d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 21 Feb 2019 10:49:53 +0100 Subject: [PATCH 11/26] x2: first implementation of ID management, some cleanup Some deadcode was removed. The implementation of the ID management is not finished. It will only work if the handover is successful. No error recovery has been done. For error recovery, we need to implement the X2AP timers. As it is, in case of error, an ID might very well never be released. It has been tested with 1 and 2 UEs doing handover more or less at the same time. --- cmake_targets/CMakeLists.txt | 1 + openair2/COMMON/x2ap_messages_types.h | 28 +-- openair2/RRC/LTE/rrc_defs.h | 3 +- openair2/RRC/LTE/rrc_eNB.c | 226 ++------------------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 5 +- openair2/X2AP/x2ap_eNB.c | 58 ++++-- openair2/X2AP/x2ap_eNB_defs.h | 4 + openair2/X2AP/x2ap_eNB_generate_messages.c | 31 ++- openair2/X2AP/x2ap_eNB_generate_messages.h | 2 +- openair2/X2AP/x2ap_eNB_handler.c | 86 ++++++-- openair2/X2AP/x2ap_ids.c | 92 +++++++++ openair2/X2AP/x2ap_ids.h | 47 +++++ 12 files changed, 313 insertions(+), 270 deletions(-) create mode 100644 openair2/X2AP/x2ap_ids.c create mode 100644 openair2/X2AP/x2ap_ids.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6c176a75c2..a1b4955b21 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -469,6 +469,7 @@ add_library(X2AP_ENB ${X2AP_DIR}/x2ap_eNB_itti_messaging.c ${X2AP_DIR}/x2ap_eNB_management_procedures.c ${X2AP_DIR}/x2ap_eNB_generate_messages.c + ${X2AP_DIR}/x2ap_ids.c ) add_dependencies(X2AP_ENB rrc_flag x2_flag) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index b5e73db3ae..38429b712e 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -42,9 +42,9 @@ /* X2AP UE CONTEXT RELEASE */ typedef struct x2ap_ue_context_release_s { - int old_eNB_ue_x2ap_id; - int new_eNB_ue_x2ap_id; - int target_mod_id; + /* used for X2AP->RRC in source and RRC->X2AP in target */ + int rnti; + int source_assoc_id; } x2ap_ue_context_release_t; @@ -138,12 +138,12 @@ typedef struct x2ap_lastvisitedcell_info_s { uint64_t time_UE_StayedInCell; }x2ap_lastvisitedcell_info_t; -//used for src typedef struct x2ap_handover_req_s { - int source_rnti; /* TODO: to be fixed/remove */ - int source_x2id; /* TODO: to be fixed/remove */ + /* used for RRC->X2AP in source eNB */ + int rnti; - int old_eNB_ue_x2ap_id; + /* used for X2AP->RRC in target eNB */ + int x2_id; LTE_PhysCellId_t target_physCellId; @@ -177,16 +177,16 @@ typedef struct x2ap_handover_req_s { uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; int rrc_buffer_size; - /* TODO: this parameter has to be removed */ - int target_mod_id; - int source_assoc_id; + int target_assoc_id; } x2ap_handover_req_t; typedef struct x2ap_handover_req_ack_s { - int source_rnti; /* TODO: to be fixed/remove */ - int source_x2id; /* TODO: to be fixed/remove */ - /* TODO: this parameter has to be removed */ - int target_mod_id; + /* used for RRC->X2AP in target and X2AP->RRC in source */ + int rnti; + + /* used for RRC->X2AP in target */ + int x2_id_target; + int source_assoc_id; uint8_t nb_e_rabs_tobesetup; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index e9edce2f21..22a9332a58 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -451,13 +451,14 @@ typedef struct HANDOVER_INFO_s { HO_STATE_t state; //current state of handover uint32_t modid_s; //module_idP of serving cell uint32_t modid_t; //module_idP of target cell - int source_assoc_id; + int assoc_id; uint8_t ueid_s; //UE index in serving cell uint8_t ueid_t; //UE index in target cell LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ LTE_AS_Context_t as_context; /* They are mandatory for HO */ uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ int size; /* size of above message in bytes */ + int x2_id; /* X2AP UE ID in the target eNB */ } HANDOVER_INFO; #define RRC_HEADER_SIZE_MAX 64 diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 16a26fbed8..49ca46b35d 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3924,8 +3924,7 @@ rrc_eNB_process_MeasurementReport( ue_context_pP, X2AP_HANDOVER_REQ(msg).rrc_buffer, &X2AP_HANDOVER_REQ(msg).rrc_buffer_size); - X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti; - X2AP_HANDOVER_REQ(msg).old_eNB_ue_x2ap_id = 0; + X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rnti; X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. measResultListEUTRA.list.array[ncell_index]->physCellId; X2AP_HANDOVER_REQ(msg).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc; @@ -3982,105 +3981,6 @@ rrc_eNB_generate_HandoverPreparationInformation( *_size = ho_size; } -#if 0 -//----------------------------------------------------------------------------- -void -rrc_eNB_generate_HandoverPreparationInformation( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - LTE_PhysCellId_t targetPhyId -) -//----------------------------------------------------------------------------- -{ - struct rrc_eNB_ue_context_s *ue_context_target_p = NULL; - //uint8_t UE_id_target = -1; - uint8_t mod_id_target = get_adjacent_cell_mod_id(targetPhyId); - HANDOVER_INFO *handoverInfo = CALLOC(1, sizeof(*handoverInfo)); - /* - uint8_t buffer[100]; - uint8_t size; - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP]; - RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); - */ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - handoverInfo->as_config.antennaInfoCommon.antennaPortsCount = 0; //Not used 0- but check value - handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify! - memcpy((void *)&handoverInfo->as_config.sourceMasterInformationBlock, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t)); - memcpy((void *)&handoverInfo->as_config.sourceMeasConfig, - (void *)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t)); - // FIXME handoverInfo not used... - free( handoverInfo ); - handoverInfo = 0; - //to be configured - memset((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig, - 0, sizeof(LTE_SecurityAlgorithmConfig_t)); - memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t)); - memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t)); - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo = - CALLOC(1, sizeof(LTE_ReestablishmentInfo_t)); - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId = - RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.buf = NULL; // Check values later - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.size = 0; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.bits_unused = 0; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->additionalReestabInfoList = NULL; - ue_context_pP->ue_context.handover_info->ho_prepare = 0xFF; //0xF0; - ue_context_pP->ue_context.handover_info->ho_complete = 0; - - if (mod_id_target != 0xFF) { - //UE_id_target = rrc_find_free_ue_index(modid_target); - ue_context_target_p = - rrc_eNB_get_ue_context( - RC.rrc[mod_id_target], - ue_context_pP->ue_context.rnti); - - /*UE_id_target = rrc_eNB_get_next_free_UE_index( - mod_id_target, - RC.rrc[ctxt_pP->module_id]->Info.UE_list[ue_mod_idP]); //this should return a new index*/ - - if (ue_context_target_p == NULL) { // if not already in target cell - ue_context_target_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]); - ue_context_target_p->ue_id_rnti = ue_context_pP->ue_context.rnti; // LG: should not be the same - ue_context_target_p->ue_context.rnti = ue_context_target_p->ue_id_rnti; // idem - LOG_I(RRC, - "[eNB %d] Frame %d : Emulate sending HandoverPreparationInformation msg from eNB source %d to eNB target %ld: source UE_id %x target UE_id %x source_modId: %d target_modId: %d\n", - ctxt_pP->module_id, - ctxt_pP->frame, - RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId, - targetPhyId, - ue_context_pP->ue_context.rnti, - ue_context_target_p->ue_id_rnti, - ctxt_pP->module_id, - mod_id_target); - ue_context_target_p->ue_context.handover_info = - CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_context, - (void *)&ue_context_pP->ue_context.handover_info->as_context, - sizeof(LTE_AS_Context_t)); - memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_config, - (void *)&ue_context_pP->ue_context.handover_info->as_config, - sizeof(LTE_AS_Config_t)); - ue_context_target_p->ue_context.handover_info->ho_prepare = 0x00;// 0xFF; - ue_context_target_p->ue_context.handover_info->ho_complete = 0; - ue_context_pP->ue_context.handover_info->modid_t = mod_id_target; - ue_context_pP->ue_context.handover_info->ueid_s = ue_context_pP->ue_context.rnti; - ue_context_pP->ue_context.handover_info->modid_s = ctxt_pP->module_id; - ue_context_target_p->ue_context.handover_info->modid_t = mod_id_target; - ue_context_target_p->ue_context.handover_info->modid_s = ctxt_pP->module_id; - ue_context_target_p->ue_context.handover_info->ueid_t = ue_context_target_p->ue_context.rnti; - } else { - LOG_E(RRC, "\nError in obtaining free UE id in target eNB %ld for handover \n", targetPhyId); - } - } else { - LOG_E(RRC, "\nError in obtaining Module ID of target eNB for handover \n"); - } -} -#endif - void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m) { struct rrc_eNB_ue_context_s *ue_context_target_p = NULL; /* TODO: get proper UE rnti */ @@ -4109,15 +4009,10 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p); LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid); ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - //ue_context_target_p->ue_context.handover_info->source_x2id = m->source_x2id; ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; ue_context_target_p->ue_context.handover_info->state = HO_ACK; - /* TODO: remove this hack */ - ue_context_target_p->ue_context.handover_info->source_assoc_id = m->source_assoc_id; - //ue_context_target_p->ue_context.handover_info->modid_t = mod_id; - //ue_context_target_p->ue_context.handover_info->modid_t = m->target_mod_id; - //ue_context_target_p->ue_context.handover_info->modid_s = 1-mod_id; - //ue_context_target_p->ue_context.handover_info->ueid_s = m->source_rnti; + ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id; + ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id; memset (ue_context_target_p->ue_context.nh, 0, 32); ue_context_target_p->ue_context.nh_ncc = -1; memcpy (ue_context_target_p->ue_context.kenb, m->kenb, 32); @@ -4261,28 +4156,6 @@ struct rrc_eNB_ue_context_s *ue_context_p) { } } -#if 0 -//----------------------------------------------------------------------------- -void -rrc_eNB_process_handoverPreparationInformation( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP -) -//----------------------------------------------------------------------------- -{ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending LTE_RRCConnectionReconfiguration to UE %d \n", - ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.rnti); - rrc_eNB_generate_RRCConnectionReconfiguration_handover( - ctxt_pP, - ue_context_pP, - NULL, - 0); -} -#endif - void check_handovers( protocol_ctxt_t *const ctxt_pP @@ -4327,12 +4200,10 @@ check_handovers( rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size); rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP); - /* TODO: remove this hack */ - //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = 1 - ctxt_pP->module_id; - //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = ue_context_p->ue_context.handover_info->modid_t; - //X2AP_HANDOVER_REQ_ACK(msg).source_x2id = ue_context_p->ue_context.handover_info->source_x2id; - X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->source_assoc_id; + X2AP_HANDOVER_REQ_ACK(msg).rnti = ue_context_p->ue_context.rnti; + X2AP_HANDOVER_REQ_ACK(msg).x2_id_target = ue_context_p->ue_context.handover_info->x2_id; + X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->assoc_id; /* Call admission control not implemented yet */ X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs; @@ -4347,70 +4218,6 @@ check_handovers( } } -#if 0 -//----------------------------------------------------------------------------- -void -check_handovers( - protocol_ctxt_t *const ctxt_pP -) -//----------------------------------------------------------------------------- -{ - int result; - struct rrc_eNB_ue_context_s *ue_context_p; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head) { - ctxt_pP->rnti = ue_context_p->ue_id_rnti; - - if (ue_context_p->ue_context.handover_info != NULL) { - if (ue_context_p->ue_context.handover_info->ho_prepare == 0xFF) { - LOG_D(RRC, - "[eNB %d] Frame %d: Incoming handover detected for new UE_idx %d (source eNB %d->target eNB %d) \n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti, - ctxt_pP->module_id, - ue_context_p->ue_context.handover_info->modid_t); - // source eNB generates LTE_RRCConnectionreconfiguration to prepare the HO - rrc_eNB_process_handoverPreparationInformation( - ctxt_pP, - ue_context_p); - ue_context_p->ue_context.handover_info->ho_prepare = 0xF1; - } - - if (ue_context_p->ue_context.handover_info->ho_complete == 0xF1) { - LOG_D(RRC, - "[eNB %d] Frame %d: handover Command received for new UE_id %x current eNB %d target eNB: %d \n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti, - ctxt_pP->module_id, - ue_context_p->ue_context.handover_info->modid_t); - //rrc_eNB_process_handoverPreparationInformation(enb_mod_idP,frameP,i); - result = pdcp_data_req(ctxt_pP, - SRB_FLAG_YES, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - ue_context_p->ue_context.handover_info->size, - ue_context_p->ue_context.handover_info->buf, - PDCP_TRANSMISSION_MODE_CONTROL -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - - //AssertFatal(result == TRUE, "PDCP data request failed!\n"); - if(result != TRUE) { - LOG_I(RRC, "PDCP data request failed!\n"); - return; - } - - ue_context_p->ue_context.handover_info->ho_complete = 0xF2; - } - } - } -} -#endif - void rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, @@ -8210,7 +8017,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { int CC_id; protocol_ctxt_t ctxt; -// memset(&ctxt, 0, sizeof(ctxt)); + memset(&ctxt, 0, sizeof(ctxt)); // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); @@ -8341,16 +8148,20 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case X2AP_HANDOVER_REQ: - LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s at frame %d subframe %d\n", instance, msg_name_p, - ctxt.frame, ctxt.subframe); + LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s\n", instance, msg_name_p); rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p)); break; case X2AP_HANDOVER_REQ_ACK: { struct rrc_eNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti); - LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s at frame %d subframe %d \n", instance, msg_name_p, - ctxt.frame,ctxt.subframe); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti); + if (ue_context_p == NULL) { + /* is it possible? */ + LOG_E(RRC, "could not find UE (rnti %x) while processing X2AP_HANDOVER_REQ_ACK\n", + X2AP_HANDOVER_REQ_ACK(msg_p).rnti); + exit(1); + } + LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p); DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort(); @@ -8362,9 +8173,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) { case X2AP_UE_CONTEXT_RELEASE: { struct rrc_eNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti); - LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s at frame %d subframe %d \n", instance, msg_name_p, - ctxt.frame,ctxt.subframe); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti); + LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p); DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort(); diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index e2e434feb7..82818fcd1e 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -2102,9 +2102,8 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE); - X2AP_UE_CONTEXT_RELEASE (msg_p).old_eNB_ue_x2ap_id = 0; - X2AP_UE_CONTEXT_RELEASE (msg_p).new_eNB_ue_x2ap_id = 0; - X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->source_assoc_id; + X2AP_UE_CONTEXT_RELEASE (msg_p).rnti = ue_context_pP->ue_context.rnti; + X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->assoc_id; itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); return (0); } diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 19031bceaf..c05495a0c4 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -40,6 +40,7 @@ #include "x2ap_eNB_handler.h" #include "x2ap_eNB_generate_messages.h" #include "x2ap_common.h" +#include "x2ap_ids.h" #include "queue.h" #include "assertions.h" @@ -80,8 +81,8 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_handover_req_ack_t *x2ap_handover_req_ack); static -void x2ap_eNB_handle_ue_context_release(instance_t instance, - x2ap_ue_context_release_t *x2ap_ue_context_release); +void x2ap_eNB_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release); static @@ -299,6 +300,8 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length; new_instance->num_cc = x2ap_register_eNB->num_cc; + x2ap_id_manager_init(&new_instance->id_manager); + for (int i = 0; i< x2ap_register_eNB->num_cc; i++) { new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i]; @@ -376,15 +379,10 @@ static void x2ap_eNB_handle_handover_req(instance_t instance, x2ap_handover_req_t *x2ap_handover_req) { - /* TODO: remove this hack (the goal is to find the correct - * eNodeB structure for the target) - we need a proper way for RRC - * and X2AP to identify eNodeBs - * RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in - * the configuration file) - * as far as I understand.. CROUX - */ x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; + x2ap_id_manager *id_manager; + int ue_id; int target_pci = x2ap_handover_req->target_physCellId; @@ -394,9 +392,18 @@ void x2ap_eNB_handle_handover_req(instance_t instance, target = x2ap_is_eNB_pci_in_list(target_pci); DevAssert(target != NULL); - /* store rnti at index 0 */ - //x2id_to_source_rnti[0] = x2ap_handover_req->source_rnti; - x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req); + /* allocate x2ap ID */ + id_manager = &instance_p->id_manager; + ue_id = x2ap_allocate_new_id(id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + /* TODO: cancel handover: send (to be defined) message to RRC */ + exit(1); + } + /* id_source is ue_id, id_target is unknown yet */ + x2ap_set_ids(id_manager, ue_id, x2ap_handover_req->rnti, ue_id, -1); + + x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req, ue_id); } static @@ -413,6 +420,9 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; int source_assoc_id = x2ap_handover_req_ack->source_assoc_id; + int ue_id; + int id_source; + int id_target; instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -420,19 +430,23 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, target = x2ap_get_eNB(NULL, source_assoc_id, 0); DevAssert(target != NULL); + /* rnti is a new information, save it */ + ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target); + x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack); - //x2ap_eNB_generate_x2_handover_req_ack(instance_p, target, x2ap_handover_req_ack->source_x2id, - //x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size); } static -void x2ap_eNB_handle_ue_context_release(instance_t instance, - x2ap_ue_context_release_t *x2ap_ue_context_release) +void x2ap_eNB_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release) { x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; int source_assoc_id = x2ap_ue_context_release->source_assoc_id; - + int ue_id; instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -440,6 +454,14 @@ void x2ap_eNB_handle_ue_context_release(instance_t instance, DevAssert(target != NULL); x2ap_eNB_generate_x2_ue_context_release(instance_p, target, x2ap_ue_context_release); + + /* free the X2AP UE ID */ + ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti); + if (ue_id == -1) { + X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti); + exit(1); + } + x2ap_release_id(&instance_p->id_manager, ue_id); } void *x2ap_task(void *arg) { @@ -474,7 +496,7 @@ void *x2ap_task(void *arg) { break; case X2AP_UE_CONTEXT_RELEASE: - x2ap_eNB_handle_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), &X2AP_UE_CONTEXT_RELEASE(received_msg)); break; diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index f90176430c..3356a101b4 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -33,6 +33,8 @@ #include "sctp_eNB_defs.h" +#include "x2ap_ids.h" + #ifndef X2AP_ENB_DEFS_H_ #define X2AP_ENB_DEFS_H_ @@ -180,6 +182,8 @@ typedef struct x2ap_eNB_instance_s { uint16_t sctp_out_streams; uint32_t enb_port_for_X2C; int multi_sd; + + x2ap_id_manager id_manager; } x2ap_eNB_instance_t; typedef struct { diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 27fd766614..c13469d5d4 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -35,6 +35,7 @@ #include "x2ap_eNB_generate_messages.h" #include "x2ap_eNB_encoder.h" #include "x2ap_eNB_decoder.h" +#include "x2ap_ids.h" #include "x2ap_eNB_itti_messaging.h" @@ -409,7 +410,7 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, } int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, - x2ap_handover_req_t *x2ap_handover_req) + x2ap_handover_req_t *x2ap_handover_req, int ue_id) { X2AP_X2AP_PDU_t pdu; @@ -439,7 +440,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = x2ap_handover_req->old_eNB_ue_x2ap_id; + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -572,6 +573,9 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, X2AP_HandoverRequestAcknowledge_IEs_t *ie; X2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; X2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; + int ue_id; + int id_source; + int id_target; uint8_t *buffer; uint32_t len; @@ -580,6 +584,10 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, DevAssert(instance_p != NULL); DevAssert(x2ap_eNB_data_p != NULL); + ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + /* Prepare the X2AP handover message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; @@ -593,7 +601,7 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_ignore; ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = 0; + ie->value.choice.UE_X2AP_ID = id_source; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -601,7 +609,7 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_ignore; ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1; - ie->value.choice.UE_X2AP_ID_1 = 0; + ie->value.choice.UE_X2AP_ID_1 = id_target; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -655,6 +663,9 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 X2AP_X2AP_PDU_t pdu; X2AP_UEContextRelease_t *out; X2AP_UEContextRelease_IEs_t *ie; + int ue_id; + int id_source; + int id_target; uint8_t *buffer; uint32_t len; @@ -663,6 +674,14 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 DevAssert(instance_p != NULL); DevAssert(x2ap_eNB_data_p != NULL); + ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti); + if (ue_id == -1) { + X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti); + exit(1); + } + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + /* Prepare the X2AP ue context relase message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; @@ -676,7 +695,7 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = x2ap_ue_context_release->old_eNB_ue_x2ap_id; + ie->value.choice.UE_X2AP_ID = id_source; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -684,7 +703,7 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1; - ie->value.choice.UE_X2AP_ID_1 = x2ap_ue_context_release->new_eNB_ue_x2ap_id; + ie->value.choice.UE_X2AP_ID_1 = id_target; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 6636413fc6..059d213277 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -48,7 +48,7 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, long cause_value); int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, - x2ap_handover_req_t *x2ap_handover_req); + x2ap_handover_req_t *x2ap_handover_req, int ue_id); int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_ack_t *x2ap_handover_req_ack); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index cb216dfc81..c07f064319 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -36,6 +36,7 @@ #include "x2ap_eNB_defs.h" #include "x2ap_eNB_handler.h" #include "x2ap_eNB_decoder.h" +#include "x2ap_ids.h" #include "x2ap_eNB_management_procedures.h" #include "x2ap_eNB_generate_messages.h" @@ -593,6 +594,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; + int ue_id; DevAssert (pdu != NULL); x2HandoverRequest = &pdu->choice.initiatingMessage.value.choice.HandoverRequest; @@ -608,19 +610,30 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); - //X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti; - //X2AP_HANDOVER_REQ(m).source_x2id = x2HandoverRequest->old_eNB_UE_X2AP_ID; if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; - } else { - X2AP_HANDOVER_REQ(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; } + /* allocate a new X2AP UE ID */ + ue_id = x2ap_allocate_new_id(&instance_p->id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + /* TODO: cancel handover: send HO preparation failure to source eNB */ + exit(1); + } + /* rnti is unknown yet, must not be set to -1, 0 is fine */ + x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id); + + X2AP_HANDOVER_REQ(msg).x2_id = ue_id; + //X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. //measResultListEUTRA.list.array[ncell_index]->physCellId; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, @@ -643,7 +656,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, /* TODO: properly store Target Cell ID */ - X2AP_HANDOVER_REQ(msg).source_assoc_id = assoc_id; + X2AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); @@ -699,9 +712,6 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; @@ -719,6 +729,10 @@ int x2ap_eNB_handle_handover_response (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; + int ue_id; + int id_source; + int id_target; + int rnti; DevAssert (pdu != NULL); x2HandoverRequestAck = &pdu->choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; @@ -734,12 +748,32 @@ int x2ap_eNB_handle_handover_response (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ_ACK); - /* TODO: fill the message */ - //extern int x2id_to_source_rnti[1]; - //X2AP_HANDOVER_REQ_ACK(m).source_x2id = x2HandoverRequestAck->old_eNB_UE_X2AP_ID; - //X2AP_HANDOVER_REQ_ACK(m).source_rnti = x2id_to_source_rnti[x2HandoverRequestAck->old_eNB_UE_X2AP_ID]; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + id_source = ie->value.choice.UE_X2AP_ID; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + id_target = ie->value.choice.UE_X2AP_ID_1; + + ue_id = id_source; + + if (id_source != x2ap_id_get_id_source(&instance_p->id_manager, ue_id)) { + X2AP_ERROR("incorrect X2AP IDs for UE (old ID %d new ID %d)\n", id_source, id_target); + exit(1); + } + + rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + + /* id_target is a new information, store it */ + x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target); + + X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); @@ -752,9 +786,6 @@ int x2ap_eNB_handle_handover_response (instance_t instance, memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; } @@ -772,6 +803,9 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; + int ue_id; + int id_source; + int id_target; DevAssert (pdu != NULL); x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease; @@ -787,22 +821,36 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); - X2AP_UE_CONTEXT_RELEASE(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; + id_source = ie->value.choice.UE_X2AP_ID; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); - X2AP_UE_CONTEXT_RELEASE(msg).new_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; + id_target = ie->value.choice.UE_X2AP_ID_1; - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); + ue_id = id_source; + + if (id_target != x2ap_id_get_id_target(&instance_p->id_manager, ue_id)) { + X2AP_ERROR("UE context release: bad id_target for UE %x (id_source %d) expected %d got %d\n", + x2ap_id_get_rnti(&instance_p->id_manager, ue_id), + id_source, + x2ap_id_get_id_target(&instance_p->id_manager, ue_id), + id_target); + } + + X2AP_UE_CONTEXT_RELEASE(msg).rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + x2ap_release_id(&instance_p->id_manager, ue_id); + return 0; } diff --git a/openair2/X2AP/x2ap_ids.c b/openair2/X2AP/x2ap_ids.c new file mode 100644 index 0000000000..b5607821fe --- /dev/null +++ b/openair2/X2AP/x2ap_ids.c @@ -0,0 +1,92 @@ +/* + * 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 + */ + +#include "x2ap_ids.h" + +#include + +void x2ap_id_manager_init(x2ap_id_manager *m) +{ + int i; + memset(m, 0, sizeof(x2ap_id_manager)); + for (i = 0; i < X2AP_MAX_IDS; i++) + m->ids[i].rnti = -1; +} + +int x2ap_allocate_new_id(x2ap_id_manager *m) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti == -1) { + m->ids[i].rnti = 0; + m->ids[i].id_source = -1; + m->ids[i].id_target = -1; + return i; + } + return -1; +} + +void x2ap_release_id(x2ap_id_manager *m, int id) +{ + m->ids[id].rnti = -1; +} + +int x2ap_find_id(x2ap_id_manager *m, int id_source, int id_target) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source && + m->ids[i].id_target == id_target) + return i; + return -1; +} + +int x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti == rnti) + return i; + return -1; +} + +void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target) +{ + m->ids[ue_id].rnti = rnti; + m->ids[ue_id].id_source = id_source; + m->ids[ue_id].id_target = id_target; +} + +int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_source; +} + +int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_target; +} + +int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].rnti; +} diff --git a/openair2/X2AP/x2ap_ids.h b/openair2/X2AP/x2ap_ids.h new file mode 100644 index 0000000000..2232308f73 --- /dev/null +++ b/openair2/X2AP/x2ap_ids.h @@ -0,0 +1,47 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef X2AP_IDS_H_ +#define X2AP_IDS_H_ + +#define X2AP_MAX_IDS 16 + +typedef struct { + int rnti; /* -1 when free */ + int id_source; + int id_target; +} x2ap_id; + +typedef struct { + x2ap_id ids[X2AP_MAX_IDS]; +} x2ap_id_manager; + +void x2ap_id_manager_init(x2ap_id_manager *m); +int x2ap_allocate_new_id(x2ap_id_manager *m); +void x2ap_release_id(x2ap_id_manager *m, int id); +int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target); +int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti); +void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target); +int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id); +int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id); +int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id); + +#endif /* X2AP_IDS_H_ */ From 78b6fef63c200ccb38173bcfb98a454b284fb3f4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 28 Feb 2019 12:54:03 +0100 Subject: [PATCH 12/26] fix compilation in nos1 mode Some #if defined(ENABLE_USE_MME)/#endif were added here and there. The nos1 softmodem has not been tested, maybe this commit breaks things. --- openair2/RRC/LTE/rrc_eNB.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 49ca46b35d..95048d763e 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -850,7 +850,9 @@ rrc_eNB_free_UE( LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", enb_mod_idP, rnti); +#if defined(ENABLE_USE_MME) rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); +#endif // send cause 21: radio connection with ue lost /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before @@ -866,7 +868,9 @@ rrc_eNB_free_UE( LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", enb_mod_idP, rnti); +#if defined(ENABLE_USE_MME) rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); +#endif // send cause 20: user inactivity return; } @@ -1039,7 +1043,9 @@ rrc_eNB_process_RRCConnectionSetupComplete( if (EPC_MODE_ENABLED == 1) { // Forward message to S1AP layer +#if defined(ENABLE_USE_MME) rrc_eNB_send_S1AP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcConnectionSetupComplete); +#endif } else { // RRC loop back (no S1AP), send SecurityModeCommand to UE rrc_eNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP); @@ -4120,6 +4126,7 @@ void rrc_eNB_process_handoverCommand( ue_context->ue_context.handover_info->size = size; } +#if defined(ENABLE_USE_MME) void rrc_eNB_handover_ue_context_release( protocol_ctxt_t *const ctxt_pP, struct rrc_eNB_ue_context_s *ue_context_p) { @@ -4155,6 +4162,7 @@ struct rrc_eNB_ue_context_s *ue_context_p) { rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); } } +#endif /* defined(ENABLE_USE_MME) */ void check_handovers( @@ -5160,6 +5168,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc , 0, 0 #endif ); +#if defined(ENABLE_USE_MME) rrc_eNB_process_security ( ctxt_pP, ue_context_p, @@ -5172,6 +5181,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc ctxt_pP, ue_context_p, FALSE); +#endif // Add a new user (called during the HO procedure) LOG_I(RRC, "rrc_eNB_target_add_ue_handover module_id %d rnti %d\n", ctxt_pP->module_id, ctxt_pP->rnti); @@ -7576,9 +7586,11 @@ rrc_eNB_decode_dcch( if (EPC_MODE_ENABLED) { if (EPC_MODE_ENABLED == 1) { +#if defined(ENABLE_USE_MME) rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ul_dcch_msg); +#endif } } else { ue_context_p->ue_context.nb_of_e_rabs = 1; @@ -7626,9 +7638,11 @@ rrc_eNB_decode_dcch( sdu_sizeP); if (EPC_MODE_ENABLED == 1) { +#if defined(ENABLE_USE_MME) rrc_eNB_send_S1AP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg); +#endif } break; @@ -7837,6 +7851,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) } } +#if defined(ENABLE_USE_MME) if (ue_context_p->ue_context.handover_info != NULL) { if (ue_context_p->ue_context.handover_info->state == HO_RELEASE) { ue_to_be_removed = ue_context_p; @@ -7844,6 +7859,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) break; //break RB_FOREACH (why to break ?) } } +#endif pthread_mutex_lock(&rrc_release_freelist); From 5bf595a0ad7898f9c598f85c605607c87d526ac8 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 28 Feb 2019 20:16:17 +0100 Subject: [PATCH 13/26] fixing added cppcheck errors Signed-off-by: Raphael Defosseux --- openair2/X2AP/x2ap_eNB_handler.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index c07f064319..9da9278741 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -755,10 +755,22 @@ int x2ap_eNB_handle_handover_response (instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + id_source = ie->value.choice.UE_X2AP_ID; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + id_target = ie->value.choice.UE_X2AP_ID_1; ue_id = id_source; @@ -829,11 +841,21 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + id_source = ie->value.choice.UE_X2AP_ID; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + id_target = ie->value.choice.UE_X2AP_ID_1; ue_id = id_source; From e3bb3ab7d305761df4701a1ad0099ba3ca4d06a9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 5 Mar 2019 18:27:54 +0100 Subject: [PATCH 14/26] Change integer based conf parameter from string --- .../GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf index d33a9dc41f..a69daff48e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf @@ -13,7 +13,7 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2;} ); From ea0e313f8165cdd422d80ab290684d7d87febbd2 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 6 Mar 2019 17:59:06 +0100 Subject: [PATCH 15/26] CI: issue #410 --> command options are displayed in build HTML report Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnRH.sh | 5 +++-- ci-scripts/reportBuildLocally.sh | 18 ++++++++++++++++++ ci-scripts/waitBuildOnVM.sh | 10 ++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh index bb57cde165..dd3c382951 100755 --- a/ci-scripts/buildOnRH.sh +++ b/ci-scripts/buildOnRH.sh @@ -204,12 +204,13 @@ then STATUS=-1 fi +echo "COMMAND: build_oai -I -w USRP --eNB" > $ARCHIVES_LOC/build_final_status.log if [ $STATUS -eq 0 ] then - echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log echo "STATUS seems OK" else - echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log echo "STATUS failed?" fi exit $STATUS diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 3e385fb810..d237cc652b 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -143,13 +143,21 @@ function summary_table_header { echo "

$1

" >> ./build_results.html if [ -f $2/build_final_status.log ] then + if [ `grep -c COMMAND $2/build_final_status.log` -eq 1 ] + then + COMMAND=`grep COMMAND $2/build_final_status.log | sed -e "s#COMMAND: ##"` + else + COMMAND="Unknown" + fi if [ `grep -c BUILD_OK $2/build_final_status.log` -eq 1 ] then echo "
" >> ./build_results.html + echo " $COMMAND " >> ./build_results.html echo " BUILD was SUCCESSFUL " >> ./build_results.html echo "
" >> ./build_results.html else echo "
" >> ./build_results.html + echo " $COMMAND " >> ./build_results.html echo " BUILD was a FAILURE! " >> ./build_results.html echo "
" >> ./build_results.html fi @@ -220,6 +228,13 @@ function sca_summary_table_header { NB_WARNINGS=`egrep -c "severity=\"warning\"" $1` ADDED_ERRORS="0" ADDED_WARNINGS="0" + FINAL_LOG=`echo $1 | sed -e "s#cppcheck\.xml#build_final_status.log#"` + if [ `grep -c COMMAND $FINAL_LOG` -eq 1 ] + then + COMMAND=`grep COMMAND $FINAL_LOG | sed -e "s#COMMAND: ##"` + else + COMMAND="Unknown" + fi if [ $MR_TRIG -eq 1 ] then if [ -d ../../cppcheck_archives ] @@ -237,12 +252,14 @@ function sca_summary_table_header { if [ $NB_ERRORS -eq 0 ] && [ $NB_WARNINGS -eq 0 ] then echo "
" >> ./build_results.html + echo " $COMMAND

" >> ./build_results.html echo " CPPCHECK found NO error and NO warning " >> ./build_results.html echo "
" >> ./build_results.html else if [ $NB_ERRORS -eq 0 ] then echo "
" >> ./build_results.html + echo " $COMMAND

" >> ./build_results.html if [ $PU_TRIG -eq 1 ] then echo " CPPCHECK found NO error and $NB_WARNINGS warnings " >> ./build_results.html @@ -259,6 +276,7 @@ function sca_summary_table_header { echo "
" >> ./build_results.html else echo "
" >> ./build_results.html + echo " $COMMAND

" >> ./build_results.html if [ $PU_TRIG -eq 1 ] then echo " CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings " >> ./build_results.html diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 2820b88647..7e4504944f 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -185,10 +185,16 @@ function check_on_vm_build { fi fi + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + echo "COMMAND: cppcheck $BUILD_OPTIONS . 2> cppcheck.xml" > $ARCHIVES_LOC/build_final_status.log + else + echo "COMMAND: build_oai -I $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log + fi if [[ $STATUS -eq 0 ]] then - echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log else - echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log fi } From 63989f579b80e2cbc44f698caeed32e58f1d2a82 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 8 Mar 2019 10:28:59 +0100 Subject: [PATCH 16/26] T: minor: fix typo --- common/utils/T/tracer/macpdu2wireshark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index 7ea3b70bb4..8720efd8c0 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -289,7 +289,7 @@ void usage(void) { " -max-sib report at maximum n SIBs\n" " -live run live\n" " -live-ip tracee's IP address (default %s)\n" - " -live-port tracee's port (default %d)\n" + " -live-port tracee's port (default %d)\n" "-i and -live are mutually exclusive options. One of them must be provided\n" "but not both.\n", DEFAULT_IP, From f83c92d799137b827c74534f33cc84aed807f0cf Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 8 Mar 2019 10:52:12 +0100 Subject: [PATCH 17/26] CI: add a procedure to reset B2xx boards before running Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 5 +++++ ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml | 2 +- ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 5e89384ebb..6fa3ae2f24 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -408,6 +408,11 @@ class SSHConnection(): self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + self.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) self.close() self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 5) + result = re.search('type: b200', str(self.ssh.before)) + if result is not None: + logging.debug('Found a B2xx device --> resetting it') + self.command('echo ' + self.eNBPassword + ' | sudo -S sudo b2xx_fx3_utils --reset-device', '\$', 5) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) # Initialize_eNB_args usually start with -O and followed by the location in repository full_config_file = self.Initialize_eNB_args.replace('-O ','') diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml index d5a25c7fa7..03172ef6bd 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml @@ -65,7 +65,7 @@ Ping ping (5MHz - 20 sec) -c 20 - 25 + 50 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml index 1de23d05d6..3a877ea3c3 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml @@ -81,7 +81,7 @@ Ping ping (5MHz - 20 sec) -c 20 - 25 + 50 From 067a4129e2357f5111deee3cd7b40448d4b06f04 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 8 Mar 2019 13:34:16 +0100 Subject: [PATCH 18/26] CI: minor fixes: -- Moved the Gitlab notification within the try: As a result, when fails, the notification will be a fail -- Changed all exit by return in the runTest script Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 30 +++++++++++++++--------------- ci-scripts/runTestOnVM.sh | 32 +++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 19c26aa8e4..1919a7e03b 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -329,13 +329,13 @@ pipeline { stage ("Test physical simulators") { steps { script { - gitlabCommitStatus(name: "Test phy-sim") { - timeout (time: 20, unit: 'MINUTES') { - try { + timeout (time: 20, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test phy-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } catch (Exception e) { - currentBuild.result = 'FAILURE' } + } catch (Exception e) { + currentBuild.result = 'FAILURE' } } } @@ -360,13 +360,13 @@ pipeline { stage ("Test basic simulator") { steps { script { - gitlabCommitStatus(name: "Test basic-sim") { - timeout (time: 30, unit: 'MINUTES') { - try { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test basic-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } catch (Exception e) { - currentBuild.result = 'FAILURE' } + } catch (Exception e) { + currentBuild.result = 'FAILURE' } } } @@ -375,13 +375,13 @@ pipeline { stage ("Test L2 simulator") { steps { script { - gitlabCommitStatus(name: "Test L2-sim") { - timeout (time: 30, unit: 'MINUTES') { - try { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test L2-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } catch (Exception e) { - currentBuild.result = 'FAILURE' } + } catch (Exception e) { + currentBuild.result = 'FAILURE' } } } diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 5b9ba3d093..48f3adb675 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -664,7 +664,7 @@ function run_test_on_vm { if [ "$RUN_OPTIONS" == "none" ] then echo "No run on VM testing for this variant currently" - exit $STATUS + return fi if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]] @@ -823,7 +823,8 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -882,7 +883,8 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -941,7 +943,8 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -993,7 +996,8 @@ function run_test_on_vm { echo "ERROR: compiling flexran controller on vm went wrong" terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi FLEXRAN_CTL_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#flexran-rtc#"` FLEXRAN_CTL_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#flexran-rtc-cmds#"` @@ -1003,7 +1007,8 @@ function run_test_on_vm { echo "ERROR: Flexran Ctl VM is not alive" terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi uvt-kvm wait $FLEXRAN_CTL_VM_NAME --insecure FLEXRAN_CTL_VM_IP_ADDR=`uvt-kvm ip $FLEXRAN_CTL_VM_NAME` @@ -1038,7 +1043,8 @@ function run_test_on_vm { terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 03_enb_ue_connected get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -1080,7 +1086,8 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -1131,7 +1138,8 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -1182,7 +1190,8 @@ function run_test_on_vm { # recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC # terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR # echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log -# exit -1 +# STATUS=-1 +# return # fi # get_ue_ip_addr $VM_CMDS $VM_IP_ADDR # @@ -1294,7 +1303,8 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi echo "############################################################" From 99fcdfd0f7c9e9131044ed602735412ff3271397 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 8 Mar 2019 15:22:21 +0100 Subject: [PATCH 19/26] CI: reduce failure constraint on TDD-5MHz in unbalanced UL iperf test Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml index 03172ef6bd..9cdd7523ad 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml @@ -112,7 +112,7 @@ Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) -u -b 2M -t 30 -i 1 -R - 50 + 80 unbalanced From c9dcaa53afa047649ba835e0fb64631ea0a72324 Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 8 Mar 2019 16:00:09 +0100 Subject: [PATCH 20/26] noS1 woking with tun interfaces and basic simu --- cmake_targets/CMakeLists.txt | 2 +- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 4 +- openair1/SIMULATION/ETH_TRANSPORT/proto.h | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 21 +++++---- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 2 + openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 30 ++++++++---- openair2/LAYER2/RLC/rlc.c | 4 +- openair2/RRC/LTE/rrc_UE.c | 10 ++-- openair2/RRC/LTE/rrc_eNB.c | 16 ++----- openair2/RRC/NAS/nas_config.c | 6 +-- targets/RT/USER/lte-softmodem.c | 7 ++- targets/RT/USER/lte-ue.c | 46 +++++++------------ targets/RT/USER/lte-uesoftmodem.c | 8 ++-- 13 files changed, 80 insertions(+), 78 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 810d3465c2..7fb0c0c6a9 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1287,7 +1287,7 @@ set(L2_SRC ${RLC_DIR}/rlc.c ${RLC_DIR}/rlc_rrc.c ${RLC_DIR}/rlc_mpls.c - ${RRC_DIR}/rrc_UE.c +# ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_S1AP.c ${RRC_DIR}/rrc_eNB_UE_context.c diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index 358a561c21..cdda4dfe78 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -93,12 +93,12 @@ static int tun_alloc(char *dev) { return fd; } -int netlink_init_tun(void) { +int netlink_init_tun(char *ifprefix) { int ret; char ifname[64]; for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { - sprintf(ifname, "oaitun_ue%d",i+1); + sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1); nas_sock_fd[i] = tun_alloc(ifname); if (nas_sock_fd[i] == -1) { diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index 6d54bfb24c..d84322da31 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -62,6 +62,6 @@ int multicast_link_read_data_from_sock(uint8_t eNB_flag); void clear_eNB_transport_info(uint8_t); void clear_UE_transport_info(uint8_t); int netlink_init(void); -int netlink_init_tun(void); +int netlink_init_tun(char *ifsuffix); #endif /* EMU_PROTO_H_ */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 76e36dca9a..3801df9a39 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -51,7 +51,7 @@ #include "targets/COMMON/openairinterface5g_limits.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" #include "UTIL/OSA/osa_defs.h" - +#include "openair2/RRC/NAS/nas_config.h" # include "intertask_interface.h" @@ -1145,9 +1145,10 @@ pdcp_run ( } while(msg_p != NULL); // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer - if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { - pdcp_fifo_read_input_sdus(ctxt_pP); - } +// if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { + pdcp_fifo_read_input_sdus(ctxt_pP); + } // PDCP -> NAS/IP traffic: RX if (ctxt_pP->enb_flag) { @@ -2027,9 +2028,6 @@ rrc_pdcp_config_req ( } } - -//----------------------------------------------------------------------------- - uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { /* temporary enforce netlink when UE_NAS_USE_TUN is set, this is while switching from noS1 as build option @@ -2045,8 +2043,14 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { if (PDCP_USE_NETLINK) { if(UE_NAS_USE_TUN) { - netlink_init_tun(); + netlink_init_tun("ue"); + LOG_I(PDCP, "UE pdcp will use tun interface\n"); + } else if(ENB_NAS_USE_TUN) { + netlink_init_tun("enb"); + nas_config(1, 1, 1, "enb"); + LOG_I(PDCP, "ENB pdcp will use tun interface\n"); } else { + LOG_I(PDCP, "pdcp will use kernel modules\n"); netlink_init(); } } @@ -2054,6 +2058,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { return pdcp_params.optmask ; } + //----------------------------------------------------------------------------- void pdcp_free ( diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 8f30608cd8..cf8d1a1fd6 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -55,6 +55,7 @@ #define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13) #define LINK_ENB_PDCP_TO_GTPV1U_BIT (1<< 14) #define UE_NAS_USE_TUN_BIT (1<< 15) +#define ENB_NAS_USE_TUN_BIT (1<< 16) typedef struct { uint64_t optmask; } pdcp_params_t; @@ -63,6 +64,7 @@ typedef struct { #define LINK_ENB_PDCP_TO_IP_DRIVER ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_IP_DRIVER_BIT) #define LINK_ENB_PDCP_TO_GTPV1U ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_GTPV1U_BIT) #define UE_NAS_USE_TUN ( get_pdcp_optmask() & UE_NAS_USE_TUN_BIT) +#define ENB_NAS_USE_TUN ( get_pdcp_optmask() & ENB_NAS_USE_TUN_BIT) uint64_t get_pdcp_optmask(void); extern pthread_t pdcp_thread; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index a55cf906a0..8a44d7b1a8 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -125,7 +125,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) ); } else if (UE_NAS_USE_TUN) { ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); - } else if (PDCP_USE_NETLINK) {//UE_NAS_USE_TUN + } else if (ENB_NAS_USE_TUN) { + ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + } else if (PDCP_USE_NETLINK) { memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite); nas_nlh_tx->nlmsg_len = sizeToWrite; ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0); @@ -143,8 +145,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { //----------------------------------------------------------------------------- int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { pdcp_data_req_header_t pdcp_read_header_g; + - if (UE_NAS_USE_TUN) { + if (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) { protocol_ctxt_t ctxt = *ctxt_pP; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; @@ -155,20 +158,31 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { do { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); - len = read(nas_sock_fd[ctxt_pP->module_id], &nl_rx_buf, NL_MAX_PAYLOAD); + len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); if (len<=0) continue; - LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + + if (UE_NAS_USE_TUN) { + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + } else { + ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0]; + ctxt.enb_flag=ENB_FLAG_YES; + ctxt.module_id=0; + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + } + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + + if (h_rc == HASH_TABLE_OK) { LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", ctxt.frame, ctxt.instance, len, rab_id); - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id); MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, @@ -192,7 +206,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { MSC_AS_TIME_ARGS(ctxt_pP), ctxt.instance, rab_id, rab_id, len); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); } diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 309facf34b..b07f5b99fd 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -584,14 +584,14 @@ void rlc_data_ind ( const sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { //----------------------------------------------------------------------------- -#if defined(TRACE_RLC_PAYLOAD) + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, sdu_sizeP); rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP); -#endif + #if T_TRACER if (ctxt_pP->enb_flag) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index d70d7030ab..f8711da639 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -810,18 +810,18 @@ rrc_ue_establish_drb( (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, RADIO_ACCESS_BEARER,Rlc_info_um); */ - if(!EPC_MODE_ENABLED) { +// if(!EPC_MODE_ENABLED) { //# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) ip_addr_offset3 = 0; ip_addr_offset4 = 1; - LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, + LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oip%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id ip_addr_offset3+ue_mod_idP+1, // third_octet ip_addr_offset4+ue_mod_idP+1, // fourth_octet - "ue"); // interface suffix + "oip"); // interface suffix - if (oip_ifup == 0 && (!IS_SOFTMODEM_NOKRNMOD)) { // interface is up --> send a config the DRB + if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, @@ -837,7 +837,7 @@ rrc_ue_establish_drb( } //# endif - } +// } return(0); } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d377f3a8d6..77519b2015 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6150,9 +6150,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( int i, drb_id; int oip_ifup = 0; int dest_ip_offset = 0; - /* avoid gcc warnings */ - (void)oip_ifup; - (void)dest_ip_offset; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; @@ -6272,10 +6269,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); - if (!EPC_MODE_ENABLED) { -// if (PDCP_USE_NETLINK && (!LINK_ENB_PDCP_TO_GTPV1U)) { - // can mean also IPV6 since ether -> ipv6 autoconf -//# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) + if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) { LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", ctxt_pP->module_id, ctxt_pP->module_id); @@ -6283,7 +6277,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id, // interface index ctxt_pP->module_id + 1, // thrid octet ctxt_pP->module_id + 1, // fourth octet - "enb"); + "oai"); if (oip_ifup == 0) { // interface is up --> send a config the DRB module_id_t ue_module_id; dest_ip_offset = 8; @@ -6301,10 +6295,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); - } - -//# endif - } + } /* oip_ifup */ + } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/ LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index 96ef60c13a..2c432cf922 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -236,7 +236,7 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br } // non blocking full configuration of the interface (address, and the two lest octets of the address) -int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix) +int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { //char buf[5]; char ipAddress[20]; @@ -248,8 +248,8 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix sprintf(broadcastAddress, "10.0.%d.255", thirdOctet); - sprintf(interfaceName, "%s%s%d", UE_NAS_USE_TUN?"oaitun_":"oip", - UE_NAS_USE_TUN?ifsuffix:"",interface_id); + sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname, + UE_NAS_USE_TUN?"ue": (ENB_NAS_USE_TUN?"enb":""),interface_id); bringInterfaceUp(interfaceName, 0); // sets the machine address diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 60920eb401..0ee3d6dcf9 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -653,9 +653,12 @@ int main( int argc, char **argv ) { LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); - pdcp_module_init( ( IS_SOFTMODEM_NOS1 && !(IS_SOFTMODEM_NOKRNMOD))? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT); + uint32_t pdcp_initmask = ( IS_SOFTMODEM_NOS1 )? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; # - + if ( IS_SOFTMODEM_NOS1) + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + pdcp_module_init(pdcp_initmask); + if (RC.nb_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP if (create_tasks(1) < 0) { diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index c8709f87c5..853c98df3f 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -578,11 +578,7 @@ static void *UE_thread_synch(void *arg) case pbch: -#if DISABLE_LOG_X - printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); -#else LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); -#endif if (initial_sync( UE, UE->mode ) == 0) { LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", @@ -702,19 +698,11 @@ static void *UE_thread_synch(void *arg) return &UE_thread_synch_retval; // not reached } } -#if DISABLE_LOG_X - printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); -#else LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", freq_offset, UE->rx_total_gain_dB, downlink_frequency[0][0]+freq_offset, downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); -#endif for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; @@ -793,11 +781,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { // most of the time, the thread is waiting here pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); } - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - } - + //printf("Processing sub frqme %d in %s\n", proc->subframe_rx, threadname); initRefTimes(t2); initRefTimes(t3); pickTime(current); @@ -870,12 +854,8 @@ static void *UE_thread_rxn_txnp4(void *arg) { phy_procedures_UE_S_TX(UE,0,0); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - } proc->instance_cnt_rxtx--; - if ( IS_SOFTMODEM_BASICSIM ) { + if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); } if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { @@ -1665,7 +1645,7 @@ void *UE_thread(void *arg) { // update thread index for received subframe UE->current_thread_id[sub_frame] = thread_idx; - if (IS_SOFTMODEM_BASICSIM) { + if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { int t; for (t = 0; t < 2; t++) { UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; @@ -1748,8 +1728,21 @@ void *UE_thread(void *arg) { LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); } pickTime(gotIQs); + struct timespec tv={0}; + tv.tv_nsec=10*1000; + if( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) + tv.tv_sec=INT_MAX; // operate on thread sf mod 2 - AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + if (pthread_mutex_timedlock(&proc->mutex_rxtx, &tv) !=0) { + if ( errno == ETIMEDOUT) { + LOG_E(PHY,"Missed real time\n"); + continue; + } else { + LOG_E(PHY,"System error\n"); + abort(); + } + } + //usleep(3000); if(sub_frame == 0) { //UE->proc.proc_rxtx[0].frame_rx++; //UE->proc.proc_rxtx[1].frame_rx++; @@ -1771,11 +1764,6 @@ void *UE_thread(void *arg) { proc->instance_cnt_rxtx++; LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); - if (proc->instance_cnt_rxtx != 0) { - LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); - if (proc->instance_cnt_rxtx > 2) - exit_fun("instance_cnt_rxtx > 2"); - } AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 78d5bebc43..2eeb4cd426 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -751,7 +751,6 @@ int main( int argc, char **argv ) { cpuf=get_cpu_freq_GHz(); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); -#if defined(ENABLE_ITTI) printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); @@ -761,9 +760,9 @@ int main( int argc, char **argv ) { } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); -#endif + init_opt(); - uint32_t pdcp_initmask = ((!IS_SOFTMODEM_NOS1) || IS_SOFTMODEM_NOKRNMOD)? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); + uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1 )? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_mode == 3) ) { pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; @@ -772,12 +771,11 @@ int main( int argc, char **argv ) { pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; pdcp_module_init( pdcp_initmask ); //TTN for D2D -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) printf ("RRC control socket\n"); rrc_control_socket_init(); printf ("PDCP PC5S socket\n"); pdcp_pc5_socket_init(); -#endif + // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); From f922c8d9172fff06663114d3843caa915c413aae Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 8 Mar 2019 19:30:23 +0100 Subject: [PATCH 21/26] CI: temp fix for CI build Signed-off-by: Raphael Defosseux --- ci-scripts/oai-ci-vm-tool | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index c28f51415e..30d8912f50 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -69,7 +69,7 @@ VM_MEMORY=2048 VM_CPU=4 ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 +NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -w USRP" KEEP_VM_ALIVE=0 RUN_OPTIONS="none" @@ -231,7 +231,7 @@ case $key in VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -w USRP --mu" NBARGS=$[$NBARGS+256] shift @@ -272,7 +272,7 @@ case $key in VM_NAME=ci-enb-ethernet ARCHIVES_LOC=enb_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=8 BUILD_OPTIONS="--eNB -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] shift @@ -281,7 +281,7 @@ case $key in VM_NAME=ci-ue-ethernet ARCHIVES_LOC=ue_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=8 BUILD_OPTIONS="--UE -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] shift @@ -292,7 +292,7 @@ case $key in VM_CPU=8 ARCHIVES_LOC=l2_sim LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=6 BUILD_OPTIONS="--eNB -t ETHERNET" RUN_OPTIONS="complex" NBARGS=$[$NBARGS+256] @@ -314,7 +314,7 @@ case $key in VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -w USRP --mu" NBARGS=$[$NBARGS+256] ;; @@ -351,7 +351,7 @@ case $key in VM_NAME=ci-enb-ethernet ARCHIVES_LOC=enb_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=8 BUILD_OPTIONS="--eNB -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] ;; @@ -359,7 +359,7 @@ case $key in VM_NAME=ci-ue-ethernet ARCHIVES_LOC=ue_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=8 BUILD_OPTIONS="--UE -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] ;; @@ -369,7 +369,7 @@ case $key in VM_CPU=8 ARCHIVES_LOC=l2_sim LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=6 BUILD_OPTIONS="--eNB -t ETHERNET" RUN_OPTIONS="complex" NBARGS=$[$NBARGS+256] From 49f4bdc2e528e83c69f32659289d6b83f41f75fc Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 8 Mar 2019 19:38:21 +0100 Subject: [PATCH 22/26] try to fix build failure due to increased number of build files on some build commands (=> more log files) --- ci-scripts/oai-ci-vm-tool | 16 +-- common/utils/telnetsrv/telnetsrv.c | 26 ++-- .../utils/telnetsrv/telnetsrv_ltemeasur_def.h | 127 ++++++++++++++++ common/utils/telnetsrv/telnetsrv_phycmd.c | 136 ++++++++++-------- common/utils/telnetsrv/telnetsrv_proccmd.c | 2 +- 5 files changed, 225 insertions(+), 82 deletions(-) create mode 100644 common/utils/telnetsrv/telnetsrv_ltemeasur_def.h diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index c28f51415e..9b0d0b566d 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -231,7 +231,7 @@ case $key in VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=6 BUILD_OPTIONS="--eNB -w USRP --mu" NBARGS=$[$NBARGS+256] shift @@ -272,7 +272,7 @@ case $key in VM_NAME=ci-enb-ethernet ARCHIVES_LOC=enb_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] shift @@ -281,7 +281,7 @@ case $key in VM_NAME=ci-ue-ethernet ARCHIVES_LOC=ue_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--UE -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] shift @@ -292,7 +292,7 @@ case $key in VM_CPU=8 ARCHIVES_LOC=l2_sim LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -t ETHERNET" RUN_OPTIONS="complex" NBARGS=$[$NBARGS+256] @@ -314,7 +314,7 @@ case $key in VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=6 BUILD_OPTIONS="--eNB -w USRP --mu" NBARGS=$[$NBARGS+256] ;; @@ -351,7 +351,7 @@ case $key in VM_NAME=ci-enb-ethernet ARCHIVES_LOC=enb_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] ;; @@ -359,7 +359,7 @@ case $key in VM_NAME=ci-ue-ethernet ARCHIVES_LOC=ue_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--UE -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] ;; @@ -369,7 +369,7 @@ case $key in VM_CPU=8 ARCHIVES_LOC=l2_sim LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=5 BUILD_OPTIONS="--eNB -t ETHERNET" RUN_OPTIONS="complex" NBARGS=$[$NBARGS+256] diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index b6803ead6b..4b6def2f6d 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -77,17 +77,17 @@ paramdef_t telnetoptions[] = { /* configuration parameters for telnet utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ - {"listenaddr", "", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, - {"listenport", "", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, - {"priority", "", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, - {"loopcount", "", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, - {"loopdelay", "", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, - {"histfile", "", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, - {"histsize", "", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, - {"phypbsize", "",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, - {"staticmod", "", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, - {"shrmod", "", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } + {"listenaddr", "\n", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, + {"listenport", "\n", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, + {"priority", "\n", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, + {"loopcount", "\n", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, + {"loopdelay", "\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, + {"histfile", "\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, + {"histsize", "\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, + {"phypbsize", "\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, + {"staticmod", "\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, + {"shrmod", "\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } }; int get_phybsize(void) { @@ -355,7 +355,7 @@ int setgetvar(int moduleindex,char getorset,char *params) { char varname[TELNET_CMD_MAXSIZE]; char *varval=NULL; memset(varname,0,sizeof(varname)); - n = sscanf(params,"%19s %ms",varname,&varval); + n = sscanf(params,"%s %ms",varname,&varval); for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) { if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) { @@ -475,7 +475,7 @@ int process_command(char *buf) { memset(cmdb,0,sizeof(cmdb)); bufbck=strdup(buf); rt=CMDSTATUS_NOTFOUND; - j = sscanf(buf,"%9s %9s %2000[^\t\n]",modulename,cmd,cmdb); + j = sscanf(buf,"%9s %9s %[^\t\n]",modulename,cmd,cmdb); if (telnetparams.telnetdbg > 0) printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); diff --git a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h new file mode 100644 index 0000000000..2f479d8ee6 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h @@ -0,0 +1,127 @@ +/* + * 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_ltemeasur_def.h + * \brief: definitions of macro used to initialize the telnet_ltemeasurdef_t + * \ strucures arrays which are then used by the display functions + * \ in telnetsrv_measurements.c. + * \author Francois TABURET + * \date 2019 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + +#define LTEMAC_MEASURE \ +{ \ + {"total_num_bcch_pdu", &(macstatptr->total_num_bcch_pdu),TELNET_VARTYPE_INT32,0},\ + {"bcch_buffer", &(macstatptr->bcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"total_bcch_buffer", &(macstatptr->total_bcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"bcch_mcs", &(macstatptr->bcch_mcs),TELNET_VARTYPE_INT32,0},\ + {"total_num_ccch_pdu", &(macstatptr->total_num_ccch_pdu),TELNET_VARTYPE_INT32,0},\ + {"ccch_buffer", &(macstatptr->ccch_buffer),TELNET_VARTYPE_INT32,0},\ + {"total_ccch_buffer", &(macstatptr->total_ccch_buffer),TELNET_VARTYPE_INT32,0},\ + {"ccch_mcs", &(macstatptr->ccch_mcs),TELNET_VARTYPE_INT32,0},\ + {"total_num_pcch_pdu", &(macstatptr->total_num_pcch_pdu),TELNET_VARTYPE_INT32,0},\ + {"pcch_buffer", &(macstatptr->pcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"total_pcch_buffer", &(macstatptr->total_pcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"pcch_mcs", &(macstatptr->pcch_mcs),TELNET_VARTYPE_INT32,0},\ + {"num_dlactive_UEs", &(macstatptr->num_dlactive_UEs),TELNET_VARTYPE_INT16,0},\ + {"available_prbs", &(macstatptr->available_prbs),TELNET_VARTYPE_INT16,0},\ + {"total_available_prbs", &(macstatptr->total_available_prbs),TELNET_VARTYPE_INT32,0},\ + {"available_ncces", &(macstatptr->available_ncces),TELNET_VARTYPE_INT16,0},\ + {"dlsch_bitrate", &(macstatptr->dlsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"dlsch_bytes_tx", &(macstatptr->dlsch_bytes_tx),TELNET_VARTYPE_INT32,0},\ + {"dlsch_pdus_tx", &(macstatptr->dlsch_pdus_tx),TELNET_VARTYPE_INT32,0},\ + {"total_dlsch_bitrate", &(macstatptr->total_dlsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"total_dlsch_bytes_tx", &(macstatptr->total_dlsch_bytes_tx),TELNET_VARTYPE_INT32,0},\ + {"total_dlsch_pdus_tx", &(macstatptr->total_dlsch_pdus_tx),TELNET_VARTYPE_INT32,0},\ + {"ulsch_bitrate", &(macstatptr->ulsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"ulsch_bytes_rx", &(macstatptr->ulsch_bytes_rx),TELNET_VARTYPE_INT32,0},\ + {"ulsch_pdus_rx", &(macstatptr->ulsch_pdus_rx),TELNET_VARTYPE_INT32,0},\ + {"total_ulsch_bitrate", &(macstatptr->total_ulsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"total_ulsch_bytes_rx", &(macstatptr->total_ulsch_bytes_rx),TELNET_VARTYPE_INT32,0},\ + {"total_ulsch_pdus_rx", &(macstatptr->total_ulsch_pdus_rx),TELNET_VARTYPE_INT32,0},\ + {"sched_decisions", &(macstatptr->sched_decisions),TELNET_VARTYPE_INT32,0},\ + {"missed_deadlines", &(macstatptr->missed_deadlines),TELNET_VARTYPE_INT32,0},\ +} + +#define LTEMAC_UEMEASURE \ +{ \ + {"dlsch_mcs1", &(macuestatptr->dlsch_mcs1),TELNET_VARTYPE_INT8,0},\ + {"dlsch_mcs2", &(macuestatptr->dlsch_mcs2),TELNET_VARTYPE_INT8,0},\ + {"rbs_used", &(macuestatptr->rbs_used),TELNET_VARTYPE_INT32,0},\ + {"rbs_used_retx", &(macuestatptr->rbs_used_retx),TELNET_VARTYPE_INT16,0},\ + {"total_rbs_used", &(macuestatptr->total_rbs_used),TELNET_VARTYPE_INT16,0},\ + {"ncce_used", &(macuestatptr->ncce_used),TELNET_VARTYPE_INT16,0},\ + {"ncce_used_retx", &(macuestatptr->ncce_used_retx),TELNET_VARTYPE_INT16,0},\ + {"TBS", &(macuestatptr->TBS),TELNET_VARTYPE_INT32,0},\ + {"total_pdu_bytes", &(macuestatptr->total_pdu_bytes),TELNET_VARTYPE_INT64,0},\ + {"total_num_pdus", &(macuestatptr->total_num_pdus),TELNET_VARTYPE_INT32,0},\ + {"overhead_bytes", &(macuestatptr->overhead_bytes),TELNET_VARTYPE_INT64,0},\ + {"crnti", &(macuestatptr->crnti),TELNET_VARTYPE_INT16,0},\ + {"normalized_rx_power", &(macuestatptr->normalized_rx_power),TELNET_VARTYPE_INT32,0},\ + {"target_rx_power", &(macuestatptr->target_rx_power),TELNET_VARTYPE_INT32,0},\ + {"ulsch_mcs1", &(macuestatptr->ulsch_mcs1),TELNET_VARTYPE_INT8,0},\ + {"ulsch_mcs2", &(macuestatptr->ulsch_mcs2),TELNET_VARTYPE_INT8,0},\ + {"rbs_used_rx", &(macuestatptr->rbs_used_rx),TELNET_VARTYPE_INT32,0},\ + {"rbs_used_retx_rx", &(macuestatptr->rbs_used_retx_rx),TELNET_VARTYPE_INT32,0},\ + {"total_rbs_used_rx", &(macuestatptr->total_rbs_used_rx),TELNET_VARTYPE_INT32,0},\ + {"ulsch_TBS", &(macuestatptr->ulsch_TBS),TELNET_VARTYPE_INT32,0},\ + {"total_pdu_bytes_rx", &(macuestatptr->total_pdu_bytes_rx),TELNET_VARTYPE_INT64,0},\ + {"total_num_pdus_rx", &(macuestatptr->total_num_pdus_rx),TELNET_VARTYPE_INT32,0},\ + {"num_errors_rx", &(macuestatptr->num_errors_rx),TELNET_VARTYPE_INT32,0},\ +} + +#define LTE_RLCMEASURE \ +{ \ + {"rlc_mode", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_sdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_sdu_discarded", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_bytes_discarded", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_data_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_data_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_pdu_by_status", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_bytes_by_status", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_control_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_control_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_pdcp_sdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_pdcp_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdus_duplicate", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes_duplicate", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdu_dropped", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes_dropped", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdu_out_of_window", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes_out_of_window", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_control_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_control_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"timer_reorder_tout", NULL, TELNET_VARTYPE_UINT, 0},\ + {"timer_poll_retrans_tout", NULL, TELNET_VARTYPE_UINT, 0},\ + {"timer_status_prohibit_tout", NULL, TELNET_VARTYPE_UINT, 0},\ +} diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c index 35554a77a6..c60126f1c7 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.c +++ b/common/utils/telnetsrv/telnetsrv_phycmd.c @@ -29,7 +29,7 @@ * \note * \warning */ -#define _GNU_SOURCE +#define _GNU_SOURCE #include #include @@ -39,88 +39,104 @@ #define TELNETSRV_PHYCMD_MAIN #include "telnetsrv_phycmd.h" char *prnbuff; -extern int dump_eNB_l2_stats(char *buffer, int length); +extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length); -void init_phytelnet(void) { - prnbuff=malloc(get_phybsize() ); - - if (prnbuff == NULL) { - fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno)); - } +void init_phytelnet(void) +{ +prnbuff=malloc(get_phybsize() ); +if (prnbuff == NULL) + { + fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno)); + } } -void display_uestatshead( telnet_printfunc_t prnt) { - prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n"); +void display_uestatshead( telnet_printfunc_t prnt) +{ +prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n"); } -void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag) { - int p; - prnbuff=malloc(20480); - p=dump_eNB_l2_stats( prnbuff, 20480); +void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag) +{ - if(prntflag>=1) - prnt("%s\n",prnbuff); +int p; + + p=dump_eNB_l2_stats( prnbuff, 0); + if(prntflag>=1) + prnt("%s\n",prnbuff); + if(debug>=1) + prnt("%i bytes printed\n",p); - if(debug>=1) - prnt("%i bytes printed\n",p); - free(prnbuff); } -void display_uestats(int debug, telnet_printfunc_t prnt, int ue) { - for (int cc=0; cc<1 ; cc++) { - } +void display_uestats(int debug, telnet_printfunc_t prnt, int ue) +{ + for (int cc=0; cc<1 ; cc++) + { + + + } } -void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt) { - prnt(" DLSCH kb DLSCH kb/s\n"); - dump_uestats(debug, prnt,0); +void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt) +{ + prnt(" DLSCH kb DLSCH kb/s\n"); + + dump_uestats(debug, prnt,0); + } -int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) { - if (debug > 0) - prnt("phy interface module received %s\n",buf); +int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) +{ + + - if (strcasestr(buf,"phycnt") != NULL) { - display_phycounters(buf, debug, prnt); - } - - if (strcasestr(buf,"uestat") != NULL) { - char *cptr=strcasestr(buf+sizeof("uestat"),"UE"); - display_uestatshead(prnt); - - if (cptr != NULL) { - int ueidx = strtol( cptr+sizeof("UE"), NULL, 10); - - if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0) { - display_uestats(debug, prnt,ueidx); - } - } /* if cptr != NULL */ - else { - for (int ue=0; ue 0) + prnt("phy interface module received %s\n",buf); + if (strcasestr(buf,"phycnt") != NULL) + { + display_phycounters(buf, debug, prnt); + } + if (strcasestr(buf,"uestat") != NULL) + { + char *cptr=strcasestr(buf+sizeof("uestat"),"UE"); + display_uestatshead(prnt); + if (cptr != NULL) + { + int ueidx = strtol( cptr+sizeof("UE"), NULL, 10); + if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0) + { + display_uestats(debug, prnt,ueidx); + } + } /* if cptr != NULL */ + else + { + for (int ue=0; ue]", dump_phyvars}, + {"disp","[phycnt,uedump,uestat UE]", dump_phyvars}, - {"","",NULL}, + {"","",NULL}, }; /*-------------------------------------------------------------------------------------*/ -void add_phy_cmds(void) { - init_phytelnet(); - add_telnetcmd("phy", phy_vardef, phy_cmdarray); +void add_phy_cmds(void) +{ + + init_phytelnet(); + add_telnetcmd("phy", phy_vardef, phy_cmdarray); } diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 3b423bd465..9dd512091d 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -183,7 +183,7 @@ struct dirent *entry; { if(entry->d_name[0] == '.') continue; - snprintf(aname, sizeof(aname), "/proc/%d/task/%s/stat", getpid(),entry->d_name); + snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name); read_statfile(aname,debug,prnt); } /* while entry != NULL */ closedir(proc_dir); From 753c2f446d84f4ba2a51af27703a65c72c5e84af Mon Sep 17 00:00:00 2001 From: frtabu Date: Sun, 10 Mar 2019 00:04:12 +0100 Subject: [PATCH 23/26] apply astyle, fix compilation warnings in raw aeth transport and kernel modules --- openair1/PHY/INIT/lte_param_init.c | 66 +- openair1/PHY/LTE_TRANSPORT/dci.c | 236 +- openair1/PHY/LTE_TRANSPORT/pss.c | 47 +- .../SIMULATION/ETH_TRANSPORT/netlink_init.c | 1 - openair1/SIMULATION/LTE_PHY/dlsim.c | 16 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 2 - openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 277 +-- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 21 +- openair2/LAYER2/RLC/rlc.c | 2 - openair2/NETWORK_DRIVER/MESH/constant.h | 3 +- openair2/NETWORK_DRIVER/MESH/ioctl.h | 3 +- openair2/RRC/LTE/rrc_UE.c | 54 +- openair2/RRC/LTE/rrc_eNB.c | 2 + openair2/RRC/NAS/nas_config.c | 139 +- openair2/RRC/NAS/nas_config.h | 19 +- targets/ARCH/COMMON/common_lib.c | 148 +- targets/ARCH/COMMON/common_lib.h | 106 +- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c | 38 +- targets/RT/USER/lte-ru.c | 11 +- targets/RT/USER/lte-softmodem-common.c | 4 +- targets/RT/USER/lte-softmodem.c | 4 +- targets/RT/USER/lte-ue.c | 2127 ++++++++--------- targets/RT/USER/lte-uesoftmodem.c | 4 +- 23 files changed, 1602 insertions(+), 1728 deletions(-) diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index dc8ac26d0d..1be5f6d520 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -37,27 +37,25 @@ extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; extern RU_t *ru; -extern void phy_init_RU(RU_t*); +extern void phy_init_RU(RU_t *); void lte_param_init(PHY_VARS_eNB **eNBp, - PHY_VARS_UE **UEp, - RU_t **rup, - unsigned char N_tx_port_eNB, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, - unsigned char N_rx_ru, + unsigned char N_rx_ru, unsigned char N_rx_ue, - unsigned char transmission_mode, - uint8_t extended_prefix_flag, - frame_t frame_type, - uint16_t Nid_cell, - uint8_t tdd_config, - uint8_t N_RB_DL, - uint8_t pa, - uint8_t threequarter_fs, + unsigned char transmission_mode, + uint8_t extended_prefix_flag, + frame_t frame_type, + uint16_t Nid_cell, + uint8_t tdd_config, + uint8_t N_RB_DL, + uint8_t pa, + uint8_t threequarter_fs, uint8_t osf, - uint32_t perfect_ce) -{ - + uint32_t perfect_ce) { LTE_DL_FRAME_PARMS *frame_parms; int i; PHY_VARS_eNB *eNB; @@ -71,23 +69,16 @@ void lte_param_init(PHY_VARS_eNB **eNBp, UE = *UEp; ru = *rup; printf("eNB %p, UE %p, ru %p\n",eNB,UE,ru); - - - - memset((void*)eNB,0,sizeof(PHY_VARS_eNB)); - memset((void*)UE,0,sizeof(PHY_VARS_UE)); - memset((void*)ru,0,sizeof(RU_t)); - + memset((void *)eNB,0,sizeof(PHY_VARS_eNB)); + memset((void *)UE,0,sizeof(PHY_VARS_UE)); + memset((void *)ru,0,sizeof(RU_t)); ru->eNB_list[0] = eNB; eNB->RU_list[0] = ru; ru->num_eNB=1; - srand(0); randominit(0); set_taus_seed(0); - frame_parms = &(eNB->frame_parms); - frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz frame_parms->N_RB_UL = N_RB_DL; frame_parms->threequarter_fs = threequarter_fs; @@ -106,13 +97,9 @@ void lte_param_init(PHY_VARS_eNB **eNBp, // frame_parms->Bsrs = 0; // frame_parms->kTC = 0;44 // frame_parms->n_RRC = 0; - init_frame_parms(frame_parms,osf); - //copy_lte_parms_to_phy_framing(frame_parms, &(PHY_config->PHY_framing)); - // phy_init_top(frame_parms); //allocation - UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; UE->frame_parms.nb_antennas_rx=N_rx_ue; @@ -121,14 +108,10 @@ void lte_param_init(PHY_VARS_eNB **eNBp, ru->nb_tx = N_tx_phy; ru->nb_rx = N_rx_ru; ru->if_south = LOCAL_RF; - eNB->configured=1; - eNB->transmission_mode[0] = transmission_mode; UE->transmission_mode[0] = transmission_mode; - dump_frame_parms(frame_parms); - UE->measurements.n_adj_cells=0; UE->measurements.adj_cell_id[0] = Nid_cell+1; UE->measurements.adj_cell_id[1] = Nid_cell+2; @@ -144,7 +127,6 @@ void lte_param_init(PHY_VARS_eNB **eNBp, phy_init_RU(ru); generate_pcfich_reg_mapping(&UE->frame_parms); generate_phich_reg_mapping(&UE->frame_parms); - // DL power control init //if (transmission_mode == 1) { UE->pdsch_config_dedicated->p_a = pa; @@ -166,17 +148,13 @@ void lte_param_init(PHY_VARS_eNB **eNBp, if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624; else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4; - } - else ru->N_TA_offset=0; + } else ru->N_TA_offset=0; - if (IS_SOFTMODEM_BASICSIM) - /* this is required for the basic simulator in TDD mode - * TODO: find a proper cleaner solution - */ + if (IS_SOFTMODEM_BASICSIM) + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ UE->N_TA_offset = 0; - printf("Done lte_param_init\n"); - - } diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index d4e870fb0c..edd063a090 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -64,35 +64,26 @@ void dci_encoding(uint8_t *a, uint8_t A, uint16_t E, uint8_t *e, - uint16_t rnti) -{ - - + uint16_t rnti) { uint8_t D = (A + 16); uint32_t RCC; uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96]; uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)]; - #ifdef DEBUG_DCI_ENCODING int32_t i; #endif // encode dci - #ifdef DEBUG_DCI_ENCODING printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E); #endif - memset((void *)d,LTE_NULL,96); - ccodelte_encode(A,2,a,d+96,rnti); - #ifdef DEBUG_DCI_ENCODING for (i=0; i<16+A; i++) printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i))); #endif - #ifdef DEBUG_DCI_ENCODING printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e); #endif @@ -100,27 +91,24 @@ void dci_encoding(uint8_t *a, //#ifdef DEBUG_DCI_ENCODING if (E>1000) printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e); + //#endif lte_rate_matching_cc(RCC,E,w,e); - - - } uint8_t *generate_dci0(uint8_t *dci, uint8_t *e, uint8_t DCI_LENGTH, - uint16_t coded_bits, - uint16_t rnti) -{ - + uint16_t coded_bits, + uint16_t rnti) { uint8_t dci_flip[8]; +#ifdef DEBUG_DCI_ENCODING - #ifdef DEBUG_DCI_ENCODING - for (int i=0;i<1+((DCI_LENGTH+16)/8);i++) + for (int i=0; i<1+((DCI_LENGTH+16)/8); i++) printf("i %d : %x\n",i,dci[i]); - #endif + +#endif if (DCI_LENGTH<=32) { dci_flip[0] = dci[3]; @@ -129,8 +117,7 @@ uint8_t *generate_dci0(uint8_t *dci, dci_flip[3] = dci[0]; #ifdef DEBUG_DCI_ENCODING printf("DCI => %x,%x,%x,%x\n", - dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); - + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); #endif } else { dci_flip[0] = dci[7]; @@ -143,13 +130,12 @@ uint8_t *generate_dci0(uint8_t *dci, dci_flip[7] = dci[0]; #ifdef DEBUG_DCI_ENCODING printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", - dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3], - dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]); + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3], + dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]); #endif } dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti); - return(e+coded_bits); } @@ -160,9 +146,7 @@ uint8_t *generate_dci0(uint8_t *dci, -void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) -{ - +void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) { int32_t *wptr,*wptr2,*zptr; uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi); uint32_t RCC = (Mquad>>5), ND; @@ -180,7 +164,6 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w Kpi = (RCC<<5); ND = Kpi - Mquad; - k=0; for (col=0; col<32; col++) { @@ -191,12 +174,9 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w if (index>=ND) { for (a=0; anb_antenna_ports_eNB; a++) { //printf("a %d k %d\n",a,k); - wptr = &wtemp[a][k<<2]; zptr = &z[a][(index-ND)<<2]; - //printf("wptr=%p, zptr=%p\n",wptr,zptr); - wptr[0] = zptr[0]; wptr[1] = zptr[1]; wptr[2] = zptr[2]; @@ -212,9 +192,7 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w // permutation for (i=0; inb_antenna_ports_eNB; a++) { - //wptr = &wtemp[a][i<<2]; //wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2]; wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2]; @@ -230,17 +208,13 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, uint8_t *e, - uint32_t length) -{ + uint32_t length) { int i; uint8_t reset; uint32_t x1, x2, s=0; - //LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length); - reset = 1; // x1 is set in lte_gold_generic - x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; inushift%3; - int Msymb2; int split_flag=0; switch (frame_parms->N_RB_DL) { - case 100: - Msymb2 = Msymb; - break; + case 100: + Msymb2 = Msymb; + break; - case 75: - Msymb2 = 3*Msymb/4; - break; + case 75: + Msymb2 = 3*Msymb/4; + break; - case 50: - Msymb2 = Msymb>>1; - break; + case 50: + Msymb2 = Msymb>>1; + break; - case 25: - Msymb2 = Msymb>>2; - break; + case 25: + Msymb2 = Msymb>>2; + break; - case 15: - Msymb2 = Msymb*15/100; - break; + case 15: + Msymb2 = Msymb*15/100; + break; - case 6: - Msymb2 = Msymb*6/100; - break; + case 6: + Msymb2 = Msymb*6/100; + break; - default: - Msymb2 = Msymb>>2; - break; + default: + Msymb2 = Msymb>>2; + break; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,1); generate_pcfich(num_pdcch_symbols, amp, @@ -328,41 +295,37 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, y[0] = &yseq0[0]; y[1] = &yseq1[0]; - if (IS_SOFTMODEM_BASICSIM){ - /* this should be the normal case - * but it has to be validated for all the various cases - * so let's just do it for the basic simulator - */ -// memset(e, 2, DCI_BITS_MAX); + if (IS_SOFTMODEM_BASICSIM) { + /* this should be the normal case + * but it has to be validated for all the various cases + * so let's just do it for the basic simulator + */ + // memset(e, 2, DCI_BITS_MAX); } else { - // reset all bits to , here we set elements as 2 - // memset(e, 2, DCI_BITS_MAX); - // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. + // reset all bits to , here we set elements as 2 + // memset(e, 2, DCI_BITS_MAX); + // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. for (i=0; i=1; L>>=1) { for (i=0; i=0) { e_ptr = generate_dci0(dci_alloc[i].dci_pdu, @@ -374,14 +337,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, } } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0); // Scrambling #ifdef DEBUG_DCI_ENCODING printf("pdcch scrambling\n"); #endif //LOG_D(PHY, "num_pdcch_symbols:%d mi:%d nquad:%d\n", num_pdcch_symbols, mi, get_nquad(num_pdcch_symbols, frame_parms, mi)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,1); pdcch_scrambling(frame_parms, subframe, @@ -389,11 +351,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, 8*get_nquad(num_pdcch_symbols, frame_parms, mi)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,0); //72*get_nCCE(num_pdcch_symbols,frame_parms,mi)); - - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,1); + // Now do modulation if (frame_parms->nb_antenna_ports_eNB==1) gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); @@ -401,7 +360,6 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, gain_lin_QPSK = amp/2; e_ptr = e; - #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK); #endif @@ -409,91 +367,73 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, //LOG_D(PHY,"%s() Msymb2:%d\n", __FUNCTION__, Msymb2); if (frame_parms->nb_antenna_ports_eNB==1) { //SISO - - for (i=0; i>2); #endif // first antenna position n -> x0 - ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; - ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; - // second antenna position n -> -x1* - ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK; + ((int16_t *)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK; e_ptr++; - ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; - // fill in the rest of the ALAMOUTI precoding - ((int16_t*)&y[0][i+1])[0] = -((int16_t*)&y[1][i])[0]; - ((int16_t*)&y[0][i+1])[1] = ((int16_t*)&y[1][i])[1]; - ((int16_t*)&y[1][i+1])[0] = ((int16_t*)&y[0][i])[0]; - ((int16_t*)&y[1][i+1])[1] = -((int16_t*)&y[0][i])[1]; - + ((int16_t *)&y[0][i+1])[0] = -((int16_t *)&y[1][i])[0]; + ((int16_t *)&y[0][i+1])[1] = ((int16_t *)&y[1][i])[1]; + ((int16_t *)&y[1][i+1])[0] = ((int16_t *)&y[0][i])[0]; + ((int16_t *)&y[1][i+1])[1] = -((int16_t *)&y[0][i])[1]; } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,0); - - #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Interleaving\n"); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,1); // printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]); // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5 pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,1); mprime=0; nsymb = (frame_parms->Ncp==0) ? 14:12; re_offset = frame_parms->first_carrier_offset; - // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 // printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]); #ifdef DEBUG_DCI_ENCODING printf("kprime loop - N_RB_DL:%d lprime:num_pdcch_symbols:%d Ncp:%d pcfich:%02x,%02x,%02x,%02x ofdm_symbol_size:%d first_carrier_offset:%d nb_antenna_ports_eNB:%d\n", - frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp, - frame_parms->pcfich_reg[0], - frame_parms->pcfich_reg[1], - frame_parms->pcfich_reg[2], - frame_parms->pcfich_reg[3], - frame_parms->ofdm_symbol_size, - frame_parms->first_carrier_offset, - frame_parms->nb_antenna_ports_eNB - ); + frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp, + frame_parms->pcfich_reg[0], + frame_parms->pcfich_reg[1], + frame_parms->pcfich_reg[2], + frame_parms->pcfich_reg[3], + frame_parms->ofdm_symbol_size, + frame_parms->first_carrier_offset, + frame_parms->nb_antenna_ports_eNB + ); #endif + for (kprime=0; kprimeN_RB_DL*12; kprime++) { for (lprime=0; lprimeofdm_symbol_size*(lprime+(subframe*nsymb)); - - - tti_offset = symbol_offset + re_offset; - (re_offset==(frame_parms->ofdm_symbol_size-2)) ? (split_flag=1) : (split_flag=0); // printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset); @@ -504,16 +444,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, #endif } else { // Copy REG to TX buffer - if ((lprime == 0)|| ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) { // first symbol, or second symbol+4 TX antennas skip pilots - kprime_mod12 = kprime%12; if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) { // kprime represents REG - for (i=0; i<6; i++) { if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) { txdataF[0][tti_offset+i] = wbar[0][mprime]; @@ -522,9 +459,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+i] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif - mprime++; } } @@ -542,7 +478,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+i] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif mprime++; } @@ -553,7 +489,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+0] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset+1] = wbar[0][mprime]; @@ -562,7 +498,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+1] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime]; @@ -571,8 +507,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime], - *(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short *)&wbar[0][mprime], + *(1+(short *)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime]; @@ -581,11 +517,10 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime], - *(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short *)&wbar[0][mprime], + *(1+(short *)&wbar[0][mprime])); #endif mprime++; - } } } @@ -593,7 +528,6 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (mprime>=Msymb2) return(num_pdcch_symbols); } // check_phich_reg - } //lprime loop re_offset++; @@ -601,8 +535,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (re_offset == (frame_parms->ofdm_symbol_size)) re_offset = 1; } // kprime loop - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0); return(num_pdcch_symbols); } diff --git a/openair1/PHY/LTE_TRANSPORT/pss.c b/openair1/PHY/LTE_TRANSPORT/pss.c index e83e2c4d9d..9ebd841430 100644 --- a/openair1/PHY/LTE_TRANSPORT/pss.c +++ b/openair1/PHY/LTE_TRANSPORT/pss.c @@ -44,66 +44,59 @@ int generate_pss(int32_t **txdataF, short amp, LTE_DL_FRAME_PARMS *frame_parms, unsigned short symbol, - unsigned short slot_offset) -{ - + unsigned short slot_offset) { unsigned int Nsymb; unsigned short k,m,aa,a; uint8_t Nid2; short *primary_sync; - - Nid2 = frame_parms->Nid_cell % 3; switch (Nid2) { - case 0: - primary_sync = primary_synch0; - break; + case 0: + primary_sync = primary_synch0; + break; - case 1: - primary_sync = primary_synch1; - break; + case 1: + primary_sync = primary_synch1; + break; - case 2: - primary_sync = primary_synch2; - break; + case 2: + primary_sync = primary_synch2; + break; - default: - LOG_E(PHY,"[PSS] eNb_id has to be 0,1,2\n"); - return(-1); + default: + LOG_E(PHY,"[PSS] eNb_id has to be 0,1,2\n"); + return(-1); } a = (frame_parms->nb_antenna_ports_eNB == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15; //printf("[PSS] amp=%d, a=%d\n",amp,a); if (IS_SOFTMODEM_BASICSIM) - /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */ + /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */ a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15; Nsymb = (frame_parms->Ncp==NORMAL)?14:12; for (aa=0; aanb_antenna_ports_eNB; aa++) { // aa = 0; - // The PSS occupies the inner 6 RBs, which start at k = frame_parms->ofdm_symbol_size-3*12+5; //printf("[PSS] k = %d\n",k); for (m=5; m<67; m++) { - ((short*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + - symbol*frame_parms->ofdm_symbol_size + k)] = - (a * primary_sync[2*m]) >> 15; - ((short*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + - symbol*frame_parms->ofdm_symbol_size + k) + 1] = - (a * primary_sync[2*m+1]) >> 15; - + ((short *)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + + symbol*frame_parms->ofdm_symbol_size + k)] = + (a * primary_sync[2*m]) >> 15; + ((short *)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + + symbol*frame_parms->ofdm_symbol_size + k) + 1] = + (a * primary_sync[2*m+1]) >> 15; k+=1; if (k >= frame_parms->ofdm_symbol_size) { k++; //skip DC k-=frame_parms->ofdm_symbol_size; } - } } diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index cdda4dfe78..5a5f9852b1 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -63,7 +63,6 @@ struct msghdr nas_msg_rx; #define GRAAL_NETLINK_ID 31 - static int tun_alloc(char *dev) { struct ifreq ifr; int fd, err; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 4af273b8b0..c7916b8dfc 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -782,13 +782,15 @@ int main(int argc, char **argv) { break; case 'u': - dual_stream_UE=1; - if (UE != NULL) - UE->use_ia_receiver = 1; + dual_stream_UE=1; + + if (UE != NULL) + UE->use_ia_receiver = 1; else { printf("UE is NULL\n"); - exit(-1); - } + exit(-1); + } + if ((n_tx_port!=2) || (transmission_mode!=5)) { printf("IA receiver only supported for TM5!"); exit(-1); @@ -951,8 +953,8 @@ int main(int argc, char **argv) { fl_set_object_label(form_ue->button_0, "IA Receiver ON"); fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); } else { - printf("UE is NULL\n"); - exit(-1); + printf("UE is NULL\n"); + exit(-1); } } } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 221cc708f3..3e9623dc2f 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -1211,9 +1211,7 @@ int main(int argc, char **argv) { } dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); - round=5; - } if (n_frames==1) printf("round %d errors %u/%u\n",round,errs[round],trials); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 3801df9a39..99736939c4 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -440,7 +440,6 @@ pdcp_data_ind( uint32_t rx_hfn_for_count; int pdcp_sn_for_count; int security_ok; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN); LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP, "[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); @@ -567,6 +566,7 @@ pdcp_data_ind( } #if 0 + /* Removed by Cedric */ if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) { LOG_T(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number); @@ -588,6 +588,7 @@ pdcp_data_ind( free_mem_block(sdu_buffer_pP, __func__); return FALSE; } + #endif // SRB1/2: control-plane data @@ -678,158 +679,156 @@ pdcp_data_ind( payload_offset=pdcp_header_len;// PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; switch (pdcp_p->rlc_mode) { - case RLC_MODE_AM: { - /* process as described in 36.323 5.1.2.1.2 */ - int reordering_window; + case RLC_MODE_AM: { + /* process as described in 36.323 5.1.2.1.2 */ + int reordering_window; - if (pdcp_p->seq_num_size == 7) - reordering_window = REORDERING_WINDOW_SN_7BIT; - else - reordering_window = REORDERING_WINDOW_SN_12BIT; + if (pdcp_p->seq_num_size == 7) + reordering_window = REORDERING_WINDOW_SN_7BIT; + else + reordering_window = REORDERING_WINDOW_SN_12BIT; - if (sequence_number - pdcp_p->last_submitted_pdcp_rx_sn > reordering_window || - (pdcp_p->last_submitted_pdcp_rx_sn - sequence_number >= 0 && - pdcp_p->last_submitted_pdcp_rx_sn - sequence_number < reordering_window)) { - /* TODO: specs say to decipher and do header decompression */ - LOG_W(PDCP, - PROTOCOL_PDCP_CTXT_FMT"discard PDU, out of\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - LOG_W(PDCP, "Ignoring PDU...\n"); - free_mem_block(sdu_buffer_pP, __func__); - /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + if (sequence_number - pdcp_p->last_submitted_pdcp_rx_sn > reordering_window || + (pdcp_p->last_submitted_pdcp_rx_sn - sequence_number >= 0 && + pdcp_p->last_submitted_pdcp_rx_sn - sequence_number < reordering_window)) { + /* TODO: specs say to decipher and do header decompression */ + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"discard PDU, out of\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; + } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) { + pdcp_p->rx_hfn++; + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + pdcp_p->next_pdcp_rx_sn = sequence_number + 1; + } else if (sequence_number - pdcp_p->next_pdcp_rx_sn >= reordering_window) { + rx_hfn_for_count = pdcp_p->rx_hfn - 1; + pdcp_sn_for_count = sequence_number; + } else if (sequence_number >= pdcp_p->next_pdcp_rx_sn) { + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + pdcp_p->next_pdcp_rx_sn = sequence_number + 1; + + if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) { + pdcp_p->next_pdcp_rx_sn = 0; + pdcp_p->rx_hfn++; + } + } else { /* sequence_number < pdcp_p->next_pdcp_rx_sn */ + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + } + + if (pdcp_p->security_activated == 1) { + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } + + security_ok = pdcp_validate_security(ctxt_pP, + pdcp_p, + srb_flagP, + rb_idP, + pdcp_header_len, + rx_hfn_for_count, + pdcp_sn_for_count, + sdu_buffer_pP->data, + sdu_buffer_sizeP - pdcp_tailer_len) == 0; + + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } + } else { + security_ok = 1; + } + + if (security_ok == 0) { + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/AM PDU\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; + } + + /* TODO: specs say we have to store this PDU in a list and then deliver + * stored packets to upper layers according to a well defined + * procedure. The code below that deals with delivery is today + * too complex to do this properly, so we only send the current + * received packet. This is not correct and has to be fixed + * some day. + * In the meantime, let's pretend the last submitted PDCP SDU + * is the current one. + * TODO: we also have to deal with re-establishment PDU (control PDUs) + * that contain no SDU. + */ + pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; + break; + } /* case RLC_MODE_AM */ + + case RLC_MODE_UM: + + /* process as described in 36.323 5.1.2.1.3 */ + if (sequence_number < pdcp_p->next_pdcp_rx_sn) { + pdcp_p->rx_hfn++; + } - } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) { - pdcp_p->rx_hfn++; rx_hfn_for_count = pdcp_p->rx_hfn; pdcp_sn_for_count = sequence_number; pdcp_p->next_pdcp_rx_sn = sequence_number + 1; - } else if (sequence_number - pdcp_p->next_pdcp_rx_sn >= reordering_window) { - rx_hfn_for_count = pdcp_p->rx_hfn - 1; - pdcp_sn_for_count = sequence_number; - - } else if (sequence_number >= pdcp_p->next_pdcp_rx_sn) { - rx_hfn_for_count = pdcp_p->rx_hfn; - pdcp_sn_for_count = sequence_number; - pdcp_p->next_pdcp_rx_sn = sequence_number + 1; if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) { pdcp_p->next_pdcp_rx_sn = 0; pdcp_p->rx_hfn++; } - } else { /* sequence_number < pdcp_p->next_pdcp_rx_sn */ - rx_hfn_for_count = pdcp_p->rx_hfn; - pdcp_sn_for_count = sequence_number; - } + if (pdcp_p->security_activated == 1) { + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } - if (pdcp_p->security_activated == 1) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + security_ok = pdcp_validate_security(ctxt_pP, + pdcp_p, + srb_flagP, + rb_idP, + pdcp_header_len, + rx_hfn_for_count, + pdcp_sn_for_count, + sdu_buffer_pP->data, + sdu_buffer_sizeP - pdcp_tailer_len) == 0; + + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } } else { - start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + security_ok = 1; } - security_ok = pdcp_validate_security(ctxt_pP, - pdcp_p, - srb_flagP, - rb_idP, - pdcp_header_len, - rx_hfn_for_count, - pdcp_sn_for_count, - sdu_buffer_pP->data, - sdu_buffer_sizeP - pdcp_tailer_len) == 0; - - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); - } else { - stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); - } - } else { - security_ok = 1; - } - - if (security_ok == 0) { - LOG_W(PDCP, - PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/AM PDU\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - LOG_W(PDCP, "Ignoring PDU...\n"); - free_mem_block(sdu_buffer_pP, __func__); - /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; - } - - /* TODO: specs say we have to store this PDU in a list and then deliver - * stored packets to upper layers according to a well defined - * procedure. The code below that deals with delivery is today - * too complex to do this properly, so we only send the current - * received packet. This is not correct and has to be fixed - * some day. - * In the meantime, let's pretend the last submitted PDCP SDU - * is the current one. - * TODO: we also have to deal with re-establishment PDU (control PDUs) - * that contain no SDU. - */ - - pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; - - break; - } /* case RLC_MODE_AM */ - - case RLC_MODE_UM: - /* process as described in 36.323 5.1.2.1.3 */ - if (sequence_number < pdcp_p->next_pdcp_rx_sn) { - pdcp_p->rx_hfn++; - } - rx_hfn_for_count = pdcp_p->rx_hfn; - pdcp_sn_for_count = sequence_number; - pdcp_p->next_pdcp_rx_sn = sequence_number + 1; - if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) { - pdcp_p->next_pdcp_rx_sn = 0; - pdcp_p->rx_hfn++; - } - - if (pdcp_p->security_activated == 1) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); - } else { - start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + if (security_ok == 0) { + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/UM PDU\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; } - security_ok = pdcp_validate_security(ctxt_pP, - pdcp_p, - srb_flagP, - rb_idP, - pdcp_header_len, - rx_hfn_for_count, - pdcp_sn_for_count, - sdu_buffer_pP->data, - sdu_buffer_sizeP - pdcp_tailer_len) == 0; + break; - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); - } else { - stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); - } - } else { - security_ok = 1; - } - - if (security_ok == 0) { - LOG_W(PDCP, - PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/UM PDU\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - LOG_W(PDCP, "Ignoring PDU...\n"); - free_mem_block(sdu_buffer_pP, __func__); - /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; - } - - break; - - default: - LOG_E(PDCP, "bad RLC mode, cannot happen.\n"); - exit(1); + default: + LOG_E(PDCP, "bad RLC mode, cannot happen.\n"); + exit(1); } /* switch (pdcp_p->rlc_mode) */ } else { /* MBMS_flagP == 0 */ payload_offset=0; @@ -1145,10 +1144,10 @@ pdcp_run ( } while(msg_p != NULL); // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer -// if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { - if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { - pdcp_fifo_read_input_sdus(ctxt_pP); - } + // if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { + pdcp_fifo_read_input_sdus(ctxt_pP); + } // PDCP -> NAS/IP traffic: RX if (ctxt_pP->enb_flag) { @@ -2042,6 +2041,8 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { ((PDCP_USE_NETLINK)?"usenetlink":"")); if (PDCP_USE_NETLINK) { + nas_getparams(); + if(UE_NAS_USE_TUN) { netlink_init_tun("ue"); LOG_I(PDCP, "UE pdcp will use tun interface\n"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 8a44d7b1a8..4ac866cd66 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -145,7 +145,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { //----------------------------------------------------------------------------- int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { pdcp_data_req_header_t pdcp_read_header_g; - if (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) { protocol_ctxt_t ctxt = *ctxt_pP; @@ -163,22 +162,20 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { if (len<=0) continue; - if (UE_NAS_USE_TUN) { - key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); } else { - ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0]; - ctxt.enb_flag=ENB_FLAG_YES; - ctxt.module_id=0; - key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES); - h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0]; + ctxt.enb_flag=ENB_FLAG_YES; + ctxt.module_id=0; + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); } - LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - - if (h_rc == HASH_TABLE_OK) { LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", ctxt.frame, ctxt.instance, len, rab_id); diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index b07f5b99fd..38d78f18fd 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -584,14 +584,12 @@ void rlc_data_ind ( const sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { //----------------------------------------------------------------------------- - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, sdu_sizeP); rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP); - #if T_TRACER if (ctxt_pP->enb_flag) diff --git a/openair2/NETWORK_DRIVER/MESH/constant.h b/openair2/NETWORK_DRIVER/MESH/constant.h index 1c756765c6..5347c5a784 100644 --- a/openair2/NETWORK_DRIVER/MESH/constant.h +++ b/openair2/NETWORK_DRIVER/MESH/constant.h @@ -47,7 +47,8 @@ #define NAS_INET6_ADDRSTRLEN 46 #define NAS_INET_ADDRSTRLEN 16 -#define NAS_CX_MAX 128 // 32 //Identical to RRC constant +#define NAS_CX_MAX 32 //128 //Identical to RRC constant: no you cannot +/* increase to 128 without risking stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */ //#define NAS_CX_MULTICAST_ALLNODE 2 #define NAS_RETRY_LIMIT_DEFAULT 5 diff --git a/openair2/NETWORK_DRIVER/MESH/ioctl.h b/openair2/NETWORK_DRIVER/MESH/ioctl.h index ffa9b4e79b..904105b1d1 100644 --- a/openair2/NETWORK_DRIVER/MESH/ioctl.h +++ b/openair2/NETWORK_DRIVER/MESH/ioctl.h @@ -64,7 +64,8 @@ // Max number of entry of a message list #define NAS_LIST_CX_MAX 32 #define NAS_LIST_RB_MAX 32 -#define NAS_LIST_CLASS_MAX 32 +#define NAS_LIST_CLASS_MAX 16 // 32 is too high!!: +/* risk of stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */ typedef unsigned short nasMsgType_t; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index f8711da639..a00bc53759 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -801,7 +801,6 @@ rrc_ue_establish_drb( (void)ip_addr_offset4; LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n", ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity); - /* rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE); @@ -810,35 +809,34 @@ rrc_ue_establish_drb( (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, RADIO_ACCESS_BEARER,Rlc_info_um); */ -// if(!EPC_MODE_ENABLED) { -//# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) - ip_addr_offset3 = 0; - ip_addr_offset4 = 1; - LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oip%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, - ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); - oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id - ip_addr_offset3+ue_mod_idP+1, // third_octet - ip_addr_offset4+ue_mod_idP+1, // fourth_octet - "oip"); // interface suffix + // if(!EPC_MODE_ENABLED) { + //# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) + ip_addr_offset3 = 0; + ip_addr_offset4 = 1; + LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oip%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, + ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); + oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id + ip_addr_offset3+ue_mod_idP+1, // third_octet + ip_addr_offset4+ue_mod_idP+1, // fourth_octet + "oip"); // interface suffix - if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB - LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", - ue_mod_idP, - ip_addr_offset3+ue_mod_idP, - (long int)((eNB_index * LTE_maxDRB) + DRB_config->drb_Identity)); - rb_conf_ipv4(0,//add - ue_mod_idP,//cx align with the UE index - ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index - (eNB_index * LTE_maxDRB) + DRB_config->drb_Identity,//rb - 0,//dscp - ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr - ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr - LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); - } - -//# endif -// } + if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB + LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", + ue_mod_idP, + ip_addr_offset3+ue_mod_idP, + (long int)((eNB_index * LTE_maxDRB) + DRB_config->drb_Identity)); + rb_conf_ipv4(0,//add + ue_mod_idP,//cx align with the UE index + ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index + (eNB_index * LTE_maxDRB) + DRB_config->drb_Identity,//rb + 0,//dscp + ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr + ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr + LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); + } + //# endif + // } return(0); } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 77519b2015..6129a88ab2 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -6269,6 +6269,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); + if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) { LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", ctxt_pP->module_id, @@ -6278,6 +6279,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id + 1, // thrid octet ctxt_pP->module_id + 1, // fourth octet "oai"); + if (oip_ifup == 0) { // interface is up --> send a config the DRB module_id_t ue_module_id; dest_ip_offset = 8; diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index 2c432cf922..61909df5ec 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -45,47 +45,55 @@ #include "nas_config.h" #include "common/utils/LOG/log.h" #include "targets/RT/USER/lte-softmodem.h" +#include "common/config/config_userapi.h" //default values according to the examples, -char *baseNetAddress = "10.0" ; -char *netMask = "255.255.255.0" ; -char *broadcastAddr = "10.0.255.255" ; +char *baseNetAddress ; +char *netMask ; +char *broadcastAddr ; +#define NASHLP_NETPREFIX "\n" +#define NASHLP_NETMASK "\n" +#define NASHLP_BROADCASTADDR "\n" +void nas_getparams(void) { + paramdef_t nasoptions[] = { + /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /* configuration parameters for netlink, includes network parameters when running in noS1 mode */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ + /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + {"NetworkPrefix", NASHLP_NETPREFIX, 0, strptr:&baseNetAddress, defstrval:"10.0", TYPE_STRING, 0 }, + {"NetworkMask", NASHLP_NETMASK, 0, strptr:&netMask, defstrval:"255.255.255.0", TYPE_STRING, 0 }, + {"BroadcastAddr", NASHLP_BROADCASTADDR, 0, strptr:&broadcastAddr, defstrval:"10.0.255.255", TYPE_STRING, 0 }, + }; + config_get( nasoptions,sizeof(nasoptions)/sizeof(paramdef_t),"nas.noS1"); +} - -void setBaseNetAddress (char* baseAddr) -{ +void setBaseNetAddress (char *baseAddr) { strcpy(baseNetAddress,baseAddr); } -char* getBaseNetAddress (void) -{ +char *getBaseNetAddress (void) { return baseNetAddress; } -void setNetMask (char* baseAddr) -{ +void setNetMask (char *baseAddr) { strcpy(netMask,baseAddr); } -char* getNetMask (void) -{ +char *getNetMask (void) { return netMask; } -void setBroadcastAddress (char* baseAddr) -{ +void setBroadcastAddress (char *baseAddr) { strcpy(broadcastAddr, baseAddr); } -char* getBroadcastAddress (void) -{ +char *getBroadcastAddress (void) { return broadcastAddr; } //Add Gateway to the interface -int set_gateway(char *interfaceName, char *gateway) -{ +int set_gateway(char *interfaceName, char *gateway) { int sock_fd; struct rtentry rt; struct sockaddr_in addr; @@ -96,20 +104,16 @@ int set_gateway(char *interfaceName, char *gateway) } memset (&rt, 0, sizeof (rt)); - addr.sin_family = AF_INET; /*set Destination addr*/ inet_aton("0.0.0.0",&addr.sin_addr); memcpy(&rt.rt_dst, &addr, sizeof(struct sockaddr_in)); - /*set gateway addr*/ inet_aton(gateway,&addr.sin_addr); memcpy(&rt.rt_gateway, &addr, sizeof(struct sockaddr_in)); - /*set genmask addr*/ inet_aton("0.0.0.0",&addr.sin_addr); memcpy(&rt.rt_genmask, &addr, sizeof(struct sockaddr_in)); - rt.rt_dev = interfaceName; //rt.rt_flags = RTF_UP|RTF_GATEWAY|RTF_DEFAULT; /* SR: rt_flags on 16 bits but RTF_DEFAULT = 0x00010000 @@ -129,19 +133,16 @@ int set_gateway(char *interfaceName, char *gateway) LOG_I(OIP,"set_gateway OK!\n"); return 0; } - } close(sock_fd); - LOG_D(OIP,"Set Gateway OK!\n"); return 0; } // sets a genneric interface parameter // (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS) -int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) -{ +int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) { int sock_fd; struct ifreq ifr; struct sockaddr_in addr; @@ -154,10 +155,8 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)-1); - memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; - inet_aton(settingAddress,&addr.sin_addr); memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in)); @@ -169,15 +168,13 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati } close(sock_fd); - // printf("Set OK!\n"); return 0; } // sets a genneric interface parameter // (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS) -int bringInterfaceUp(char *interfaceName, int up) -{ +int bringInterfaceUp(char *interfaceName, int up) { int sock_fd; struct ifreq ifr; @@ -213,8 +210,7 @@ int bringInterfaceUp(char *interfaceName, int up) return 0; } // non blocking full configuration of the interface (address, net mask, and broadcast mask) -int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) -{ +int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) { bringInterfaceUp(interfaceName, 0); // sets the machine address int returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR); @@ -229,28 +225,21 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br // if(!returnValue) // returnValue=set_gateway(interfaceName, broadcastAddress); - bringInterfaceUp(interfaceName, 1); - return returnValue; } // non blocking full configuration of the interface (address, and the two lest octets of the address) -int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) -{ +int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { //char buf[5]; char ipAddress[20]; char broadcastAddress[20]; char interfaceName[20]; int returnValue; sprintf(ipAddress, "10.0.%d.%d", thirdOctet,fourthOctet); - sprintf(broadcastAddress, "10.0.%d.255", thirdOctet); - - sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname, UE_NAS_USE_TUN?"ue": (ENB_NAS_USE_TUN?"enb":""),interface_id); - bringInterfaceUp(interfaceName, 0); // sets the machine address returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR); @@ -264,18 +253,13 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR); bringInterfaceUp(interfaceName, 1); - return returnValue; - } // Blocking full configuration of the interface (address, net mask, and broadcast mask) -int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) -{ - +int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) { char command[200]; command[0]='\0'; - strcat(command, "ifconfig "); strncat(command, interfaceName, sizeof(command) - strlen(command) - 1); strncat(command, " ", sizeof(command) - strlen(command) - 1); @@ -284,16 +268,13 @@ int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, strncat(command, networkMask, sizeof(command) - strlen(command) - 1); strncat(command, " broadcast ", sizeof(command) - strlen(command) - 1); strncat(command, broadcastAddress, sizeof(command) - strlen(command) - 1); - // ifconfig nasmesh0 10.0.1.1 networkMask 255.255.255.0 broadcast 10.0.1.255 int i = system (command); - return i; } // program help -void helpOptions(char **argv) -{ +void helpOptions(char **argv) { printf("Help for %s\n", argv[0]); printf(" -i \n"); printf(" -a \n"); @@ -305,13 +286,11 @@ void helpOptions(char **argv) printf(" IP Address: 10.0.1.1\n"); printf(" Net mask: 255.255.255.0\n"); printf(" Broadcast address: [Beginning of the IP address].255\n"); - exit(1); } // creates the broadcast address if it wasn't set before -void createBroadcast(char *broadcastAddress) -{ +void createBroadcast(char *broadcastAddress) { int pos=strlen(broadcastAddress)-1; while(broadcastAddress[pos]!='.') @@ -333,7 +312,6 @@ int main(int argc,char **argv) char ipAddress[100]; char networkMask[100]; char broadcastAddress[100]; - strcpy(interfaceName, "oai0"); strcpy(ipAddress, "10.0.1.1"); strcpy(networkMask, "255.255.255.0"); @@ -341,38 +319,38 @@ int main(int argc,char **argv) while ((c = getopt (argc, argv, "i:a:n:b:h")) != -1) switch (c) { - case 'h': - helpOptions(argv); - break; + case 'h': + helpOptions(argv); + break; - case 'i': - strcpy(interfaceName,optarg); - break; + case 'i': + strcpy(interfaceName,optarg); + break; - case 'a': - strcpy(ipAddress,optarg); - break; + case 'a': + strcpy(ipAddress,optarg); + break; - case 'n': - strcpy(networkMask,optarg); - break; + case 'n': + strcpy(networkMask,optarg); + break; - case 'b': - strcpy(broadcastAddress,optarg); - break; + case 'b': + strcpy(broadcastAddress,optarg); + break; - case '?': - if (isprint (optopt)) - fprintf (stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf (stderr, - "Unknown option character `\\x%x'.\n", - optopt); + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); - return 1; + return 1; - default: - abort (); + default: + abort (); } if(strlen(broadcastAddress)==0) { @@ -385,7 +363,6 @@ int main(int argc,char **argv) //test // setBaseNetAddress("11.11"); // nas_config(interfaceName, 33, 44); - } #endif diff --git a/openair2/RRC/NAS/nas_config.h b/openair2/RRC/NAS/nas_config.h index c6c60baf0b..fdc3c98f1b 100644 --- a/openair2/RRC/NAS/nas_config.h +++ b/openair2/RRC/NAS/nas_config.h @@ -31,6 +31,13 @@ #include +/*! \fn void void nas_getparams(void)(void) + * \brief This function get parameters used to configure network interface when running in noS1 mode + * \note + * @ingroup ????? + */ +void nas_getparams(void); + /*! \fn int NAS_config(char*, char*, char*, char*) * \brief This function initializes the nasmesh interface * \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1 @@ -98,7 +105,7 @@ int set_gateway(char *interfaceName, char *gateway); * \note * @ingroup ????? */ -void setBaseNetAddress(char* baseAddr); +void setBaseNetAddress(char *baseAddr); /*! \fn char* getBaseNetAddress() * \brief This function returns the basic network address used @@ -106,7 +113,7 @@ void setBaseNetAddress(char* baseAddr); * \note * @ingroup ????? */ -char* getBaseNetAddress(void); +char *getBaseNetAddress(void); /*! \fn void setNetMask(char*) * \brief This function sets the new default network mask used @@ -114,7 +121,7 @@ char* getBaseNetAddress(void); * \note * @ingroup ????? */ -void setNetMask(char* baseAddr); +void setNetMask(char *baseAddr); /*! \fn char* getNetMask() * \brief This function returns the network mask address in use @@ -122,7 +129,7 @@ void setNetMask(char* baseAddr); * \note * @ingroup ????? */ -char* getNetMask(void); +char *getNetMask(void); /*! \fn coid setBroadcastAddress(char*) * \brief This function sets the new broadcast address used @@ -130,7 +137,7 @@ char* getNetMask(void); * \note * @ingroup ????? */ -void setBroadcastAddress(char* baseAddr); +void setBroadcastAddress(char *baseAddr); /*! \fn char* getBroadcastAddress() * \brief This function returns the broadcast address in use @@ -138,7 +145,7 @@ void setBroadcastAddress(char* baseAddr); * \note * @ingroup ????? */ -char* getBroadcastAddress(void); +char *getBroadcastAddress(void); int bringInterfaceUp(char *interfaceName, int up); diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 06b08dfc40..3f81816aa1 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file common_lib.c - * \brief common APIs for different RF frontend device +/*! \file common_lib.c + * \brief common APIs for different RF frontend device * \author HongliangXU, Navid Nikaein * \date 2015 * \version 0.2 @@ -40,113 +40,121 @@ #include "targets/RT/USER/lte-softmodem.h" int set_device(openair0_device *device) { - switch (device->type) { - - case EXMIMO_DEV: - printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case USRP_B200_DEV: - printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case USRP_X300_DEV: - printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case BLADERF_DEV: - printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case LMSSDR_DEV: - printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case IRIS_DEV: - printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case NONE_DEV: - printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - default: - printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return -1; + case EXMIMO_DEV: + printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case USRP_B200_DEV: + printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case USRP_X300_DEV: + printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case BLADERF_DEV: + printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case LMSSDR_DEV: + printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case IRIS_DEV: + printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case NONE_DEV: + printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + default: + printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return -1; } + return 0; } int set_transport(openair0_device *device) { - switch (device->transp_type) { - - case ETHERNET_TP: - printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return 0; - break; - case NONE_TP: - printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return 0; - break; - default: - printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return -1; - break; + case ETHERNET_TP: + printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return 0; + break; + + case NONE_TP: + printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return 0; + break; + + default: + printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return -1; + break; } - } typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); /* look for the interface library and load it */ -int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) { - +int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *cfg, uint8_t flag) { loader_shlibfunc_t shlib_fdesc[1]; int ret=0; char *libname; + if ( IS_SOFTMODEM_BASICSIM ) { - libname=OAI_BASICSIM_LIBNAME; - shlib_fdesc[0].fname="device_init"; - } else - if ( IS_SOFTMODEM_RFSIM ) { - libname=OAI_RFSIM_LIBNAME; - shlib_fdesc[0].fname="device_init"; + libname=OAI_BASICSIM_LIBNAME; + shlib_fdesc[0].fname="device_init"; + } else if ( IS_SOFTMODEM_RFSIM ) { + libname=OAI_RFSIM_LIBNAME; + shlib_fdesc[0].fname="device_init"; } else if (flag == RAU_LOCAL_RADIO_HEAD) { - libname=OAI_RF_LIBNAME; - shlib_fdesc[0].fname="device_init"; + libname=OAI_RF_LIBNAME; + shlib_fdesc[0].fname="device_init"; } else { - libname=OAI_TP_LIBNAME; - shlib_fdesc[0].fname="transport_init"; - } + libname=OAI_TP_LIBNAME; + shlib_fdesc[0].fname="transport_init"; + } + ret=load_module_shlib(libname,shlib_fdesc,1,NULL); + if (ret < 0) { - fprintf(stderr,"Library %s couldn't be loaded\n",libname); + fprintf(stderr,"Library %s couldn't be loaded\n",libname); } else { - ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); - } - return ret; + ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); + } + + return ret; } int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) { - int rc=0; rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD ); - if ( rc >= 0) { - if ( set_device(device) < 0) { + if ( rc >= 0) { + if ( set_device(device) < 0) { fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); - return -1; - } + return -1; + } } + return rc; } -int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) { +int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params) { int rc; rc=load_lib(device, openair0_cfg, eth_params, RAU_REMOTE_RADIO_HEAD); - if ( rc >= 0) { + + if ( rc >= 0) { if ( set_transport(device) < 0) { fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__); - return -1; - } + return -1; + } } - return rc; + return rc; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index de9acc3ab5..0af6fa9c5e 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file common_lib.h - * \brief common APIs for different RF frontend device +/*! \file common_lib.h + * \brief common APIs for different RF frontend device * \author HongliangXU, Navid Nikaein * \date 2015 * \version 0.2 @@ -48,13 +48,13 @@ #define RAU_REMOTE_RADIO_HEAD 1 #ifndef MAX_CARDS -#define MAX_CARDS 8 + #define MAX_CARDS 8 #endif typedef int64_t openair0_timestamp; typedef volatile int64_t openair0_vtimestamp; - + /*!\brief structrue holds the parameters to configure USRP devices*/ typedef struct openair0_device_t openair0_device; @@ -123,16 +123,16 @@ typedef enum { /*!\brief openair0 device host type */ typedef enum { MIN_HOST_TYPE = 0, - /*!\brief device functions within a RAU */ + /*!\brief device functions within a RAU */ RAU_HOST, - /*!\brief device functions within a RRU */ + /*!\brief device functions within a RRU */ RRU_HOST, MAX_HOST_TYPE -}host_type_t; +} host_type_t; -/*! \brief RF Gain clibration */ +/*! \brief RF Gain clibration */ typedef struct { //! Frequency for which RX chain was calibrated double freq; @@ -160,7 +160,7 @@ typedef struct { duplex_mode_t duplex_mode; //! number of downlink resource blocks int num_rb_dl; - //! number of samples per frame + //! number of samples per frame unsigned int samples_per_frame; //! the sample rate for both transmit and receive. double sample_rate; @@ -175,9 +175,9 @@ typedef struct { //! number of TX channels (=TX antennas) int tx_num_channels; //! \brief RX base addresses for mmapped_dma - int32_t* rxbase[4]; + int32_t *rxbase[4]; //! \brief TX base addresses for mmapped_dma - int32_t* txbase[4]; + int32_t *txbase[4]; //! \brief Center frequency in Hz for RX. //! index: [0..rx_num_channels[ double rx_freq[4]; @@ -188,7 +188,7 @@ typedef struct { //! \brief Pointer to Calibration table for RX gains rx_gain_calib_table_t *rx_gain_calib_table; - //! mode for rxgain (ExpressMIMO2) + //! mode for rxgain (ExpressMIMO2) rx_gain_t rxg_mode[4]; //! \brief Gain for RX in dB. //! index: [0..rx_num_channels] @@ -202,14 +202,14 @@ typedef struct { double rx_bw; //! TX bandwidth in Hz double tx_bw; - //! clock source + //! clock source clock_source_t clock_source; //! Manual SDR IP address char *sdr_addrs; //! Auto calibration flag int autocal[4]; //! rf devices work with x bits iqs when oai have its own iq format - //! the two following parameters are used to convert iqs + //! the two following parameters are used to convert iqs int iq_txshift; int iq_rxrescale; //! Configuration file for LMS7002M @@ -222,10 +222,10 @@ typedef struct { unsigned int sf_read_delay; // read delay in replay mode unsigned int sf_write_delay; // write delay in replay mode unsigned int eth_mtu; // ethernet MTU -#endif +#endif } openair0_config_t; -/*! \brief RF mapping */ +/*! \brief RF mapping */ typedef struct { //! card id int card; @@ -272,14 +272,14 @@ struct openair0_device_t { /*!brief Component Carrier ID of this device */ int CC_id; - + /*!brief Type of this device */ dev_type_t type; /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */ transport_type_t transp_type; - /*!brief Type of the device's host (RAU/RRU) */ + /*!brief Type of the device's host (RAU/RRU) */ host_type_t host_type; /* !brief RF frontend parameters set by application */ @@ -301,25 +301,25 @@ struct openair0_device_t { /*! \brief Called to send a request message between RAU-RRU on control port @param device pointer to the device structure specific to the RF hardware target @param msg pointer to the message structure passed between RAU-RRU - @param msg_len length of the message - */ + @param msg_len length of the message + */ int (*trx_ctlsend_func)(openair0_device *device, void *msg, ssize_t msg_len); /*! \brief Called to receive a reply message between RAU-RRU on control port @param device pointer to the device structure specific to the RF hardware target @param msg pointer to the message structure passed between RAU-RRU - @param msg_len length of the message - */ + @param msg_len length of the message + */ int (*trx_ctlrecv_func)(openair0_device *device, void *msg, ssize_t msg_len); /*! \brief Called to send samples to the RF target @param device pointer to the device structure specific to the RF hardware target - @param timestamp The timestamp at whicch the first sample MUST be sent + @param timestamp The timestamp at whicch the first sample MUST be sent @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to TRUE if timestamp parameter needs to be applied - */ + */ int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); /*! \brief Receive samples from hardware. @@ -335,55 +335,55 @@ struct openair0_device_t { */ int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id); - /*! \brief print the device statistics + /*! \brief print the device statistics * \param device the hardware to use * \returns 0 on success */ int (*trx_get_stats_func)(openair0_device *device); - /*! \brief Reset device statistics + /*! \brief Reset device statistics * \param device the hardware to use - * \returns 0 in success + * \returns 0 in success */ int (*trx_reset_stats_func)(openair0_device *device); - /*! \brief Terminate operation of the transceiver -- free all associated resources + /*! \brief Terminate operation of the transceiver -- free all associated resources * \param device the hardware to use */ void (*trx_end_func)(openair0_device *device); - /*! \brief Stop operation of the transceiver + /*! \brief Stop operation of the transceiver */ int (*trx_stop_func)(openair0_device *device); /* Functions API related to UE*/ - /*! \brief Set RX feaquencies + /*! \brief Set RX feaquencies * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \param exmimo_dump_config dump EXMIMO configuration - * \returns 0 in success + * \param exmimo_dump_config dump EXMIMO configuration + * \returns 0 in success */ - int (*trx_set_freq_func)(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config); - + int (*trx_set_freq_func)(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config); + /*! \brief Set gains * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ - int (*trx_set_gains_func)(openair0_device* device, openair0_config_t *openair0_cfg); + int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg); /*! \brief RRU Configuration callback * \param idx RU index * \param arg pointer to capabilities or configuration */ - void (*configure_rru)(int idx, void* arg); + void (*configure_rru)(int idx, void *arg); }; /* type of device init function, implemented in shared lib */ typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); /* type of transport init function, implemented in shared lib */ -typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params); +typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); #ifdef __cplusplus extern "C" @@ -391,23 +391,23 @@ extern "C" #endif - /*! \brief Initialize openair RF target. It returns 0 if OK */ - int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); - /*! \brief Initialize transport protocol . It returns 0 if OK */ - int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params); +/*! \brief Initialize openair RF target. It returns 0 if OK */ +int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); +/*! \brief Initialize transport protocol . It returns 0 if OK */ +int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); - - /*! \brief Get current timestamp of USRP - * \param device the hardware to use - */ - openair0_timestamp get_usrp_time(openair0_device *device); - /*! \brief Set RX frequencies - * \param device the hardware to use - * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success - */ - int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg); +/*! \brief Get current timestamp of USRP + * \param device the hardware to use + */ +openair0_timestamp get_usrp_time(openair0_device *device); + +/*! \brief Set RX frequencies + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + * \returns 0 in success + */ +int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg); /*@}*/ diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index acb4c2ec9b..2c8e55d14f 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -138,7 +138,7 @@ int eth_socket_init_raw(openair0_device *device) { return 0; } - +/* 09/03/2019: fix obvious inconsistencies, but this code hasn't be tested for sure */ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) { int bytes_sent=0; @@ -148,7 +148,12 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi //sendto_flag|=flags; eth->tx_nsamps=nsamps; - + int pktsize; + if (eth->compression == ALAW_COMPRESS) { + pktsize = RAW_PACKET_SIZE_BYTES_ALAW(nsamps); + } else { + pktsize = RAW_PACKET_SIZE_BYTES(nsamps); + } for (i=0;iehd,MAC_HEADER_SIZE_BYTES); *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1); - *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp; - - int sent_byte; - + *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp; /*printf("[RRU]write mod_%d %d , len %d, buff %p \n", Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/ - while(bytes_sent < sent_byte) { -#if DEBUG - printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n", - (void *)(buff2+bytes_sent), - sent_byte - bytes_sent, - bytes_sent); -#endif + while(bytes_sent < pktsize) { + /* Send packet */ bytes_sent += send(eth->sockfdd, buff2, - sent_byte, + pktsize, sendto_flag); if ( bytes_sent == -1) { eth->num_tx_errors++; perror("ETHERNET WRITE: "); exit(-1); } else { -#if DEBUG - printf("------- TX ------: nu=%x an_id=%d ts%d bytes_sent=%d\n", - *(uint8_t *)(buff2+ETH_ALEN), - *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)), - *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)), - bytes_sent); - dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, sent_byte, TX_FLAG); - -#endif - eth->tx_actual_nsamps=bytes_sent>>2; - eth->tx_count++; + eth->tx_actual_nsamps=bytes_sent>>2; + eth->tx_count++; } } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index fd84c66c75..787e630d17 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1381,12 +1381,11 @@ int setup_RU_buffers(RU_t *ru) { else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; - if(IS_SOFTMODEM_BASICSIM) - /* this is required for the basic simulator in TDD mode - * TODO: find a proper cleaner solution - */ - ru->N_TA_offset = 0; - + if(IS_SOFTMODEM_BASICSIM) + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + ru->N_TA_offset = 0; } if (ru->openair0_cfg.mmapped_dma == 1) { diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index e121e31a39..242d0b76d7 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -99,9 +99,11 @@ void get_common_options(void) { if (basicsim) { set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); } + #if BASIC_SIMULATOR - set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); + set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); #endif + if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 0ee3d6dcf9..15553c0af3 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -655,10 +655,12 @@ int main( int argc, char **argv ) { fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); uint32_t pdcp_initmask = ( IS_SOFTMODEM_NOS1 )? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; # + if ( IS_SOFTMODEM_NOS1) pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + pdcp_module_init(pdcp_initmask); - + if (RC.nb_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP if (create_tasks(1) < 0) { diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 853c98df3f..bb2319774c 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -80,12 +80,12 @@ void init_UE_threads_stub(int); void init_UE_single_thread_stub(int); void *UE_thread(void *arg); void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp); -void init_UE_stub(int nb_inst,int,int,char*); -void init_UE_stub_single_thread(int nb_inst,int,int,char*); +void init_UE_stub(int nb_inst,int,int,char *); +void init_UE_stub_single_thread(int nb_inst,int,int,char *); int init_timer_thread(void); extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), - unsigned char _multicast_group, char *multicast_ifname); + unsigned char _multicast_group, char *multicast_ifname); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); @@ -169,21 +169,18 @@ struct sched_param sched_param_UE_thread; void get_uethreads_params(void) { paramdef_t cmdline_threadsparams[] =CMDLINE_UETHREADSPARAMS_DESC; - - config_process_cmdline( cmdline_threadsparams,sizeof(cmdline_threadsparams)/sizeof(paramdef_t),NULL); } void phy_init_lte_ue_transport(PHY_VARS_UE *ue,int absraction_flag); -PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t UE_id, - uint8_t abstraction_flag) +PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag) { - - PHY_VARS_UE* ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE)); + PHY_VARS_UE *ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE)); memset(ue,0,sizeof(PHY_VARS_UE)); if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in @@ -195,13 +192,12 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, ue->mac_enabled = 1; // In phy_stub_UE (MAC-to-MAC) mode these init functions don't need to get called. Is this correct? - if (nfapi_mode!=3) - { - // initialize all signal buffers - init_lte_ue_signal(ue,1,abstraction_flag); - // intialize transport - init_lte_ue_transport(ue,abstraction_flag); - } + if (nfapi_mode!=3) { + // initialize all signal buffers + init_lte_ue_signal(ue,1,abstraction_flag); + // intialize transport + init_lte_ue_transport(ue,abstraction_flag); + } return(ue); } @@ -211,9 +207,9 @@ char uecap_xer[1024]; -void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { - +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name) { #ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { struct sched_attr attr= {0}; attr.size = sizeof(attr); @@ -222,60 +218,64 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_ attr.sched_deadline = sched_deadline; attr.sched_period = 0; AssertFatal(sched_setattr(0, &attr, 0) == 0, - "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); + "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", - name, (unsigned long)gettid(), sched_getcpu()); + name, (unsigned long)gettid(), sched_getcpu()); } + #else + if (CPU_COUNT(cpuset) > 0) AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; sp.sched_priority = sched_fifo; AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, - "Can't set thread priority, Are you root?\n"); + "Can't set thread priority, Are you root?\n"); /* Check the actual affinity mask assigned to the thread */ cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); + if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { - char txt[512]={0}; + char txt[512]= {0}; + for (int j = 0; j < CPU_SETSIZE; j++) if (CPU_ISSET(j, cset)) - sprintf(txt+strlen(txt), " %d ", j); + sprintf(txt+strlen(txt), " %d ", j); + printf("CPU Affinity of thread %s is %s\n", name, txt); } + CPU_FREE(cset); #endif - } void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp0) { - PHY_VARS_UE *UE; int inst; int ret; LTE_DL_FRAME_PARMS *fp; - LOG_I(PHY,"UE : Calling Layer 2 for initialization\n"); - l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, - 0,// cba_group_active - 0); // HO flag + 0,// cba_group_active + 0); // HO flag + + if (PHY_vars_UE_g==NULL) PHY_vars_UE_g = (PHY_VARS_UE ***)calloc(1+nb_inst,sizeof(PHY_VARS_UE **)); + + for (inst=0; instframe_parms.nb_antennas_rx = fp0->nb_antennas_rx; - RC.ru[0]->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx; - PHY_vars_UE_g[inst][0] = init_ue_vars(&RC.ru[0]->frame_parms,inst,0); + RC.ru[0]->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; + RC.ru[0]->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx; + PHY_vars_UE_g[inst][0] = init_ue_vars(&RC.ru[0]->frame_parms,inst,0); } + // turn off timing control loop in UE PHY_vars_UE_g[inst][0]->no_timing_correction = timing_correction; - UE = PHY_vars_UE_g[inst][0]; fp = &UE->frame_parms; printf("PHY_vars_UE_g[0][0] = %p\n",UE); @@ -290,7 +290,6 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti UE->pusch_config_dedicated[i].betaOffset_ACK_Index = 0; UE->pusch_config_dedicated[i].betaOffset_RI_Index = 0; UE->pusch_config_dedicated[i].betaOffset_CQI_Index = 2; - UE->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; UE->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); UE->scheduling_request_config[i].dsr_TransMax = sr_n4; @@ -305,69 +304,75 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti if (UE->mac_enabled == 1) { UE->pdcch_vars[0][0]->crnti = 0x1234; UE->pdcch_vars[1][0]->crnti = 0x1234; - }else { + } else { UE->pdcch_vars[0][0]->crnti = 0x1235; UE->pdcch_vars[1][0]->crnti = 0x1235; } + UE->rx_total_gain_dB = rxgain; UE->tx_power_max_dBm = txpowermax; - UE->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx; - UE->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; + UE->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; if (fp->frame_type == TDD) { switch (fp->N_RB_DL) { + case 100: + if (fp->threequarter_fs) UE->N_TA_offset = (624*3)/4; + else UE->N_TA_offset = 624; - case 100: - if (fp->threequarter_fs) UE->N_TA_offset = (624*3)/4; - else UE->N_TA_offset = 624; - break; - case 75: - UE->N_TA_offset = (624*3)/4; - break; - case 50: - UE->N_TA_offset = 624/2; - break; - case 25: - UE->N_TA_offset = 624/4; - break; - case 15: - UE->N_TA_offset = 624/8; - break; - case 6: - UE->N_TA_offset = 624/16; - break; - default: - AssertFatal(1==0,"illegal N_RB_DL %d\n",fp->N_RB_DL); - break; + break; + + case 75: + UE->N_TA_offset = (624*3)/4; + break; + + case 50: + UE->N_TA_offset = 624/2; + break; + + case 25: + UE->N_TA_offset = 624/4; + break; + + case 15: + UE->N_TA_offset = 624/8; + break; + + case 6: + UE->N_TA_offset = 624/16; + break; + + default: + AssertFatal(1==0,"illegal N_RB_DL %d\n",fp->N_RB_DL); + break; } - } - else UE->N_TA_offset = 0; + } else UE->N_TA_offset = 0; if( IS_SOFTMODEM_BASICSIM) - /* this is required for the basic simulator in TDD mode - * TODO: find a proper cleaner solution - */ + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ UE->N_TA_offset = 0; - if (simL1flag == 1) init_ue_devices(UE); + LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); init_UE_threads(inst); if (simL1flag == 0) { ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]); - if (ret !=0){ - exit_fun("Error loading device library"); + + if (ret !=0) { + exit_fun("Error loading device library"); } } + UE->rfdevice.host_type = RAU_HOST; // UE->rfdevice.type = NONE_DEV; - AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, - (void*)UE), ""); + (void *)UE), ""); } printf("UE threads created by %ld\n", gettid()); @@ -376,31 +381,24 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti // Initiating all UEs within a single set of threads for PHY_STUB. Future extensions -> multiple // set of threads for multiple UEs. void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) { - int inst; - LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst); - l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, - 0,// cba_group_active - 0); // HO flag - - for (inst=0;instMod_id); init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); ind = 0; found = 0; - if (UE->UE_scan == 0) { do { current_band = eutra_bands[ind].band; printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); if ((eutra_bands[ind].dl_min <= UE->frame_parms.dl_CarrierFreq) && (eutra_bands[ind].dl_max >= UE->frame_parms.dl_CarrierFreq)) { - for (i=0; i<4; i++) - uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; + for (i=0; i<4; i++) + uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; found = 1; break; @@ -501,229 +489,240 @@ static void *UE_thread_synch(void *arg) return &UE_thread_synch_retval; } + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,oai_exit, + openair0_cfg[0].rx_num_channels); - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,oai_exit, openair0_cfg[0].rx_num_channels); - - for (i=0;irf_map.card].rx_num_channels;i++) { + for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq; openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + if (uplink_frequency_offset[CC_id][i] != 0) // - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; else //FDD - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; } sync_mode = pbch; - } else if (UE->UE_scan == 1) { current_band=0; for (i=0; irf_map.card].rx_num_channels; i++) { downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = - bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; + bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; } } -/* - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - pthread_mutex_unlock(&sync_mutex); -*/ + /* + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + pthread_mutex_unlock(&sync_mutex); + */ wait_sync("UE_thread_sync"); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); while (oai_exit==0) { AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + while (UE->proc.instance_cnt_synch < 0) // the thread waits here most of the time pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); switch (sync_mode) { - case pss: - LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - current_offset += 20000000; // increase by 20 MHz + case pss: + LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + current_offset += 20000000; // increase by 20 MHz - if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { - current_band++; - current_offset=0; - } + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { + current_band++; + current_offset=0; + } - if (current_band==bands_to_scan.nbands) { - current_band=0; - oai_exit=1; - } + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } - for (i=0; irf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - if (UE->UE_scan_carrier) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - } + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + } - break; + break; - case pbch: + case pbch: + LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (initial_sync( UE, UE->mode ) == 0) { + if (initial_sync( UE, UE->mode ) == 0) { + LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); - LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", - (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti, - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, - UE->UE_scan_carrier ); + // rerun with new cell parameters and frequency-offset + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); + else + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); - // rerun with new cell parameters and frequency-offset - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); - else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; - downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; - freq_offset=0; - } - } + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + freq_offset=0; + } + } - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - } + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); - //UE->rfdevice.trx_stop_func(&UE->rfdevice); - sleep(1); - init_frame_parms(&UE->frame_parms,1); - /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - }*/ + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; - if (UE->UE_scan_carrier == 1) { + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; - UE->UE_scan_carrier = 0; - } else { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - UE->is_synchronized = 1; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } - if( UE->mode == rx_dump_frame ) { - FILE *fd; - if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present - if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } else { - LOG_E(PHY,"Cannot open file for writing\n"); - exit(0); - } - } else { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - UE->is_synchronized = 0; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + //UE->rfdevice.trx_stop_func(&UE->rfdevice); + sleep(1); + init_frame_parms(&UE->frame_parms,1); - } - } - } - } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) - freq_offset += 100; - freq_offset *= -1; + /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + }*/ - if (abs(freq_offset) > 7500) { - LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); - FILE *fd; - if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - AssertFatal(1==0,"No cell synchronization found, abandoning"); - return &UE_thread_synch_retval; // not reached - } - } - LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + if (UE->UE_scan_carrier == 1) { + UE->UE_scan_carrier = 0; + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 1; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (UE->UE_scan_carrier==1) - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 - break; - case si: - default: - break; + if( UE->mode == rx_dump_frame ) { + FILE *fd; + + if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void *)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } else { + LOG_E(PHY,"Cannot open file for writing\n"); + exit(0); + } + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 0; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + } + } + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + freq_offset += 100; + + freq_offset *= -1; + + if (abs(freq_offset) > 7500) { + LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); + FILE *fd; + + if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { + fwrite((void *)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } + + AssertFatal(1==0,"No cell synchronization found, abandoning"); + return &UE_thread_synch_retval; // not reached + } + } + + LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (UE->UE_scan_carrier==1) + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + }// initial_sync=0 + + break; + + case si: + default: + break; } AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); // indicate readiness UE->proc.instance_cnt_synch--; AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); } // while !oai_exit @@ -737,15 +736,18 @@ static void *UE_thread_synch(void *arg) * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -const char * get_connectionloss_errstr(int errcode) { - switch (errcode) { - case CONNECTION_LOST: - return "RRC Connection lost, returning to PRACH"; - case PHY_RESYNCH: - return "RRC Connection lost, trying to resynch"; - case RESYNCH: - return "return to PRACH and perform a contention-free access"; - }; +const char *get_connectionloss_errstr(int errcode) { + switch (errcode) { + case CONNECTION_LOST: + return "RRC Connection lost, returning to PRACH"; + + case PHY_RESYNCH: + return "RRC Connection lost, trying to resynch"; + + case RESYNCH: + return "return to PRACH and perform a contention-free access"; + }; + return "UNKNOWN RETURN CODE"; } @@ -754,9 +756,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { struct rx_tx_thread_data *rtd = arg; UE_rxtx_proc_t *proc = rtd->proc; PHY_VARS_UE *UE = rtd->UE; - proc->subframe_rx=proc->sub_frame_start; - char threadname[256]; sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); cpu_set_t cpuset; @@ -764,51 +764,56 @@ static void *UE_thread_rxn_txnp4(void *arg) { if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 ) CPU_SET(threads.one, &cpuset); + if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 ) CPU_SET(threads.two, &cpuset); + if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) CPU_SET(threads.three, &cpuset); + //CPU_SET(threads.three, &cpuset); - init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, - threadname); + init_thread(900000,1000000, FIFO_PRIORITY-1, &cpuset, + threadname); while (!oai_exit) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("nothing to add"); } + while (proc->instance_cnt_rxtx < 0) { // most of the time, the thread is waiting here pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); } + //printf("Processing sub frqme %d in %s\n", proc->subframe_rx, threadname); initRefTimes(t2); initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); - // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", - threadname, - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadname, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } else { - LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", - threadname, - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadname, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } + #ifdef UE_SLOT_PARALLELISATION phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else @@ -819,45 +824,46 @@ static void *UE_thread_rxn_txnp4(void *arg) { #if UE_TIMING_TRACE start_meas(&UE->generic_stat); #endif - if (UE->mac_enabled==1) { + if (UE->mac_enabled==1) { int ret = ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); } } + #if UE_TIMING_TRACE stop_meas(&UE->generic_stat); #endif - // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) + (UE->frame_parms.frame_type == FDD) ) if (UE->mode != loop_through_memory) - phy_procedures_UE_TX(UE,proc,0,0,UE->mode); - - + phy_procedures_UE_TX(UE,proc,0,0,UE->mode); if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && - (UE->frame_parms.frame_type == TDD)) + (UE->frame_parms.frame_type == TDD)) if (UE->mode != loop_through_memory) - phy_procedures_UE_S_TX(UE,0,0); - updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + phy_procedures_UE_S_TX(UE,0,0); + updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); proc->instance_cnt_rxtx--; + if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { - if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); + if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); } + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); exit_fun("noting to add"); @@ -874,61 +880,57 @@ static void *UE_thread_rxn_txnp4(void *arg) { unsigned int emulator_absSF; void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) { - PHY_VARS_UE *UE; UE = PHY_vars_UE_g[0][0]; + UE_tport_t *pdu = (UE_tport_t *)rx_buffer; + SLSCH_t *slsch = (SLSCH_t *)&pdu->slsch; + SLDCH_t *sldch = (SLDCH_t *)&pdu->sldch; - UE_tport_t *pdu = (UE_tport_t*)rx_buffer; - SLSCH_t *slsch = (SLSCH_t*)&pdu->slsch; - SLDCH_t *sldch = (SLDCH_t*)&pdu->sldch; + switch (((UE_tport_header_t *)rx_buffer)->packet_type) { + case TTI_SYNC: + emulator_absSF = ((UE_tport_header_t *)rx_buffer)->absSF; + wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); + break; - switch (((UE_tport_header_t*)rx_buffer)->packet_type) { - case TTI_SYNC: - emulator_absSF = ((UE_tport_header_t*)rx_buffer)->absSF; - wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); - break; - case SLSCH: + case SLSCH: + LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLSCH packet\n",emulator_absSF/10,emulator_absSF%10); + LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC\n",num_bytes, + pdu->header.absSF/10,pdu->header.absSF%10, + slsch->payload_length); + printf("SLSCH:"); + for (int i=0; iheader.absSF/10,pdu->header.absSF%10, - slsch->payload_length); - printf("SLSCH:"); - for (int i=0;iheader.absSF/10, + pdu->header.absSF%10, + pdu->payload, + slsch->payload_length, + 0, + SL_DISCOVERY_FLAG_NO); + break; - ue_send_sl_sdu(0, - 0, - pdu->header.absSF/10, - pdu->header.absSF%10, - pdu->payload, - slsch->payload_length, - 0, - SL_DISCOVERY_FLAG_NO); - break; + case SLDCH: + LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10); + LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes, + pdu->header.absSF/10,pdu->header.absSF%10, + sldch->payload_length); + printf("SLDCH:"); - case SLDCH: - - - LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10); - LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes, - pdu->header.absSF/10,pdu->header.absSF%10, - sldch->payload_length); - printf("SLDCH:"); - for (int i=0;iheader.absSF/10, - pdu->header.absSF%10, - sldch->payload, - sldch->payload_length, - 0, - SL_DISCOVERY_FLAG_YES); - break; + for (int i=0; iheader.absSF/10, + pdu->header.absSF%10, + sldch->payload, + sldch->payload_length, + 0, + SL_DISCOVERY_FLAG_YES); + break; } } @@ -942,21 +944,19 @@ void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) { */ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { - - thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); - - // for multipule UE's L2-emulator - //module_id_t Mod_id = 0; - - //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames + thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); + // for multipule UE's L2-emulator + //module_id_t Mod_id = 0; + //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames static __thread int UE_thread_rxtx_retval; struct rx_tx_thread_data *rtd = arg; - if (rtd == NULL) { - LOG_E( MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n" ); - exit_fun("nothing to add"); - } - UE_rxtx_proc_t *proc = rtd->proc; + if (rtd == NULL) { + LOG_E( MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n" ); + exit_fun("nothing to add"); + } + + UE_rxtx_proc_t *proc = rtd->proc; // settings for nfapi-L2-emulator mode module_id_t ue_thread_id = rtd->ue_thread_id; uint16_t ue_index = 0; @@ -967,11 +967,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { uint8_t end_flag; proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0]; phy_stub_ticking->num_single_thread[ue_thread_id] = -1; - UE = rtd->UE; - - if(ue_thread_id == 0){ + if(ue_thread_id == 0) { phy_stub_ticking->ticking_var = -1; proc->subframe_rx=proc->sub_frame_start; // Initializations for nfapi-L2-emulator mode @@ -981,296 +979,287 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { tx_request_pdu_list = NULL; // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. - do{ + do { end_flag = 1; - for(uint16_t i = 0;i< NB_THREAD_INST;i++){ - if(phy_stub_ticking->num_single_thread[i] == 0){ + + for(uint16_t i = 0; i< NB_THREAD_INST; i++) { + if(phy_stub_ticking->num_single_thread[i] == 0) { end_flag = 0; } } - }while(end_flag == 0); + } while(end_flag == 0); sync_var=0; } - //PANOS: CAREFUL HERE! wait_sync("UE_phy_stub_single_thread_rxn_txnp4"); while (!oai_exit) { - if(ue_thread_id == 0){ - if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { - LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("nothing to add"); - } - while (phy_stub_ticking->ticking_var < 0) { - // most of the time, the thread is waiting here - //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) - LOG_D(MAC,"Waiting for ticking_var\n"); - pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); - } - phy_stub_ticking->ticking_var--; - if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { - LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - } + if(ue_thread_id == 0) { + if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } - proc->subframe_rx=timer_subframe; - proc->frame_rx = timer_frame; - - // FDD and TDD tx timing settings. - // XXX:It is the result of timing adjustment in debug. - // It is necessary to investigate why this will work in the future. - proc->subframe_tx=(timer_subframe+sf_ahead)%10; - proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0); - //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + while (phy_stub_ticking->ticking_var < 0) { + // most of the time, the thread is waiting here + //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) + LOG_D(MAC,"Waiting for ticking_var\n"); + pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); + } - if (UE != NULL) { - if (UE->frame_parms.frame_type == FDD) { - oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + phy_stub_ticking->ticking_var--; + + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } + + proc->subframe_rx=timer_subframe; + proc->frame_rx = timer_frame; + // FDD and TDD tx timing settings. + // XXX:It is the result of timing adjustment in debug. + // It is necessary to investigate why this will work in the future. + proc->subframe_tx=(timer_subframe+sf_ahead)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0); + //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + + if (UE != NULL) { + if (UE->frame_parms.frame_type == FDD) { + oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + } else { + oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + } } else { - oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + // Default will be FDD + oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + } + + //Guessing that the next 4 lines are not needed for the phy_stub mode. + /*initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/ + // Not sure whether we should put the memory allocation here and not sure how much memory + //we should allocate for each subframe cycle. + UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t)); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t)); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); + UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); + UL_INFO->cqi_ind.number_of_cqis = 0; + + if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } + + memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST); + pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread); + + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); } } else { - // Default will be FDD - oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - } + if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } - //Guessing that the next 4 lines are not needed for the phy_stub mode. - /*initRefTimes(t2); - initRefTimes(t3); - pickTime(current); - updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/ + while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) { + // most of the time, the thread is waiting here + LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id); + pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread); + } - - // Not sure whether we should put the memory allocation here and not sure how much memory - //we should allocate for each subframe cycle. - UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); - - UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); - UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; - - - UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t)); - UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; - - UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); - UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; - - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); - UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; - - UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); - UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); - UL_INFO->cqi_ind.number_of_cqis = 0; - - if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } - memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST); - pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread); - - if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } - }else{ - if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } - while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) { - // most of the time, the thread is waiting here - LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id); - pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread); - } - if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } } //for (Mod_id=0; Mod_idframe_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { + ue_Mod_id = ue_thread_id + NB_THREAD_INST*ue_index; + UE = PHY_vars_UE_g[ue_Mod_id][0]; + //LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id); + //UE = PHY_vars_UE_g[Mod_id][0]; + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } else { - LOG_D(PHY, "%s,%s: calling UE_RX\n", - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s: calling UE_RX\n", + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + + phy_procedures_UE_SL_RX(UE,proc); + + if (dl_config_req!=NULL && tx_request_pdu_list!=NULL) { + //if(dl_config_req!= NULL) { + dl_config_req_UE_MAC(dl_config_req, ue_Mod_id); + } + + if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) { + hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id); + } + + if(nfapi_mode!=3) + phy_procedures_UE_SL_TX(UE,proc); } +#if UE_TIMING_TRACE + start_meas(&UE->generic_stat); +#endif + + if (UE->mac_enabled==1) { + ret = ue_scheduler(ue_Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + + if ( ret != CONNECTION_OK) { + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + } + } + +#if UE_TIMING_TRACE + stop_meas(&UE->generic_stat); +#endif + + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) { + // We make the start of RA between consecutive UEs differ by 20 frames + //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { + if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) { + next_ra_frame++; + + if(next_ra_frame > 200) { + // check if we have PRACH opportunity + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) { + // The one working strangely... + //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) { + PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); + + if(prach_resources!=NULL ) { + UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx; + LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id,proc->frame_tx, proc->subframe_tx); + fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE; + next_Mod_id = ue_Mod_id + 1; + //next_ra_frame = (proc->frame_rx + 20)%1000; + next_ra_frame = 0; + } + + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } + } // mode is PRACH + + // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if(ul_config_req!=NULL) { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id); + } + } phy_procedures_UE_SL_RX(UE,proc); - - if (dl_config_req!=NULL && tx_request_pdu_list!=NULL){ - //if(dl_config_req!= NULL) { - dl_config_req_UE_MAC(dl_config_req, ue_Mod_id); - - } - - if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id); - } - - if(nfapi_mode!=3) - phy_procedures_UE_SL_TX(UE,proc); - - } - -#if UE_TIMING_TRACE - start_meas(&UE->generic_stat); -#endif - - if (UE->mac_enabled==1) { - - ret = ue_scheduler(ue_Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); - if ( ret != CONNECTION_OK) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); - } - } -#if UE_TIMING_TRACE - stop_meas(&UE->generic_stat); -#endif - - - // Prepare the future Tx data - - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) - if (UE->mode != loop_through_memory){ - - // We make the start of RA between consecutive UEs differ by 20 frames - //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { - if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) { - next_ra_frame++; - if(next_ra_frame > 200){ - // check if we have PRACH opportunity - - if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) { - - // The one working strangely... - //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) { - - PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); - if(prach_resources!=NULL ) { - UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx; - LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id ,proc->frame_tx, proc->subframe_tx); - fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); - Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0); - UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE; - next_Mod_id = ue_Mod_id + 1; - //next_ra_frame = (proc->frame_rx + 20)%1000; - next_ra_frame = 0; - } - - //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); - } - } - } // mode is PRACH - // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger - // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). - // Generate UL_indications which correspond to UL traffic. - if(ul_config_req!=NULL){ //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id); - } - } - - phy_procedures_UE_SL_RX(UE,proc); - - } //for (Mod_id=0; Mod_idnum_single_thread[ue_thread_id] = -1; // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. - if(ue_thread_id == 0){ - do{ + if(ue_thread_id == 0) { + do { end_flag = 1; - for(uint16_t i = 0;i< NB_THREAD_INST;i++){ - if(phy_stub_ticking->num_single_thread[i] == 0){ - end_flag = 0; + + for(uint16_t i = 0; i< NB_THREAD_INST; i++) { + if(phy_stub_ticking->num_single_thread[i] == 0) { + end_flag = 0; } } - }while(end_flag == 0); + } while(end_flag == 0); + if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) { + //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + oai_nfapi_crc_indication(&UL_INFO->crc_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n"); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + } - if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) - { - //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); - oai_nfapi_crc_indication(&UL_INFO->crc_ind); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n"); - UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; - } - if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0) - { - //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); - oai_nfapi_rx_ind(&UL_INFO->rx_ind); - for(uint8_t num_pdu = 0;num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus;num_pdu++){ - free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data); - } - //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); - UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; - } - if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) - { - //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); - oai_nfapi_harq_indication(&UL_INFO->harq_ind); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n"); - UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0; + if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0) { + //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); + oai_nfapi_rx_ind(&UL_INFO->rx_ind); + for(uint8_t num_pdu = 0; num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus; num_pdu++) { + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data); + } + + //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; } - if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0) - { - //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs); - oai_nfapi_sr_indication(&UL_INFO->sr_ind); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n"); - UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + + if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) { + //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); + oai_nfapi_harq_indication(&UL_INFO->harq_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n"); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0; + } + + if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0) { + //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs); + oai_nfapi_sr_indication(&UL_INFO->sr_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n"); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; } // Free UL_INFO messages //if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){ - free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); - UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; + free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; //} //if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){ - free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); - UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; //} //if(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list !=NULL){ - free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); - UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; + free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; //} //if(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list!=NULL){ - free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; + free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; //} free(UL_INFO->cqi_ind.cqi_pdu_list); UL_INFO->cqi_ind.cqi_pdu_list = NULL; @@ -1280,43 +1269,48 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { UL_INFO = NULL; // De-allocate memory of nfapi requests copies before next subframe round - if(dl_config_req!=NULL){ - if(dl_config_req->vendor_extension!=NULL){ - free(dl_config_req->vendor_extension); - dl_config_req->vendor_extension = NULL; - } - if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL){ - free(dl_config_req->dl_config_request_body.dl_config_pdu_list); - dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; - } - free(dl_config_req); - dl_config_req = NULL; - } - if(tx_request_pdu_list!=NULL){ - free(tx_request_pdu_list); - tx_request_pdu_list = NULL; - } - if(ul_config_req!=NULL){ - if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - free(ul_config_req->ul_config_request_body.ul_config_pdu_list); - ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; - } - free(ul_config_req); - ul_config_req = NULL; + if(dl_config_req!=NULL) { + if(dl_config_req->vendor_extension!=NULL) { + free(dl_config_req->vendor_extension); + dl_config_req->vendor_extension = NULL; + } + + if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL) { + free(dl_config_req->dl_config_request_body.dl_config_pdu_list); + dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; + } + + free(dl_config_req); + dl_config_req = NULL; } - if(hi_dci0_req!=NULL){ - if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; - } - free(hi_dci0_req); - hi_dci0_req = NULL; + if(tx_request_pdu_list!=NULL) { + free(tx_request_pdu_list); + tx_request_pdu_list = NULL; } + if(ul_config_req!=NULL) { + if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + + free(ul_config_req); + ul_config_req = NULL; + } + + if(hi_dci0_req!=NULL) { + if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) { + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + } + + free(hi_dci0_req); + hi_dci0_req = NULL; + } } - } + // thread finished free(arg); return &UE_thread_rxtx_retval; @@ -1334,34 +1328,32 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { */ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { - - thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); - - module_id_t Mod_id = 0; + thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); + module_id_t Mod_id = 0; static __thread int UE_thread_rxtx_retval; struct rx_tx_thread_data *rtd = arg; UE_rxtx_proc_t *proc = rtd->proc; PHY_VARS_UE *UE = rtd->UE; - phy_stub_ticking->ticking_var = -1; proc->subframe_rx=proc->sub_frame_start; - // CAREFUL HERE! wait_sync("UE_phy_stub_thread_rxn_txnp4"); while (!oai_exit) { - if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("nothing to add"); } + while (phy_stub_ticking->ticking_var < 0) { // most of the time, the thread is waiting here //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) LOG_D(MAC,"Waiting for ticking_var\n"); pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); } + phy_stub_ticking->ticking_var--; + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); exit_fun("nothing to add"); @@ -1371,125 +1363,118 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { proc->frame_rx = timer_frame; proc->subframe_tx=(timer_subframe+4)%10; proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); - - // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { - + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } else { - LOG_D(PHY, "%s,%s: calling UE_RX\n", - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "%s,%s: calling UE_RX\n", + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } - phy_procedures_UE_SL_RX(UE,proc); - - oai_subframe_ind(timer_frame, timer_subframe); + oai_subframe_ind(timer_frame, timer_subframe); if(dl_config_req!= NULL) { - - dl_config_req_UE_MAC(dl_config_req, Mod_id); - + dl_config_req_UE_MAC(dl_config_req, Mod_id); } + //if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){ - if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); - //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; - //} - free(hi_dci0_req); - hi_dci0_req = NULL; + if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) { + hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); + //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + //} + free(hi_dci0_req); + hi_dci0_req = NULL; + } else if(hi_dci0_req!=NULL) { + free(hi_dci0_req); + hi_dci0_req = NULL; } - else if(hi_dci0_req!=NULL){ - free(hi_dci0_req); - hi_dci0_req = NULL; - } - if (nfapi_mode != 3) phy_procedures_UE_SL_TX(UE,proc); - } #if UE_TIMING_TRACE start_meas(&UE->generic_stat); #endif - if (UE->mac_enabled==1) { + if (UE->mac_enabled==1) { int ret = ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0); + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0); + if (ret != CONNECTION_OK) - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); } + #if UE_TIMING_TRACE stop_meas(&UE->generic_stat); #endif - // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) - if (UE->mode != loop_through_memory){ + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) { + if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) { + // check if we have PRACH opportunity + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) { + PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); - if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) { + if(prach_resources!=NULL) { + fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; + } - // check if we have PRACH opportunity + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } // mode is PRACH - if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) { - PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); - if(prach_resources!=NULL) { - fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); - Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); - UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; - } + // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n"); + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); - //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); - } - } // mode is PRACH - // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger - // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). - // Generate UL_indications which correspond to UL traffic. - if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n"); - ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); - if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - free(ul_config_req->ul_config_request_body.ul_config_pdu_list); - ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; - } - free(ul_config_req); - ul_config_req = NULL; - } - else if(ul_config_req!=NULL){ - free(ul_config_req); - ul_config_req = NULL; - } + if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + + free(ul_config_req); + ul_config_req = NULL; + } else if(ul_config_req!=NULL) { + free(ul_config_req); + ul_config_req = NULL; + } } phy_procedures_UE_SL_RX(UE,proc); - } + // thread finished free(arg); return &UE_thread_rxtx_retval; @@ -1508,39 +1493,34 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { */ void *UE_thread(void *arg) { - - PHY_VARS_UE *UE = (PHY_VARS_UE *) arg; // int tx_enabled = 0; int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); openair0_timestamp timestamp,timestamp1; - void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; int start_rx_stream = 0; int i; int th_id; - static uint8_t thread_idx = 0; - cpu_set_t cpuset; CPU_ZERO(&cpuset); + if ( threads.iq != -1 ) CPU_SET(threads.iq, &cpuset); - init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, - "UHD Threads"); + init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, + "UHD Threads"); /* while (sync_var<0) pthread_cond_wait(&sync_cond, &sync_mutex); pthread_mutex_unlock(&sync_mutex); */ - wait_sync("UE thread"); #ifdef NAS_UE MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif - int sub_frame=-1; //int cumulated_shift=0; @@ -1550,13 +1530,12 @@ void *UE_thread(void *arg) { } while (!oai_exit) { - if (IS_SOFTMODEM_BASICSIM) + if (IS_SOFTMODEM_BASICSIM) while (!(UE->proc.instance_cnt_synch < 0)) { printf("ue sync not ready\n"); usleep(500*1000); } - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); int instance_cnt_synch = UE->proc.instance_cnt_synch; int is_synchronized = UE->is_synchronized; @@ -1564,223 +1543,241 @@ void *UE_thread(void *arg) { if (is_synchronized == 0) { if (instance_cnt_synch < 0) { // we can invoke the synch - // grab 10 ms of signal and wakeup synch thread - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; + // grab 10 ms of signal and wakeup synch thread + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][0]; - if (UE->mode != loop_through_memory) - AssertFatal( UE->frame_parms.samples_per_tti*10 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx), ""); - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - instance_cnt_synch = ++UE->proc.instance_cnt_synch; - if (instance_cnt_synch == 0) { - AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - } - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + if (UE->mode != loop_through_memory) + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); + + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + instance_cnt_synch = ++UE->proc.instance_cnt_synch; + + if (instance_cnt_synch == 0) { + AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); + } else { + LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); + exit_fun("nothing to add"); + } + + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); } else { #if OAISIM - (void)dummy_rx; /* avoid gcc warnings */ - usleep(500); + (void)dummy_rx; /* avoid gcc warnings */ + usleep(500); #else - // grab 10 ms of signal into dummy buffer - if (UE->mode != loop_through_memory) { - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0; sf<10; sf++) - // printf("Reading dummy sf %d\n",sf); - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - } + + // grab 10 ms of signal into dummy buffer + if (UE->mode != loop_through_memory) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&dummy_rx[i][0]; + + for (int sf=0; sf<10; sf++) + // printf("Reading dummy sf %d\n",sf); + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx); + } + #endif - } + } + } // UE->is_synchronized==0 + else { + if (start_rx_stream==0) { + start_rx_stream=1; - } // UE->is_synchronized==0 - else { - if (start_rx_stream==0) { - start_rx_stream=1; - if (UE->mode != loop_through_memory) { - if (UE->no_timing_correction==0) { - LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); - AssertFatal(UE->rx_offset == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)UE->common_vars.rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx),""); - } - UE->rx_offset=0; - UE->time_sync_cell=0; - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - for (th_id=0; th_id < RX_NB_TH; th_id++) { - UE->proc.proc_rxtx[th_id].frame_rx++; - } + if (UE->mode != loop_through_memory) { + if (UE->no_timing_correction==0) { + LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + AssertFatal(UE->rx_offset == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + UE->rx_offset, + UE->frame_parms.nb_antennas_rx),""); + } - // read in first symbol - AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)UE->common_vars.rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx),""); - slot_fep(UE,0, 0, 0, 0, 0); - } //UE->mode != loop_through_memory - else - rt_sleep_ns(1000*1000); + UE->rx_offset=0; + UE->time_sync_cell=0; + //UE->proc.proc_rxtx[0].frame_rx++; + //UE->proc.proc_rxtx[1].frame_rx++; + for (th_id=0; th_id < RX_NB_TH; th_id++) { + UE->proc.proc_rxtx[th_id].frame_rx++; + } + + // read in first symbol + AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx),""); + slot_fep(UE,0, 0, 0, 0, 0); + } //UE->mode != loop_through_memory + else + rt_sleep_ns(1000*1000); + } else { + sub_frame++; + sub_frame%=10; + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx]; + // update thread index for received subframe + UE->current_thread_id[sub_frame] = thread_idx; + + if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + int t; + + for (t = 0; t < 2; t++) { + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; + pthread_mutex_lock(&proc->mutex_rxtx); + + while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + + pthread_mutex_unlock(&proc->mutex_rxtx); + } + } + + LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); + thread_idx++; + + if(thread_idx>=RX_NB_TH) + thread_idx = 0; + + if (UE->mode != loop_through_memory) { + for (i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ + UE->frame_parms.nb_prefix_samples0+ + sub_frame*UE->frame_parms.samples_per_tti]; + + for (i=0; iframe_parms.nb_antennas_tx; i++) + txp[i] = (void *)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; + + int readBlockSize, writeBlockSize; + + if (sub_frame<9) { + readBlockSize=UE->frame_parms.samples_per_tti; + writeBlockSize=UE->frame_parms.samples_per_tti; + } else { + // set TO compensation to zero + UE->rx_offset_diff = 0; + + // compute TO compensation that should be applied for this frame + + if (UE->no_timing_correction == 0) { + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && + UE->rx_offset > 0 ) + UE->rx_offset_diff = -1 ; + + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && + UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) + UE->rx_offset_diff = 1; + } + + LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); + readBlockSize=UE->frame_parms.samples_per_tti - + UE->frame_parms.ofdm_symbol_size - + UE->frame_parms.nb_prefix_samples0 - + UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.samples_per_tti - + UE->rx_offset_diff; + } + + AssertFatal(readBlockSize == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + readBlockSize, + UE->frame_parms.nb_antennas_rx),""); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (2*UE->frame_parms.samples_per_tti) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + + if( sub_frame==9) { + // read in first symbol of next frame and adjust for timing drift + int first_symbols=writeBlockSize-readBlockSize; + + if ( first_symbols > 0 ) + AssertFatal(first_symbols == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp1, + (void **)UE->common_vars.rxdata, + first_symbols, + UE->frame_parms.nb_antennas_rx),""); + + if ( first_symbols <0 ) + LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); + } + + pickTime(gotIQs); + struct timespec tv= {0}; + tv.tv_nsec=10*1000; + + if( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) + tv.tv_sec=INT_MAX; + + // operate on thread sf mod 2 + if (pthread_mutex_timedlock(&proc->mutex_rxtx, &tv) !=0) { + if ( errno == ETIMEDOUT) { + LOG_E(PHY,"Missed real time\n"); + continue; } else { - sub_frame++; - sub_frame%=10; - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx]; - // update thread index for received subframe - UE->current_thread_id[sub_frame] = thread_idx; + LOG_E(PHY,"System error\n"); + abort(); + } + } - if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { - int t; - for (t = 0; t < 2; t++) { - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; - pthread_mutex_lock(&proc->mutex_rxtx); - while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - pthread_mutex_unlock(&proc->mutex_rxtx); - } - } - LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); + //usleep(3000); + if(sub_frame == 0) { + //UE->proc.proc_rxtx[0].frame_rx++; + //UE->proc.proc_rxtx[1].frame_rx++; + for (th_id=0; th_id < RX_NB_TH; th_id++) { + UE->proc.proc_rxtx[th_id].frame_rx++; + } + } - thread_idx++; - if(thread_idx>=RX_NB_TH) - thread_idx = 0; + //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); + //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); + for (th_id=0; th_id < RX_NB_TH; th_id++) { + UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs); + } + proc->subframe_rx=sub_frame; + proc->subframe_tx=(sub_frame+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + proc->timestamp_tx = timestamp+ + (4*UE->frame_parms.samples_per_tti)- + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; + proc->instance_cnt_rxtx++; + LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + initRefTimes(t1); + initStaticTime(lastTime); + updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); + pickStaticTime(lastTime); + } else { + printf("Processing subframe %d",proc->subframe_rx); + getchar(); + } + } // start_rx_stream==1 + } // UE->is_synchronized==1 + } // while !oai_exit - if (UE->mode != loop_through_memory) { - for (i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ - UE->frame_parms.nb_prefix_samples0+ - sub_frame*UE->frame_parms.samples_per_tti]; - for (i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; - - int readBlockSize, writeBlockSize; - if (sub_frame<9) { - readBlockSize=UE->frame_parms.samples_per_tti; - writeBlockSize=UE->frame_parms.samples_per_tti; - } else { - // set TO compensation to zero - - UE->rx_offset_diff = 0; - - // compute TO compensation that should be applied for this frame - - if (UE->no_timing_correction == 0) { - if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && - UE->rx_offset > 0 ) - UE->rx_offset_diff = -1 ; - if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && - UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) - UE->rx_offset_diff = 1; - } - - LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); - readBlockSize=UE->frame_parms.samples_per_tti - - UE->frame_parms.ofdm_symbol_size - - UE->frame_parms.nb_prefix_samples0 - - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.samples_per_tti - - UE->rx_offset_diff; - } - - AssertFatal(readBlockSize == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - readBlockSize, - UE->frame_parms.nb_antennas_rx),""); - AssertFatal( writeBlockSize == - UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - writeBlockSize, - UE->frame_parms.nb_antennas_tx, - 1),""); - if( sub_frame==9) { - // read in first symbol of next frame and adjust for timing drift - int first_symbols=writeBlockSize-readBlockSize; - if ( first_symbols > 0 ) - AssertFatal(first_symbols == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp1, - (void**)UE->common_vars.rxdata, - first_symbols, - UE->frame_parms.nb_antennas_rx),""); - if ( first_symbols <0 ) - LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); - } - pickTime(gotIQs); - struct timespec tv={0}; - tv.tv_nsec=10*1000; - if( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) - tv.tv_sec=INT_MAX; - // operate on thread sf mod 2 - if (pthread_mutex_timedlock(&proc->mutex_rxtx, &tv) !=0) { - if ( errno == ETIMEDOUT) { - LOG_E(PHY,"Missed real time\n"); - continue; - } else { - LOG_E(PHY,"System error\n"); - abort(); - } - } - //usleep(3000); - if(sub_frame == 0) { - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - for (th_id=0; th_id < RX_NB_TH; th_id++) { - UE->proc.proc_rxtx[th_id].frame_rx++; - } - } - //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); - //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); - for (th_id=0; th_id < RX_NB_TH; th_id++) { - UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs); - } - proc->subframe_rx=sub_frame; - proc->subframe_tx=(sub_frame+4)%10; - proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); - proc->timestamp_tx = timestamp+ - (4*UE->frame_parms.samples_per_tti)- - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - - proc->instance_cnt_rxtx++; - LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); - - AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); - AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); - initRefTimes(t1); - initStaticTime(lastTime); - updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); - pickStaticTime(lastTime); - - } else { - printf("Processing subframe %d",proc->subframe_rx); - getchar(); - } - } // start_rx_stream==1 - } // UE->is_synchronized==1 - - } // while !oai_exit - return NULL; + return NULL; } @@ -1799,28 +1796,26 @@ void *UE_thread(void *arg) { void init_UE_threads(int inst) { struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); UE = PHY_vars_UE_g[inst][0]; - pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - pthread_mutex_init(&UE->proc.mutex_synch,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL); UE->proc.instance_cnt_synch = -1; UE->is_synchronized = 0; - // the threads are not yet active, therefore access is allowed without locking int nb_threads=RX_NB_TH; + for (int i=0; iUE = UE; rtd->proc = &UE->proc.proc_rxtx[i]; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].instance_cnt_rxtx = -1; @@ -1828,19 +1823,17 @@ void init_UE_threads(int inst) { UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); - #ifdef UE_SLOT_PARALLELISATION //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL); //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL); //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd); - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL); pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd); #endif - } - pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); + + pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void *)UE); } @@ -1860,40 +1853,42 @@ void init_UE_single_thread_stub(int nb_inst) { struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - for (int i=0; iproc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - // Don't need synch for phy_stub mode //pthread_mutex_init(&UE->proc.mutex_synch,NULL); //pthread_cond_init(&UE->proc.cond_synch,NULL); - // the threads are not yet active, therefore access is allowed without locking // In phy_stub_UE mode due to less heavy processing operations we don't need two threads //int nb_threads=RX_NB_TH; int nb_threads=1; - for(uint16_t ue_thread_id = 0;ue_thread_id < NB_THREAD_INST;ue_thread_id++){ + + for(uint16_t ue_thread_id = 0; ue_thread_id < NB_THREAD_INST; ue_thread_id++) { UE = PHY_vars_UE_g[ue_thread_id][0]; + for (int i=0; iUE = UE; rtd->proc = &UE->proc.proc_rxtx[i]; rtd->ue_thread_id = ue_thread_id; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i; @@ -1902,6 +1897,7 @@ void init_UE_single_thread_stub(int nb_inst) { pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd); } } + // Remove thread for UE_sync in phy_stub_UE mode. //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); } @@ -1923,38 +1919,35 @@ void init_UE_single_thread_stub(int nb_inst) { void init_UE_threads_stub(int inst) { struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); UE = PHY_vars_UE_g[inst][0]; - pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - // Don't need synch for phy_stub mode //pthread_mutex_init(&UE->proc.mutex_synch,NULL); //pthread_cond_init(&UE->proc.cond_synch,NULL); - // the threads are not yet active, therefore access is allowed without locking // In phy_stub_UE mode due to less heavy processing operations we don't need two threads //int nb_threads=RX_NB_TH; int nb_threads=1; + for (int i=0; iUE = UE; rtd->proc = &UE->proc.proc_rxtx[i]; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_thread_rxn_txnp4, rtd); - - } + // Remove thread for UE_sync in phy_stub_UE mode. //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); } @@ -1964,61 +1957,54 @@ void init_UE_threads_stub(int inst) { #ifdef OPENAIR2 void fill_ue_band_info(void) { - LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; int i,j; - bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; for (i=0; irf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { - memcpy(&bands_to_scan.band_info[i], - &eutra_bands[j], - sizeof(eutra_band_t)); - - printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", - bands_to_scan.band_info[i].band, - UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, - bands_to_scan.band_info[i].dl_min, - bands_to_scan.band_info[i].dl_max, - bands_to_scan.band_info[i].ul_min, - bands_to_scan.band_info[i].ul_max, - (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); - break; + memcpy(&bands_to_scan.band_info[i], + &eutra_bands[j], + sizeof(eutra_band_t)); + printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", + bands_to_scan.band_info[i].band, + UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, + bands_to_scan.band_info[i].dl_min, + bands_to_scan.band_info[i].dl_max, + bands_to_scan.band_info[i].ul_min, + bands_to_scan.band_info[i].ul_max, + (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); + break; } } } #endif int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { - int i, CC_id; LTE_DL_FRAME_PARMS *frame_parms; for (CC_id=0; CC_idframe_parms); - // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + rxdata = (int32_t **)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t *) ); + txdata = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t *) ); for (i=0; inb_antennas_rx; i++) { LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", - CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); + CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + rxdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) ); phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD } for (i=0; inb_antennas_tx; i++) { LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", - CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); + CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + txdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) ); phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; } @@ -2027,6 +2013,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) // be careful when releasing memory! // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) } + return 0; } @@ -2039,7 +2026,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) // playing the role of nfapi-pnf. //02/02/2018 -static void* timer_thread( void* param ) { +static void *timer_thread( void *param ) { thread_top_init("timer_thread",1,870000L,1000000L,1000000L); timer_subframe =9; timer_frame =1023; @@ -2049,43 +2036,48 @@ static void* timer_thread( void* param ) { UE = PHY_vars_UE_g[0][0]; //double t_diff; int external_timer = 0; - - wait_sync("timer_thread"); - opp_enabled = 1; // first check if we are receiving timing indications if(nfapi_mode==4) { - usleep(10000); - if (UE->instance_cnt_timer > 0) { - external_timer = 1; - int absSFm1 = ((emulator_absSF+10239)%10240); - timer_frame = absSFm1/10; - timer_subframe = absSFm1%10; - pthread_mutex_lock(&UE->timer_mutex); - UE->instance_cnt_timer = -1; - pthread_mutex_unlock(&UE->timer_mutex); - LOG_I(PHY,"Running with external timer\n"); - } - else LOG_I(PHY,"Running with internal timer\n"); + usleep(10000); + + if (UE->instance_cnt_timer > 0) { + external_timer = 1; + int absSFm1 = ((emulator_absSF+10239)%10240); + timer_frame = absSFm1/10; + timer_subframe = absSFm1%10; + pthread_mutex_lock(&UE->timer_mutex); + UE->instance_cnt_timer = -1; + pthread_mutex_unlock(&UE->timer_mutex); + LOG_I(PHY,"Running with external timer\n"); + } else LOG_I(PHY,"Running with internal timer\n"); } struct timespec t_start; + struct timespec t_now; + struct timespec t_sleep; + uint64_t T_0; + uint64_t T_now; + uint64_t T_next_SF; + uint64_t T_sleep; + uint64_t sf_cnt = 0; //Total Subframe counter clock_gettime(CLOCK_MONOTONIC, &t_start); + T_0 = (uint64_t) t_start.tv_sec*1000000000 + t_start.tv_nsec; + LOG_D(MAC, "timer_thread(), T_0 value: %" PRId64 "\n", T_0); while (!oai_exit) { - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. if (timer_subframe==9) { @@ -2099,74 +2091,72 @@ static void* timer_thread( void* param ) { //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), ""); AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,""); phy_stub_ticking->ticking_var++; + // This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads) - if(phy_stub_ticking->ticking_var == 0){ + if(phy_stub_ticking->ticking_var == 0) { //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d", - //phy_stub_ticking->ticking_var); + //phy_stub_ticking->ticking_var); if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) { - //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); - LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); - exit_fun("nothing to add"); + //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); + exit_fun("nothing to add"); } - } - else - LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var); + } else + LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var); AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,""); start_meas(&UE->timer_stats); - //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp if (external_timer == 0) { - clock_gettime(CLOCK_MONOTONIC, &t_now); - sf_cnt++; - T_next_SF = T_0 + sf_cnt*1000000; - T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec; - if(T_now > T_next_SF){ - t_sleep.tv_sec =0; - t_sleep.tv_nsec =0; - } - else{ - T_sleep = T_next_SF - T_now; - t_sleep.tv_sec =0; - t_sleep.tv_nsec = (__syscall_slong_t) T_sleep; - } + clock_gettime(CLOCK_MONOTONIC, &t_now); + sf_cnt++; + T_next_SF = T_0 + sf_cnt*1000000; + T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec; + + if(T_now > T_next_SF) { + t_sleep.tv_sec =0; + t_sleep.tv_nsec =0; + } else { + T_sleep = T_next_SF - T_now; + t_sleep.tv_sec =0; + t_sleep.tv_nsec = (__syscall_slong_t) T_sleep; + } + nanosleep(&t_sleep, (struct timespec *)NULL); UE_tport_t pdu; pdu.header.packet_type = TTI_SYNC; pdu.header.absSF = (timer_frame*10)+timer_subframe; - if (nfapi_mode!=3){ - multicast_link_write_sock(0, - (char *)&pdu, - sizeof(UE_tport_header_t)); - } - } - else { + if (nfapi_mode!=3) { + multicast_link_write_sock(0, + (char *)&pdu, + sizeof(UE_tport_header_t)); + } + } else { wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread"); } - /*stop_meas(&UE->timer_stats); t_diff = get_time_meas_us(&UE->timer_stats); stop_meas(&UE->timer_stats); t_diff = get_time_meas_us(&UE->timer_stats);*/ } + free(phy_stub_ticking); pthread_cond_destroy(&phy_stub_ticking->cond_ticking); pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking); return 0; - } int init_timer_thread(void) { //PHY_VARS_UE *UE=PHY_vars_UE_g[0]; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; - phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking)); + PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; + phy_stub_ticking = (SF_ticking *)malloc(sizeof(SF_ticking)); pthread_mutex_init(&UE->timer_mutex,NULL); pthread_cond_init(&UE->timer_cond,NULL); UE->instance_cnt_timer = -1; @@ -2183,8 +2173,7 @@ int init_timer_thread(void) { /* HACK: this function is needed to compile the UE * fix it somehow */ -int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) -{ +int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) { printf("you cannot read this\n"); abort(); } diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 2eeb4cd426..f327b83cf9 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -760,22 +760,22 @@ int main( int argc, char **argv ) { } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); - init_opt(); uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1 )? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_mode == 3) ) { pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; } + if ( IS_SOFTMODEM_NOKRNMOD) pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + pdcp_module_init( pdcp_initmask ); //TTN for D2D printf ("RRC control socket\n"); rrc_control_socket_init(); printf ("PDCP PC5S socket\n"); pdcp_pc5_socket_init(); - // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); From d67d435a492e088aff1af1dfebf00c66410f3f01 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 11 Mar 2019 14:41:49 +0100 Subject: [PATCH 24/26] Fixing last cppcheck warnings Signed-off-by: Raphael Defosseux --- common/utils/telnetsrv/telnetsrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 4b6def2f6d..7f8645be02 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -355,7 +355,7 @@ int setgetvar(int moduleindex,char getorset,char *params) { char varname[TELNET_CMD_MAXSIZE]; char *varval=NULL; memset(varname,0,sizeof(varname)); - n = sscanf(params,"%s %ms",varname,&varval); + n = sscanf(params,"%9s %ms",varname,&varval); for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) { if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) { @@ -475,7 +475,7 @@ int process_command(char *buf) { memset(cmdb,0,sizeof(cmdb)); bufbck=strdup(buf); rt=CMDSTATUS_NOTFOUND; - j = sscanf(buf,"%9s %9s %[^\t\n]",modulename,cmd,cmdb); + j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb); if (telnetparams.telnetdbg > 0) printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); From d4495ec78ec0f73edc47b0bd095ea29397b6939d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 12 Mar 2019 12:52:58 +0100 Subject: [PATCH 25/26] CI: Lower iperf constraints on basic-simulator Simplify HSS configuration in VM-based testing Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 2 +- ci-scripts/runTestOnVM.sh | 150 ++++++++++++++++---------------- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 63dc724b84..e481936345 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -377,7 +377,7 @@ function report_test { fi PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` - if [[ $PERF_INT -lt 90 ]] + if [[ $PERF_INT -lt 80 ]] then echo " KO" >> ./test_simulator_results.html else diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 48f3adb675..27687d2660 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -227,6 +227,9 @@ function check_iperf { local LOC_BASE_LOG=$1 local LOC_REQ_BW=$2 local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` + local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l` + local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` + local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` @@ -235,11 +238,26 @@ function check_iperf { IPERF_STATUS=-1 else local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] + if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] then - echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*Mbits.* ]] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + IPERF_STATUS=-1 + fi else - IPERF_STATUS=-1 + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] + then + if [ $LOC_IS_DL -eq 1 ] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + echo "got requested UL bandwidth: $EFFECTIVE_BANDWIDTH" + fi + else + IPERF_STATUS=-1 + fi fi fi else @@ -299,7 +317,7 @@ function install_epc_on_vm { if [ -d /opt/ltebox-archives/ ] then # Checking if all ltebox archives are available to run ltebx epc on a brand new VM - if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ] + if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim-develop.zip ] then echo "############################################################" echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox" @@ -349,7 +367,7 @@ function install_epc_on_vm { echo "############################################################" scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu - scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim-develop.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu echo "############################################################" echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)" @@ -363,8 +381,8 @@ function install_epc_on_vm { # Installing HSS echo "echo \"cd /opt\"" >> $LOC_EPC_VM_CMDS echo "cd /opt" >> $LOC_EPC_VM_CMDS - echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $LOC_EPC_VM_CMDS - echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $LOC_EPC_VM_CMDS + echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim-develop.zip\"" >> $LOC_EPC_VM_CMDS + echo "sudo unzip -qq /home/ubuntu/hss-sim-develop.zip" >> $LOC_EPC_VM_CMDS echo "echo \"cd /opt/hss_sim0609\"" >> $LOC_EPC_VM_CMDS echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS @@ -500,16 +518,6 @@ function build_ue_on_separate_folder { echo "cd tmp-ue" >> $1 echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $1 echo "unzip -qq -DD ../localZip.zip" >> $1 - - # We may have some adaptation to do - if [ -f /opt/ltebox-archives/adapt_ue_l2_sim.txt ] - then - echo "############################################################" - echo "Doing some adaptation on UE side" - echo "############################################################" - cat /opt/ltebox-archives/adapt_ue_l2_sim.txt >> $1 - fi - echo "echo \"source oaienv\"" >> $1 echo "source oaienv" >> $1 echo "cd cmake_targets/" >> $1 @@ -794,15 +802,6 @@ function run_test_on_vm { # Retrieve EPC real IP address retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR - # We may have some adaptation to do - if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ] - then - echo "############################################################" - echo "Doing some adaptation on UE side" - echo "############################################################" - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt - fi - echo "############################################################" echo "Starting the eNB in FDD-5MHz mode" echo "############################################################" @@ -840,10 +839,10 @@ function run_test_on_vm { echo "Iperf DL" echo "############################################################" CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 10 $CURR_IPERF_LOG_BASE scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 10 echo "############################################################" echo "Iperf UL" @@ -900,10 +899,10 @@ function run_test_on_vm { echo "Iperf DL" echo "############################################################" CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 10 $CURR_IPERF_LOG_BASE scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 10 echo "############################################################" echo "Iperf UL" @@ -1124,51 +1123,52 @@ function run_test_on_vm { CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf none - echo "############################################################" - echo "Starting the UE in TDD-10MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - STATUS=-1 - return - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=tdd_10MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 - - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 - +# Disabling TDD-10MHz in order to stop getting false negatives +# echo "############################################################" +# echo "Starting the UE in TDD-10MHz mode" +# echo "############################################################" +# CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log +# start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350 +# if [ $UE_SYNC -eq 0 ] +# then +# echo "Problem w/ eNB and UE not syncing" +# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC +# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR +# echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log +# STATUS=-1 +# return +# fi +# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR +# +# echo "############################################################" +# echo "Pinging the UE" +# echo "############################################################" +# PING_LOG_FILE=tdd_10MHz_ping_ue.txt +# ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC +# check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 +# +# echo "############################################################" +# echo "Iperf DL" +# echo "############################################################" +# CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl +# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC +# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 +# +# echo "############################################################" +# echo "Terminate enb/ue simulators" +# echo "############################################################" +# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC +# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# sleep 10 +# # Disabling TDD-20MHz in order to stop getting false negatives # echo "############################################################" # echo "Starting the eNB in TDD-20MHz mode" From a299d6e24865ad866163bf49967d92621cf98c9f Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 12 Mar 2019 14:12:30 +0100 Subject: [PATCH 26/26] CI: fix RHEL build status Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnRH.sh | 2 +- ci-scripts/oai-ci-vm-tool | 15 +++++++++------ ci-scripts/reportBuildLocally.sh | 10 ++++++++-- ci-scripts/reportTestLocally.sh | 2 +- ci-scripts/runTestOnVM.sh | 7 ++++--- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh index dd3c382951..076f34f8d2 100755 --- a/ci-scripts/buildOnRH.sh +++ b/ci-scripts/buildOnRH.sh @@ -180,7 +180,7 @@ echo "Checking build status" echo "############################################################" LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 +NB_PATTERN_FILES=7 LOG_FILES=`ls $ARCHIVES_LOC/*.txt` STATUS=0 diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 30d8912f50..917b0e7491 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -510,13 +510,16 @@ else fi fi -# Checking uvt-kvm is installed -UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm` -if [ $UVT_KVM_PATH -eq 0 ] +if [ $REPORT_BUILD_CMD -ne 1 ] && [ $REPORT_TEST_CMD -ne 1 ] then - echo "Error: uvt-kvm is not installed" - top_usage - exit 1 + # Checking uvt-kvm is installed + UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm` + if [ $UVT_KVM_PATH -eq 0 ] + then + echo "Error: uvt-kvm is not installed" + top_usage + exit 1 + fi fi if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index d237cc652b..b5561eea54 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -561,7 +561,8 @@ function report_build { summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/enb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html - summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row4.html + summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_usrp/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row5.html summary_table_footer summary_table_header "OAI Build basic simulator option" ./archives/basic_sim @@ -604,6 +605,8 @@ function report_build { summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_eth_row4.html summary_table_row "RB Tools - Release 14" ./archives/enb_eth/rb_tool.Rel14.txt "Built target rb_tool" ./enb_eth_row5.html summary_table_row "NAS Mesh - Release 14" ./archives/enb_eth/nasmesh.Rel14.txt "Built target nasmesh" ./enb_eth_row6.html + summary_table_row "RF Simulator - Release 14" ./archives/enb_eth/rfsimulator.Rel14.txt "Built target rfsimulator" ./enb_eth_row7.html + summary_table_row "TCP OAI Bridge - Release 14" ./archives/enb_eth/tcp_bridge_oai.Rel14.txt "Built target tcp_bridge_oai" ./enb_eth_row8.html summary_table_footer summary_table_header "OAI Build UE -- ETHERNET transport option" ./archives/ue_eth @@ -613,6 +616,8 @@ function report_build { summary_table_row "Parameters Lib Config - Release 14" ./archives/ue_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./ue_eth_row4.html summary_table_row "RB Tools - Release 14" ./archives/ue_eth/rb_tool.Rel14.txt "Built target rb_tool" ./ue_eth_row5.html summary_table_row "NAS Mesh - Release 14" ./archives/ue_eth/nasmesh.Rel14.txt "Built target nasmesh" ./ue_eth_row6.html + summary_table_row "RF Simulator - Release 14" ./archives/ue_eth/rfsimulator.Rel14.txt "Built target rfsimulator" ./ue_eth_row7.html + summary_table_row "TCP OAI Bridge - Release 14" ./archives/ue_eth/tcp_bridge_oai.Rel14.txt "Built target tcp_bridge_oai" ./ue_eth_row8.html summary_table_footer if [ -e ./archives/red_hat ] @@ -623,7 +628,8 @@ function report_build { summary_table_row "LTE SoftModem - Release 14" ./archives/red_hat/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html summary_table_row "Coding - Release 14" ./archives/red_hat/coding.Rel14.txt "Built target coding" ./enb_usrp_rh_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/red_hat/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html - summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html + summary_table_row "OAI ETHERNET transport - Release 14" ./archives/red_hat/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_usrp_rh_row4.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row5.html summary_table_footer fi diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index e481936345..63cd3f831f 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -377,7 +377,7 @@ function report_test { fi PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` - if [[ $PERF_INT -lt 80 ]] + if [[ $PERF_INT -lt 70 ]] then echo " KO" >> ./test_simulator_results.html else diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 27687d2660..8d2c5cda06 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -228,6 +228,7 @@ function check_iperf { local LOC_REQ_BW=$2 local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l` + local LOC_REQ_BW_MINUS_THREE=`echo "$LOC_REQ_BW - 3" | bc -l` local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` if [ -f ${LOC_BASE_LOG}_client.txt ] @@ -240,7 +241,7 @@ function check_iperf { local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] then - if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*Mbits.* ]] + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_THREE}.*Mbits.* ]] then echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" else @@ -959,10 +960,10 @@ function run_test_on_vm { echo "Iperf DL" echo "############################################################" CURR_IPERF_LOG_BASE=fdd_20MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 12 $CURR_IPERF_LOG_BASE scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 12 echo "############################################################" echo "Terminate enb/ue simulators"