Commit d9ec978c authored by kaltenbe's avatar kaltenbe

Merge remote-tracking branch 'origin/develop' into enhancement-74-SoDeRa

Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/build_oai
	targets/ARCH/COMMON/common_lib.c
	targets/ARCH/COMMON/common_lib.h
	targets/RT/USER/lte-softmodem.c
parents 7998985d f65b478c
...@@ -20,9 +20,11 @@ job1: ...@@ -20,9 +20,11 @@ job1:
- EXTERNAL_SHARE_RESULTS_DIR=$EXTERNAL_SHARE_DIR/$git_branch/$git_head - EXTERNAL_SHARE_RESULTS_DIR=$EXTERNAL_SHARE_DIR/$git_branch/$git_head
- echo $NFS_TEST_RESULTS_DIR - echo $NFS_TEST_RESULTS_DIR
- echo $EXTERNAL_SHARE_RESULTS_DIR - echo $EXTERNAL_SHARE_RESULTS_DIR
- echo $NRUNS_LTE_SOFTMODEM
- echo $TIMEOUT_CMD
- mkdir -p $OPENAIR_DIR/cmake_targets/autotests/log - mkdir -p $OPENAIR_DIR/cmake_targets/autotests/log
- python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -c -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS $OAI_EXTRA_ARGS -g "$OAI_TEST_CASE_GROUP">& $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log - python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -c -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS $OAI_EXTRA_ARGS -g "$OAI_TEST_CASE_GROUP">& $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log
- python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -r -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS `echo $OAI_EXTRA_ARGS` -g "$OAI_TEST_CASE_GROUP" >& $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log - python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -r -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS `echo $OAI_EXTRA_ARGS` -g "$OAI_TEST_CASE_GROUP" --nrun_lte_softmodem $NRUNS_LTE_SOFTMODEM --timeout_cmd $TIMEOUT_CMD >& $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log
- mv $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log $OPENAIR_DIR/cmake_targets/autotests/log/python_autotest.log - mv $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log $OPENAIR_DIR/cmake_targets/autotests/log/python_autotest.log
- mv $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log $OPENAIR_DIR/cmake_targets/autotests/log/python_autotest_cleanup.log - mv $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log $OPENAIR_DIR/cmake_targets/autotests/log/python_autotest_cleanup.log
- sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no " --rsync-path="mkdir -p $NFS_TEST_RESULTS_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$NFS_TEST_RESULTS_DIR - sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no " --rsync-path="mkdir -p $NFS_TEST_RESULTS_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$NFS_TEST_RESULTS_DIR
......
...@@ -161,6 +161,11 @@ set(CMAKE_C_FLAGS ...@@ -161,6 +161,11 @@ set(CMAKE_C_FLAGS
set(CMAKE_CXX_FLAGS set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 " "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 "
) )
#########################
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${OPENAIR_TARGETS}/bin")
#########################
# set a flag for changes in the source code # set a flag for changes in the source code
# these changes are related to hardcoded path to include .h files # these changes are related to hardcoded path to include .h files
add_definitions(-DCMAKER) add_definitions(-DCMAKER)
...@@ -245,6 +250,9 @@ endif (${RTAI}) ...@@ -245,6 +250,9 @@ endif (${RTAI})
set(asn1c_call "${OPENAIR_CMAKE}/tools/generate_asn1") set(asn1c_call "${OPENAIR_CMAKE}/tools/generate_asn1")
set(asn1_generated_dir ${OPENAIR_BIN_DIR}) set(asn1_generated_dir ${OPENAIR_BIN_DIR})
set(protoc_call "${OPENAIR_CMAKE}/tools/generate_protobuf")
set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
# RRC # RRC
###### ######
add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA") add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA")
...@@ -405,10 +413,55 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4 ...@@ -405,10 +413,55 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4
add_list1_option(NB_ANTENNAS_TX "2" "Number of antennas in transmission" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "2" "Number of antennas in transmission" "1" "2" "4")
add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4") add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4")
add_list2_option(RF_BOARD "EXMIMO" "RF head type" "False" "EXMIMO" "OAI_USRP" "ETHERNET" "OAI_BLADERF" "OAI_LMSSDR" "CPRIGW") add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR")
Message("RF_BOARD is ${RF_BOARD}") add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
# include RF devices / transport protocols library modules
######################################################################
include_directories("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
#set (option_HWEXMIMOLIB_lib "-l ")
set(HWLIB_EXMIMO_SOURCE
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
)
add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
set (option_HWUSRPLIB_lib "-l uhd")
set(HWLIB_USRP_SOURCE
${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
)
add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/")
set (option_HWBLADERFLIB_lib "-l bladerf")
set(HWLIB_BLADERF_SOURCE
${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
)
add_library(oai_bladerfdevif MODULE ${HWLIB_BLADERF_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/")
set (option_HWLMSSDRLIB_lib "-l LMS_SDR -l LMS7002M -l Si5351C")
set(HWLIB_LMSSDR_SOURCE
${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp
)
add_library(oai_lmssdrdevif MODULE ${HWLIB_LMSSDR_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/")
set(TPLIB_ETHERNET_SOURCE
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
)
add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
# RF devices / transport protocols settings
######################################################################
if (${RF_BOARD} STREQUAL "EXMIMO") if (${RF_BOARD} STREQUAL "EXMIMO")
set(DRIVER2013) set(DRIVER2013)
include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/") include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
...@@ -416,6 +469,7 @@ if (${RF_BOARD} STREQUAL "EXMIMO") ...@@ -416,6 +469,7 @@ if (${RF_BOARD} STREQUAL "EXMIMO")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c) ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c)
set(option_HW_lib "-rdynamic -ldl")
elseif (${RF_BOARD} STREQUAL "OAI_USRP") elseif (${RF_BOARD} STREQUAL "OAI_USRP")
include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
...@@ -423,8 +477,7 @@ elseif (${RF_BOARD} STREQUAL "OAI_USRP") ...@@ -423,8 +477,7 @@ elseif (${RF_BOARD} STREQUAL "OAI_USRP")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp) ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp)
LINK_DIRECTORIES("/opt/lib") LINK_DIRECTORIES("/opt/lib")
set(option_HW_lib "uhd") set(option_HW_lib "-luhd -rdynamic -ldl")
#set(LOWLATENCY False)
elseif (${RF_BOARD} STREQUAL "OAI_BLADERF") elseif (${RF_BOARD} STREQUAL "OAI_BLADERF")
include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/") include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/")
...@@ -434,7 +487,8 @@ elseif (${RF_BOARD} STREQUAL "OAI_BLADERF") ...@@ -434,7 +487,8 @@ elseif (${RF_BOARD} STREQUAL "OAI_BLADERF")
${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
) )
LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu")
set(option_HW_lib "bladeRF")
set(option_HW_lib "bladeRF -rdynamic -ldl")
#set(LOWLATENCY False) #set(LOWLATENCY False)
elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR") elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR")
...@@ -443,20 +497,13 @@ elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR") ...@@ -443,20 +497,13 @@ elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR")
include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms7002m") include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms7002m")
include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/Si5351C") include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/Si5351C")
include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/LMS_StreamBoard") include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/LMS_StreamBoard")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp
)
LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu")
LINK_DIRECTORIES("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/build")
LINK_DIRECTORIES("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms7002m/build")
LINK_DIRECTORIES("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/Si5351C/build")
set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp) set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp)
set(LIB_LMS_LIBRARIES "${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lmsSDR/build/libLMS_SDR.so" "${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms7002m/build/libLMS7002M.a" "${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/Si5351C/build/libSi5351C.a")
set(LOWLATENCY False) set(LOWLATENCY False)
set(option_HW_lib "-lLMS_SDR -lLMS7002M -lSi5351C -rdynamic -ldl")
elseif (${RF_BOARD} STREQUAL "ETHERNET")
include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
)
#set(LOWLATENCY True)
elseif (${RF_BOARD} STREQUAL "CPRIGW") elseif (${RF_BOARD} STREQUAL "CPRIGW")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
...@@ -464,8 +511,24 @@ elseif (${RF_BOARD} STREQUAL "CPRIGW") ...@@ -464,8 +511,24 @@ elseif (${RF_BOARD} STREQUAL "CPRIGW")
) )
include_directories("${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/") include_directories("${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/")
set(option_HW_lib "-rdynamic dl") set(option_HW_lib "-rdynamic dl")
endif (${RF_BOARD} STREQUAL "EXMIMO") endif (${RF_BOARD} STREQUAL "EXMIMO")
if (${TRANSP_PRO} STREQUAL "ETHERNET")
include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
set(TRANSPORT_SOURCE ${TRANSPORT_SOURCE}
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
)
set(option_TP_lib "-rdynamic -ldl")
endif (${TRANSP_PRO} STREQUAL "ETHERNET")
##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
Message("LOWLATENCY flag is ${LOWLATENCY}") Message("LOWLATENCY flag is ${LOWLATENCY}")
...@@ -491,6 +554,9 @@ add_list_string_option(PACKAGE_NAME "NotDefined" "As per attribute name") ...@@ -491,6 +554,9 @@ add_list_string_option(PACKAGE_NAME "NotDefined" "As per attribute name")
add_boolean_option(MESSAGE_CHART_GENERATOR False "For generating sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR False "For generating sequence diagrams")
add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams")
add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchanges in sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchanges in sequence diagrams")
add_boolean_option(ENB_AGENT True "enable eNB agent to inteface with a SDN contrller")
######################## ########################
# Include order # Include order
########################## ##########################
...@@ -1420,10 +1486,11 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) ...@@ -1420,10 +1486,11 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
################################# #################################
# add executables for operation # add executables for operation
#################################"" #################################
# lte-softmodem is both eNB and UE implementation # lte-softmodem is both eNB and UE implementation
################################################### ###################################################
add_executable(lte-softmodem add_executable(lte-softmodem
${rrc_h} ${rrc_h}
${s1ap_h} ${s1ap_h}
...@@ -1441,6 +1508,7 @@ add_executable(lte-softmodem ...@@ -1441,6 +1508,7 @@ add_executable(lte-softmodem
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${GTPU_need_ITTI} ${GTPU_need_ITTI}
${HW_SOURCE} ${HW_SOURCE}
${TRANSPORT_SOURCE}
${RTAI_SOURCE} ${RTAI_SOURCE}
${XFORMS_SOURCE} ${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_SOURCE_SOFTMODEM}
...@@ -1453,7 +1521,7 @@ target_link_libraries (lte-softmodem ...@@ -1453,7 +1521,7 @@ target_link_libraries (lte-softmodem
target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${XFORMS_LIBRARIES} ) target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} )
target_link_libraries (lte-softmodem ${LIBBOOST_LIBRARIES}) target_link_libraries (lte-softmodem ${LIBBOOST_LIBRARIES})
target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
...@@ -1476,6 +1544,7 @@ add_executable(lte-softmodem-nos1 ...@@ -1476,6 +1544,7 @@ add_executable(lte-softmodem-nos1
#${OPENAIR2_DIR}/RRC/NAS/rb_config.c #${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${HW_SOURCE} ${HW_SOURCE}
${TRANSPORT_SOURCE}
${RTAI_SOURCE} ${RTAI_SOURCE}
${XFORMS_SOURCE} ${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_SOURCE_SOFTMODEM}
...@@ -1486,38 +1555,36 @@ target_link_libraries (lte-softmodem-nos1 ...@@ -1486,38 +1555,36 @@ target_link_libraries (lte-softmodem-nos1
-Wl,--end-group ) -Wl,--end-group )
target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES})
target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} ${XFORMS_LIBRARIES} ) target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} )
target_link_libraries (lte-softmodem-nos1 ${LIBBOOST_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIBBOOST_LIBRARIES})
# rrh # rrh
################################ ################################
set(DRIVER2013) #Note: only one RF type (USRP) is currently supported for RRH
#Note: only on RF type is currently supported for RRH
add_executable(rrh_gw add_executable(rrh_gw
${OPENAIR_TARGETS}/RT/USER/rrh_gw.c ${OPENAIR_TARGETS}/RT/USER/rrh_gw.c
${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c ${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c ${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${HW_SOURCE} ${HW_SOURCE}
${TRANSPORT_SOURCE}
) )
# assert and common_lib.h # assert
target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti ${OPENAIR_TARGETS}/ARCH/COMMON ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ ) target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti)
target_link_libraries(rrh_gw target_link_libraries(rrh_gw
-Wl,--start-group -Wl,--start-group
UTIL LFDS UTIL LFDS
-Wl,--end-group ) -Wl,--end-group )
target_link_libraries (rrh_gw rt pthread m ) target_link_libraries (rrh_gw rt pthread m )
target_link_libraries (rrh_gw ${option_HW_lib} ${LIBBOOST_LIBRARIES} ) target_link_libraries (rrh_gw ${option_HW_lib} ${option_TP_lib} ${LIBBOOST_LIBRARIES} )
#Message("-- default_HW_lib=ETHERNET") # only in case of RRH
Message("-- option_HW_lib=${option_HW_lib}") Message("-- option_HW_lib=${option_HW_lib}")
Message("-- HW_SOURCE=${HW_SOURCE}") Message("-- HW_SOURCE=${HW_SOURCE}")
Message("-- option_TP_lib=${option_TP_lib}")
Message("-- TRANSPORT_SOURCE=${TRANSPORT_SOURCE}")
# USIM process # USIM process
################# #################
...@@ -1568,6 +1635,7 @@ add_executable(oaisim ...@@ -1568,6 +1635,7 @@ add_executable(oaisim
${GTPU_need_ITTI} ${GTPU_need_ITTI}
${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c
${HW_SOURCE} ${HW_SOURCE}
${TRANSPORT_SOURCE}
${XFORMS_SOURCE} ${XFORMS_SOURCE}
) )
...@@ -1579,7 +1647,7 @@ target_link_libraries (oaisim ...@@ -1579,7 +1647,7 @@ target_link_libraries (oaisim
-Wl,--end-group ) -Wl,--end-group )
target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib}
${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES})
#Force link with forms, regardless XFORMS option #Force link with forms, regardless XFORMS option
target_link_libraries (oaisim forms) target_link_libraries (oaisim forms)
...@@ -1606,6 +1674,7 @@ add_executable(oaisim_nos1 ...@@ -1606,6 +1674,7 @@ add_executable(oaisim_nos1
${OPENAIR2_DIR}/UTIL/OMG/sumo.c ${OPENAIR2_DIR}/UTIL/OMG/sumo.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c
${HW_SOURCE} ${HW_SOURCE}
${TRANSPORT_SOURCE}
${XFORMS_SOURCE} ${XFORMS_SOURCE}
) )
target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER)
...@@ -1615,7 +1684,7 @@ target_link_libraries (oaisim_nos1 ...@@ -1615,7 +1684,7 @@ target_link_libraries (oaisim_nos1
-Wl,--end-group ) -Wl,--end-group )
target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} ${option_TP_lib}
${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES})
#Force link with forms, regardless XFORMS option #Force link with forms, regardless XFORMS option
target_link_libraries (oaisim_nos1 forms) target_link_libraries (oaisim_nos1 forms)
......
...@@ -137,7 +137,13 @@ Obj.# Case# Test# Description ...@@ -137,7 +137,13 @@ Obj.# Case# Test# Description
01 59 lte-softmodem tests with USRP X310 RF as eNB and OAI EPC (eNB and EPC are on same machines) w/ Bandrich COTS UE 01 59 lte-softmodem tests with USRP X310 RF as eNB and OAI EPC (eNB and EPC are on same machines) w/ Bandrich COTS UE
01 61 lte-softmodem tests with USRP X310 RF as eNB and OAI EPC (eNB and EPC are on different machines) w/ Bandrich COTS UE 01 60 lte-softmodem tests with USRP X310 RF as eNB and OAI EPC (eNB and EPC are on different machines) w/ Bandrich COTS UE
01 60 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX
01 60 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX
01 60 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX
01 60 03 Band 7 FDD 5MHz DL Throughput for 300 sec for 1TX/1RX
01 60 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX
01 60 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX
01 61 lte-softmodem tests with EXMIMO RF as eNB and ALU EPC w/ Bandrich COTS UE for `TX/1RX, 2TX/2RX 01 61 lte-softmodem tests with EXMIMO RF as eNB and ALU EPC w/ Bandrich COTS UE for `TX/1RX, 2TX/2RX
01 61 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 61 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX
...@@ -148,7 +154,22 @@ Obj.# Case# Test# Description ...@@ -148,7 +154,22 @@ Obj.# Case# Test# Description
01 61 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX 01 61 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX
01 62 lte-softmodem tests with EXMIMO RF as eNB and OAI EPC (eNB and EPC are on same machines) w/ Bandrich COTS UE 01 62 lte-softmodem tests with EXMIMO RF as eNB and OAI EPC (eNB and EPC are on same machines) w/ Bandrich COTS UE
01 63 lte-softmodem tests with EXMIMO RF as eNB and OAI EPC (eNB and EPC are on different machines) w/ Bandrich COTS UE 01 63 lte-softmodem tests with EXMIMO RF as eNB and OAI EPC (eNB and EPC are on different machines) w/ Bandrich COTS UE
01 63 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX
01 63 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX
01 63 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX
01 63 03 Band 7 FDD 5MHz DL Throughput for 300 sec for 1TX/1RX
01 63 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX
01 63 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX
01 65 00 lte-softmodem tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX
01 65 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX
01 65 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX
01 65 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX
01 65 03 Band 7 FDD 5MHz DL Throughput for 300 sec for 1TX/1RX
01 65 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX
01 65 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX
01 64 lte-softmodem-noS1 tests 01 64 lte-softmodem-noS1 tests
......
...@@ -175,6 +175,7 @@ function test_compile() { ...@@ -175,6 +175,7 @@ function test_compile() {
#\param $13 -> output of compilation program that needs to be found for test case to pass #\param $13 -> output of compilation program that needs to be found for test case to pass
#\param $14 -> tags to help identify the test case for readability in output xml file #\param $14 -> tags to help identify the test case for readability in output xml file
#\param $15 => password for the user to run certain commands as sudo #\param $15 => password for the user to run certain commands as sudo
#\param $16 => test config file params to be modified
function test_compile_and_run() { function test_compile_and_run() {
xUnit_start xUnit_start
...@@ -195,12 +196,14 @@ function test_compile_and_run() { ...@@ -195,12 +196,14 @@ function test_compile_and_run() {
compile_prog_out=${13} compile_prog_out=${13}
tags=${14} tags=${14}
mypassword=${15} mypassword=${15}
test_config_file=${16}
build_dir=$tdir/$1/build build_dir=$tdir/$1/build
#exec_file=$build_dir/$6 #exec_file=$build_dir/$6
xmlfile_testcase=$log_dir/test.$1.xml xmlfile_testcase=$log_dir/test.$1.xml
#Temporary log file where execution log is stored. #Temporary log file where execution log is stored.
temp_exec_log=$log_dir/temp_log.txt temp_exec_log=$log_dir/temp_log.txt
export OPENAIR_LOGDIR=$log_dir
rm -fr $log_dir rm -fr $log_dir
mkdir -p $log_dir mkdir -p $log_dir
...@@ -220,6 +223,10 @@ function test_compile_and_run() { ...@@ -220,6 +223,10 @@ function test_compile_and_run() {
#compile_prog_array=() #compile_prog_array=()
#read -a compile_prog_array <<<"$compile_prog" #read -a compile_prog_array <<<"$compile_prog"
#test_config_file=`eval "echo \"$test_config_file\" "`
#echo "test_config_file = $test_config_file"
tags_array=() tags_array=()
read -a tags_array <<<"$tags" read -a tags_array <<<"$tags"
...@@ -238,10 +245,14 @@ function test_compile_and_run() { ...@@ -238,10 +245,14 @@ function test_compile_and_run() {
cd $log_dir cd $log_dir
{ {
uname -a uname -a
#eval $pre_compile_prog echo "Executing $pre_compile_prog"
#cmake .. eval $pre_compile_prog
#rm -fv $exec_file
echo "Executing $compile_prog $compile_args" >> $log_file if [ "$test_config_file" != "" ]; then
echo "Modifying test_config_file parameters..."
echo "$test_config_file" |xargs -L 1 $OPENAIR_DIR/cmake_targets/autotests/tools/search_repl.py
fi
echo "Executing $compile_prog $compile_args"
eval "$compile_prog $compile_args" eval "$compile_prog $compile_args"
echo "Copying compilation log files to test case log directory: $log_dir" echo "Copying compilation log files to test case log directory: $log_dir"
cp -fvr $OPENAIR_DIR/cmake_targets/log/ $log_dir/compile_log cp -fvr $OPENAIR_DIR/cmake_targets/log/ $log_dir/compile_log
...@@ -438,6 +449,7 @@ for search_expr in "${test_case_array[@]}" ...@@ -438,6 +449,7 @@ for search_expr in "${test_case_array[@]}"
flag_run_test_case=1 flag_run_test_case=1
fi fi
#We skip this test case if it is not in the group list #We skip this test case if it is not in the group list
if [ "$flag_run_test_case" -ne "1" ]; then if [ "$flag_run_test_case" -ne "1" ]; then
continue continue
...@@ -458,6 +470,7 @@ for search_expr in "${test_case_array[@]}" ...@@ -458,6 +470,7 @@ for search_expr in "${test_case_array[@]}"
nruns=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/nruns" $xml_conf` nruns=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/nruns" $xml_conf`
compile_prog_out=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/compile_prog_out" $xml_conf` compile_prog_out=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/compile_prog_out" $xml_conf`
tags=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/tags" $xml_conf` tags=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/tags" $xml_conf`
test_config_file=`xmlstarlet sel -t -v "/testCaseList/testCase[@id='$search_expr']/test_config_file" $xml_conf`
echo "class = $class" echo "class = $class"
echo "name = $name" echo "name = $name"
...@@ -497,7 +510,7 @@ for search_expr in "${test_case_array[@]}" ...@@ -497,7 +510,7 @@ for search_expr in "${test_case_array[@]}"
test_compile "$name" "$compile_prog" "$compile_prog_args" "$pre_exec" "$pre_exec_args" "$main_exec" "$main_exec_args" "search_array_true[@]" "$search_expr_false" "$nruns" "$pre_compile_prog" "$class" "$compile_prog_out" "$tags" test_compile "$name" "$compile_prog" "$compile_prog_args" "$pre_exec" "$pre_exec_args" "$main_exec" "$main_exec_args" "search_array_true[@]" "$search_expr_false" "$nruns" "$pre_compile_prog" "$class" "$compile_prog_out" "$tags"
elif [ "$class" == "execution" ]; then elif [ "$class" == "execution" ]; then
$SUDO killall -q oaisim_nos1 $SUDO killall -q oaisim_nos1
test_compile_and_run "$name" "$compile_prog" "$compile_prog_args" "$pre_exec" "$pre_exec_args" "$main_exec" "$main_exec_args" "search_array_true[@]" "$search_expr_false" "$nruns" "$pre_compile_prog" "$class" "$compile_prog_out" "$tags" "$mypassword" test_compile_and_run "$name" "$compile_prog" "$compile_prog_args" "$pre_exec" "$pre_exec_args" "$main_exec" "$main_exec_args" "search_array_true[@]" "$search_expr_false" "$nruns" "$pre_compile_prog" "$class" "$compile_prog_out" "$tags" "$mypassword" "$test_config_file"
else else
echo "Unexpected class of test case...Skipping the test case $name ...." echo "Unexpected class of test case...Skipping the test case $name ...."
fi fi
......
...@@ -60,7 +60,9 @@ import paramiko ...@@ -60,7 +60,9 @@ import paramiko
import subprocess import subprocess
import commands import commands
sys.path.append('/opt/ssh') sys.path.append('/opt/ssh')
sys.path.append(os.path.expandvars('$OPENAIR_DIR/cmake_targets/autotests/tools/'))
from lib_autotest import *
import ssh import ssh
from ssh import SSHSession from ssh import SSHSession
import argparse import argparse
...@@ -1015,6 +1017,8 @@ class oaiCleanOldProgramThread (threading.Thread): ...@@ -1015,6 +1017,8 @@ class oaiCleanOldProgramThread (threading.Thread):
error = error + '\n threadID = ' + str(self.threadID) + '\n threadname = ' + self.threadname + '\n CleanUpOldProgs = ' + self.CleanUpOldProgs + '\n CleanUpAluLteBox = ' + self.CleanUpAluLteBox + '\n ExmimoRfStop = ' + self.ExmimoRfStop + '\n' error = error + '\n threadID = ' + str(self.threadID) + '\n threadname = ' + self.threadname + '\n CleanUpOldProgs = ' + self.CleanUpOldProgs + '\n CleanUpAluLteBox = ' + self.CleanUpAluLteBox + '\n ExmimoRfStop = ' + self.ExmimoRfStop + '\n'
error = error + traceback.format_exc() error = error + traceback.format_exc()
print error print error
print "There is error in cleaning up old programs. The test case execution cannot continue...."
sys.exit(1)
# \brief Run parallel threads in all machines for clean up old execution of test cases # \brief Run parallel threads in all machines for clean up old execution of test cases
# \param oai_list list of handlers that can be used to execute programs on remote machines # \param oai_list list of handlers that can be used to execute programs on remote machines
...@@ -1282,18 +1286,17 @@ if localshell == 0: ...@@ -1282,18 +1286,17 @@ if localshell == 0:
print '\nCleaning Older running programs : ' + CleanUpOldProgs print '\nCleaning Older running programs : ' + CleanUpOldProgs
cleanOldPrograms(oai_list[index], CleanUpOldProgs, CleanUpAluLteBox, ExmimoRfStop) cleanOldPrograms(oai_list[index], CleanUpOldProgs, CleanUpAluLteBox, ExmimoRfStop)
result = oai_list[index].send('mount ' + NFSResultsDir, True) #result = oai_list[index].send('mount ' + NFSResultsDir, True)
print "Mounting NFS Share " + NFSResultsDir + "..." + result #print "Mounting NFS Share " + NFSResultsDir + "..." + result
# Check if NFS share is mounted correctly. # Check if NFS share is mounted correctly.
print 'Checking if NFS Share<' + NFSResultsDir + '> is mounted correctly...' #print 'Checking if NFS Share<' + NFSResultsDir + '> is mounted correctly...'
#result = oai_list[index].send_expect('mount | grep ' + NFSResultsDir, NFSResultsDir ) #cmd = 'if grep -qs '+NFSResultsDir+ ' /proc/mounts; then echo \'' + NFSResultsDir + ' is mounted\' ; fi'
cmd = 'if grep -qs '+NFSResultsDir+ ' /proc/mounts; then echo \'' + NFSResultsDir + ' is mounted\' ; fi' #search_expr = NFSResultsDir + ' is mounted'
search_expr = NFSResultsDir + ' is mounted' #print "cmd = " + cmd
print "cmd = " + cmd #print "search_expr = " + search_expr
print "search_expr = " + search_expr #result = oai_list[index].send_expect(cmd, search_expr)
result = oai_list[index].send_expect(cmd, search_expr) #print "Mount NFS_Results_Dir..." + result
print "Mount NFS_Results_Dir..." + result
index = index + 1 index = index + 1
#oai.connect2(user,pw) #oai.connect2(user,pw)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -21,6 +21,10 @@ if openair_dir == None: ...@@ -21,6 +21,10 @@ if openair_dir == None:
print "Error getting OPENAIR_DIR environment variable" print "Error getting OPENAIR_DIR environment variable"
sys.exit(1) sys.exit(1)
sys.path.append(os.path.expandvars('$OPENAIR_DIR/cmake_targets/autotests/tools/'))
from lib_autotest import *
def find_open_port(): def find_open_port():
global serial_port, ser global serial_port, ser
max_ports=100 max_ports=100
...@@ -159,34 +163,11 @@ def reset_ue(): ...@@ -159,34 +163,11 @@ def reset_ue():
VendorId=res[0][2] VendorId=res[0][2]
ProductId=res[0][3] ProductId=res[0][3]
usb_dir= find_usb_path(VendorId, ProductId) usb_dir= find_usb_path(VendorId, ProductId)
print usb_dir print "Bandrich 4G LTE Adapter found in..." + usb_dir
cmd = "sudo sh -c \"echo 0 > " + usb_dir + "/authorized\"" cmd = "sudo sh -c \"echo 0 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 5" ) os.system(cmd + " ; sleep 15" )
cmd = "sudo sh -c \"echo 1 > " + usb_dir + "/authorized\"" cmd = "sudo sh -c \"echo 1 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 5" ) os.system(cmd + " ; sleep 30" )
def read_file(filename):
try:
file = open(filename, 'r')
return file.read()
except Exception, e:
#error = ' Filename ' + filename
#error = error + ' In function: ' + sys._getframe().f_code.co_name + ': *** Caught exception: ' + str(e.__class__) + " : " + str( e)
#error = error + traceback.format_exc()
#print error
return ''
def find_usb_path(idVendor, idProduct):
for root, dirs, files in os.walk("/sys/bus/usb/devices", topdown=False):
for name in dirs:
tmpdir= os.path.join(root, name)
tmpidVendor = read_file(tmpdir+'/idVendor').replace("\n","")
tmpidProduct = read_file(tmpdir+'/idProduct').replace("\n","")
#print "tmpdir = " + tmpdir + " tmpidVendor = " + tmpidVendor + " tmpidProduct = " + tmpidProduct
if tmpidVendor == idVendor and tmpidProduct == idProduct:
return tmpdir
return ''
i=1 i=1
gw='192.172.0.1' gw='192.172.0.1'
......
#!/usr/bin/python
import os
from pyroute2 import IPRoute
import sys
import re
import threading
import signal
import traceback
import commands
def read_file(filename):
try:
file = open(filename, 'r')
return file.read()
except Exception, e:
# WE just ignore the exception as some files are probably not present
#error = ' Filename ' + filename
#error = error + ' In function: ' + sys._getframe().f_code.co_name + ': *** Caught exception: ' + str(e.__class__) + " : " + str( e)
#error = error + traceback.format_exc()
#print error
return ''
def find_usb_path(idVendor, idProduct):
for root, dirs, files in os.walk("/sys/bus/usb/devices", topdown=False):
for name in dirs:
tmpdir= os.path.join(root, name)
tmpidVendor = read_file(tmpdir+'/idVendor').replace("\n","")
tmpidProduct = read_file(tmpdir+'/idProduct').replace("\n","")
if tmpidVendor == idVendor and tmpidProduct == idProduct:
return tmpdir
return ''
#!/usr/bin/python #!/usr/bin/python
import sys import sys
import re import re
import os
#Arg 1 name of file #Arg 1 name of file
#Arg 2 keyword #Arg 2 keyword
#arg 3 replacement text #arg 3 replacement text
#Note that these should be seperated by spaces #Note that these should be seperated by spaces
if len(sys.argv) != 4: if len(sys.argv) != 4:
print "search_repl.py: Wrong number of arguments. This program needs 3 arguments" print "search_repl.py: Wrong number of arguments. This program needs 3 arguments. The number of arguments supplied : " + str(sys.argv)
sys.exit() sys.exit()
filename = sys.argv[1] filename = os.path.expandvars(sys.argv[1])
keyword = sys.argv[2] keyword = sys.argv[2]
replacement_text = sys.argv[3] replacement_text = sys.argv[3]
file = open(filename, 'r') file = open(filename, 'r')
string = file.read() string = file.read()
file.close() file.close()
......
...@@ -49,13 +49,14 @@ LOWLATENCY_FLAG_USER="False" ...@@ -49,13 +49,14 @@ LOWLATENCY_FLAG_USER="False"
FORCE_LOWLATENCY_FLAG_USER="" FORCE_LOWLATENCY_FLAG_USER=""
REL="Rel10" REL="Rel10"
HW="EXMIMO" HW="EXMIMO"
TP="None"
NOS1=0 NOS1=0
EPC=0 EPC=0
VERBOSE_COMPILE=0 VERBOSE_COMPILE=0
CFLAGS_PROCESSOR_USER="" CFLAGS_PROCESSOR_USER=""
RUN_GROUP=0 RUN_GROUP=0
TEST_CASE_GROUP="" TEST_CASE_GROUP=""
BUILD_DOXYGEN=0
trap handle_ctrl_c INT trap handle_ctrl_c INT
function print_help() { function print_help() {
...@@ -90,10 +91,13 @@ Options ...@@ -90,10 +91,13 @@ Options
default is Rel10, default is Rel10,
Rel8 limits the implementation to 3GPP Release 8 version Rel8 limits the implementation to 3GPP Release 8 version
-w | --hardware -w | --hardware
EXMIMO (Default), USRP, BLADERF, LMSSDR, ETHERNET, None EXMIMO (Default), USRP, BLADERF, LMSSDR, None
Adds this RF board support (in external packages installation and in compilation) Adds this RF board support (in external packages installation and in compilation)
-t | --transport protocol
ETHERNET , None
Adds this trasport protocol support in compilation
--oaisim --oaisim
Makes the oaisim simulator. Hardware will be defaulted to "NONE". Makes the oaisim simulator. Hardware will be defaulted to "None".
--phy_simulators --phy_simulators
Makes the unitary tests Layer 1 simulators Makes the unitary tests Layer 1 simulators
--core_simulators --core_simulators
...@@ -115,6 +119,8 @@ Options ...@@ -115,6 +119,8 @@ Options
Shows detailed compilation instructions in makefile Shows detailed compilation instructions in makefile
--cflags_processor --cflags_processor
Manually Add CFLAGS of processor if they are not detected correctly by script. Only add these flags if you know your processor supports them. Example flags: -msse3 -msse4.1 -msse4.2 -mavx2 Manually Add CFLAGS of processor if they are not detected correctly by script. Only add these flags if you know your processor supports them. Example flags: -msse3 -msse4.1 -msse4.2 -mavx2
--build-doxygen
Builds doxygen based documentation.
--disable-deadline --disable-deadline
Disables deadline scheduler of Linux kernel (>=3.14.x). Disables deadline scheduler of Linux kernel (>=3.14.x).
--enable-deadline --enable-deadline
...@@ -170,11 +176,14 @@ function main() { ...@@ -170,11 +176,14 @@ function main() {
shift;; shift;;
-r | --3gpp-release) -r | --3gpp-release)
REL=$2 REL=$2
echo_info "setting release to: $REL" echo_info "Setting release to: $REL"
shift 2;; shift 2;;
-w | --hardware) -w | --hardware)
HW="$2" #"${i#*=}" HW="$2" #"${i#*=}"
# Use OAI_USRP as the key word USRP is used inside UHD driver # 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" ] ; then
echo_fatal "Unknown HW type $HW will exit..."
else
if [ "$HW" == "USRP" ] ; then if [ "$HW" == "USRP" ] ; then
HW="OAI_USRP" HW="OAI_USRP"
fi fi
...@@ -184,7 +193,16 @@ function main() { ...@@ -184,7 +193,16 @@ function main() {
if [ "$HW" == "LMSSDR" ] ; then if [ "$HW" == "LMSSDR" ] ; then
HW="OAI_LMSSDR" HW="OAI_LMSSDR"
fi fi
echo_info "setting hardware to: $HW" echo_info "Setting hardware to: $HW"
fi
shift 2;;
-t | --transport_protocol)
TP="$2" #"${i#*=}"
if [ "$TP" != "ETHERNET" -a "$TP" != "None" ] ; then
echo_fatal "Unknown TP type $TP will exit..."
else
echo_info "Setting transport protocol to: $TP"
fi
shift 2;; shift 2;;
--oaisim) --oaisim)
oaisim=1 oaisim=1
...@@ -208,7 +226,7 @@ function main() { ...@@ -208,7 +226,7 @@ function main() {
echo_info "executing test cases only in group: $TEST_CASE_GROUP" echo_info "executing test cases only in group: $TEST_CASE_GROUP"
shift 2;; shift 2;;
-V | --vcd) -V | --vcd)
echo_info "setting gtk-wave output" echo_info "Setting gtk-wave output"
VCD_TIMING=1 VCD_TIMING=1
EXE_ARGUMENTS="$EXE_ARGUMENTS -V" EXE_ARGUMENTS="$EXE_ARGUMENTS -V"
shift;; shift;;
...@@ -231,8 +249,12 @@ function main() { ...@@ -231,8 +249,12 @@ function main() {
shift;; shift;;
--cflags_processor) --cflags_processor)
CFLAGS_PROCESSOR_USER=$2 CFLAGS_PROCESSOR_USER=$2
echo_info "setting CPU FLAGS from USER to: $CFLAGS_PROCESSOR_USER" echo_info "Setting CPU FLAGS from USER to: $CFLAGS_PROCESSOR_USER"
shift 2;; shift 2;;
--build-doxygen)
BUILD_DOXYGEN=1
echo_info "Will build doxygen support"
shift;;
--disable-deadline) --disable-deadline)
FORCE_LOWLATENCY_FLAG_USER="False" FORCE_LOWLATENCY_FLAG_USER="False"
echo_info "Disabling the usage of deadline scheduler" echo_info "Disabling the usage of deadline scheduler"
...@@ -241,7 +263,6 @@ function main() { ...@@ -241,7 +263,6 @@ function main() {
FORCE_LOWLATENCY_FLAG_USER="True" FORCE_LOWLATENCY_FLAG_USER="True"
echo_info "Enabling the usage of deadline scheduler" echo_info "Enabling the usage of deadline scheduler"
shift 1;; shift 1;;
-h | --help) -h | --help)
print_help print_help
exit 1;; exit 1;;
...@@ -252,6 +273,35 @@ function main() { ...@@ -252,6 +273,35 @@ function main() {
esac esac
done done
#########################################################
# check validity of HW and TP parameters for RRH and 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" -a "$TP" != "None" ] ; then
echo_fatal "Currently eNB can not support simultaniously local and remote radio heads!!"
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
if [ "$RRH" = "1" ] ; then
if [ "$TP" = "None" ] ; then
echo_fatal "A transport protocol (e.g. -t ETHERNET) must be defined!"
fi
if [ "$HW" = "None" ] ; then
echo_info "No radio head has been selected (HW set to $HW)"
fi
fi
echo_info "RF HW set to $HW" echo_info "RF HW set to $HW"
#Now we set flags to enable deadline scheduler settings #Now we set flags to enable deadline scheduler settings
#By default: USRP: disable, #By default: USRP: disable,
...@@ -280,6 +330,7 @@ function main() { ...@@ -280,6 +330,7 @@ function main() {
echo_info "Flags for Deadline scheduler: $LOWLATENCY_FLAG_USER" echo_info "Flags for Deadline scheduler: $LOWLATENCY_FLAG_USER"
############################################ ############################################
# setting and printing OAI envs, we should check here # setting and printing OAI envs, we should check here
############################################ ############################################
...@@ -318,7 +369,7 @@ function main() { ...@@ -318,7 +369,7 @@ function main() {
check_install_usrp_uhd_driver check_install_usrp_uhd_driver
fi fi
if [ "$HW" == "OAI_BLADERF" ] ; then if [ "$HW" == "OAI_BLADERF" ] ; then
echo_info "installing packages for BALDERF support" echo_info "installing packages for BLADERF support"
check_install_bladerf_driver check_install_bladerf_driver
fi fi
fi fi
...@@ -329,9 +380,11 @@ function main() { ...@@ -329,9 +380,11 @@ function main() {
fi fi
if [ "$oaisim" = "1" ] ; then if [ "$oaisim" = "1" ] ; then
if [ "$HW" != "ETHERNET" ] ; then #to be discussed
HW="NONE" # there is no RF device and no transport protocol
fi HW="None"
TP="None"
if [ "$XFORMS" == "True" ] ; then if [ "$XFORMS" == "True" ] ; then
PRINT_STATS="True" PRINT_STATS="True"
fi fi
...@@ -365,6 +418,7 @@ function main() { ...@@ -365,6 +418,7 @@ function main() {
echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file
echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file
echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file
echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file
echo "set(PACKAGE_NAME \"${lte_exec}\")" >> $cmake_file echo "set(PACKAGE_NAME \"${lte_exec}\")" >> $cmake_file
echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
...@@ -571,32 +625,123 @@ function main() { ...@@ -571,32 +625,123 @@ function main() {
fi fi
# RRH compilation # RRH compilation
################## #####################
if [ "$RRH" = "1" ] ; then if [ "$RRH" = "1" ] ; then
echo_info "Compiling RRH"
if [ $HW == "ETHERNET" ] ; then rrh_exec=rrh_gw
echo_info "RF frontend for RRH is not defined. This mode is used for testing (loopback)." rrh_build_dir=rrh_gw
elif [ $HW != "EXMIMO" -a $HW != "OAI_USRP" -a $HW != "OAI_BLADERF" ] ; then
echo_fatal "Hardware not defined ($HW)" echo_info "Compiling $rrh_exec ..."
fi
cmake_file=$DIR/rrh_gw/CMakeLists.txt [ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build
mkdir -p $DIR/$rrh_build_dir/build
cmake_file=$DIR/$rrh_build_dir/CMakeLists.txt
echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file
echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file
echo "set(ENABLE_ITTI False )" >> $cmake_file echo "set(ENABLE_ITTI False )" >> $cmake_file
echo "set(RF_BOARD \"${HW}\")" >> $cmake_file echo "set(RF_BOARD \"${HW}\")" >> $cmake_file
echo "set(TRANSP_PRO \"${TP}\")" >> $cmake_file
echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file
echo "set(LOWLATENCY \"${LOWLATENCY_FLAG_USER}\")" >>$cmake_file echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
cd $DIR/$rrh_build_dir/build
[ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build
mkdir -p $DIR/rrh_gw/build
cd $DIR/rrh_gw/build
cmake .. cmake ..
compilations \ compilations \
rrh_gw rrh_gw \ rrh_gw rrh_gw \
rrh_gw $dbin/rrh_gw rrh_gw $dbin/rrh_gw
fi
# build RF device and transport protocol libraries
#####################################
if [ "$eNB" = "1" -o "$RRH" = "1" ] ; then
if [ "$eNB" = "1" ] ; then
build_dir=$lte_build_dir
else
build_dir=$rrh_build_dir
fi
# build RF device libraries (currently EXMIMO is not complied with the rest of HW targets)
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
#add exmimo compilation
#TODO EXMIMO library support
echo_info "liboai_device.so is linked to EXMIMO device library"
elif [ "$HW" == "OAI_USRP" ] ; then
if [ -d "/usr/include/uhd" ] ; then
compilations \
$build_dir oai_usrpdevif \
liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
fi
ln -s liboai_usrpdevif.so liboai_device.so
ln -s $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 fi
ln -s liboai_bladerfdevif.so liboai_device.so
ln -s $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 -s liboai_lmssdrdevif.so liboai_device.so
ln -s $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to LMSSDR 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 -s liboai_eth_transpro.so liboai_transpro.so
ln -s $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
echo_info "liboai_transpro.so is linked with ETHERNET library"
fi
fi
fi
# Doxygen Support
#####################
if [ "$BUILD_DOXYGEN" = "1" ] ;then
doxygen_log=$OPENAIR_DIR/cmake_targets/log/doxygen.log
echo_info "Building doxygen based documentation. The documentation file is located here: $OPENAIR_DIR/targets/DOCS/html/index.html"
echo_info "Doxygen Generation log is located here: $doxygen_log"
echo_info "Generating doxygen files....please wait"
(
[ "$CLEAN" = "1" ] && rm -rf $OPENAIR_DIR/cmake_targets/doxygen/build
mkdir -p $OPENAIR_DIR/cmake_targets/doxygen/build
cd $OPENAIR_DIR/cmake_targets/doxygen/build
cmake ..
make doc
) >& $doxygen_log
fi
# Auto-tests # Auto-tests
##################### #####################
......
...@@ -180,7 +180,7 @@ check_install_bladerf_driver(){ ...@@ -180,7 +180,7 @@ check_install_bladerf_driver(){
$SUDO apt-get install -y bladerf libbladerf-dev $SUDO apt-get install -y bladerf libbladerf-dev
$SUDO apt-get install -y bladerf-firmware-fx3 $SUDO apt-get install -y bladerf-firmware-fx3
$SUDO apt-get install -y bladerf-fpga-hostedx40 $SUDO apt-get install -y bladerf-fpga-hostedx40
bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img
} }
check_install_additional_tools (){ check_install_additional_tools (){
......
#!/usr/bin/python
import time
import serial
import os
from pyroute2 import IPRoute
import sys
import re
import threading
import signal
import traceback
import commands
if os.environ.get('OPENAIR_DIR') == None:
print "Error getting OPENAIR_DIR environment variable"
sys.exit(1)
sys.path.append(os.path.expandvars('$OPENAIR_DIR/cmake_targets/autotests/tools/'))
from lib_autotest import *
def reset_bladerf():
stringIdBladeRF='OpenMoko, Inc'
status, out = commands.getstatusoutput('lsusb | grep -i \'' + stringIdBladeRF + '\'')
if (out == '') :
print "BladeRF not found. Exiting now..."
sys.exit()
p=re.compile('Bus\s*(\w+)\s*Device\s*(\w+):\s*ID\s*(\w+):(\w+)')
res=p.findall(out)
BusId=res[0][0]
DeviceId=res[0][1]
VendorId=res[0][2]
ProductId=res[0][3]
usb_dir= find_usb_path(VendorId, ProductId)
print "BladeRF Found in directory..." + usb_dir
cmd = "sudo sh -c \"echo 0 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 5" )
cmd = "sudo sh -c \"echo 1 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 5" )
os.system ('sudo -E bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img')
print "Resettting BladeRF..."
reset_bladerf()
os.system ("dmesg|tail")
...@@ -1077,7 +1077,7 @@ int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB, ...@@ -1077,7 +1077,7 @@ int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB,
} }
if (UE_id==NB_UE_INST) { if (UE_id==NB_UE_INST) {
LOG_E(PHY,"rx_pucch_emul: FATAL, didn't find UE with rnti %x\n",rnti); LOG_W(PHY,"rx_pucch_emul: Didn't find UE with rnti %x\n",rnti);
return(-1); return(-1);
} }
......
...@@ -76,6 +76,13 @@ ...@@ -76,6 +76,13 @@
#define openair_free(y,x) free((y)) #define openair_free(y,x) free((y))
#define PAGE_SIZE 4096 #define PAGE_SIZE 4096
//#ifdef SHRLIBDEV
//extern int rxrescale;
//#define RX_IQRESCALELEN rxrescale
//#else
//#define RX_IQRESCALELEN 15
//#endif
//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards. //! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards.
//! If no more memory is available, this function will terminate the program with an assertion error. //! If no more memory is available, this function will terminate the program with an assertion error.
static inline void* malloc16_clear( size_t size ) static inline void* malloc16_clear( size_t size )
......
...@@ -44,7 +44,14 @@ ...@@ -44,7 +44,14 @@
/** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation /** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation
* @{ * @{
* @defgroup _PHY_RF_INTERFACE_ Generic PHY - RF Interface * @defgroup _PHY_RF_INTERFACE_ PHY - RF Interface
* @ingroup _PHY_RF_INTERFACE_
* @{
* @defgroup _GENERIC_PHY_RF_INTERFACE_ Generic PHY - RF Interface
* @defgroup _USRP_PHY_RF_INTERFACE_ PHY - USRP RF Interface
* @defgroup _BLADERF_PHY_RF_INTERFACE_ PHY - BLADERF RF Interface
* @}
*
* @ingroup _ref_implementation_ * @ingroup _ref_implementation_
* @{ * @{
* This module is responsible for defining the generic interface between PHY and RF Target * This module is responsible for defining the generic interface between PHY and RF Target
......
...@@ -170,6 +170,14 @@ ...@@ -170,6 +170,14 @@
#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U"
#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U"
#define ENB_CONFIG_STRING_RRH_GW_CONFIG "rrh_gw_config"
#define ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME "local_if_name"
#define ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS "local_address"
#define ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS "remote_address"
#define ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT "local_port"
#define ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT "remote_port"
#define ENB_CONFIG_STRING_RRH_GW_ACTIVE "active"
#define ENB_CONFIG_STRING_RRH_GW_PREFERENCE "preference"
#define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity" #define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
#define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none" #define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none"
...@@ -275,6 +283,18 @@ static void enb_config_display(void) ...@@ -275,6 +283,18 @@ static void enb_config_display(void)
printf( "\tMNC: \t%02"PRIu16":\n",enb_properties.properties[i]->mnc); printf( "\tMNC: \t%02"PRIu16":\n",enb_properties.properties[i]->mnc);
} }
for (j=0; j< enb_properties.properties[i]->nb_rrh_gw; j++) {
if (enb_properties.properties[i]->rrh_gw_config[j].active == 1 ){
printf( "\n\tRRH GW %d config for eNB %u:\n\n", j, i);
printf( "\tinterface name : \t%s:\n",enb_properties.properties[i]->rrh_gw_if_name);
printf( "\tlocal address : \t%s:\n",enb_properties.properties[i]->rrh_gw_config[j].local_address);
printf( "\tlocal port : \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].local_port);
printf( "\tremote address : \t%s:\n",enb_properties.properties[i]->rrh_gw_config[j].remote_address);
printf( "\tremote port : \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].remote_port);
printf( "\ttransport : \t%s Ethernet:\n\n",(enb_properties.properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : "UDP");
}
}
for (j=0; j< enb_properties.properties[i]->nb_cc; j++) { for (j=0; j< enb_properties.properties[i]->nb_cc; j++) {
printf( "\teutra band for CC %d: \t%"PRId16":\n",j,enb_properties.properties[i]->eutra_band[j]); printf( "\teutra band for CC %d: \t%"PRId16":\n",j,enb_properties.properties[i]->eutra_band[j]);
printf( "\tdownlink freq for CC %d: \t%"PRIu64":\n",j,enb_properties.properties[i]->downlink_frequency[j]); printf( "\tdownlink freq for CC %d: \t%"PRIu64":\n",j,enb_properties.properties[i]->downlink_frequency[j]);
...@@ -455,6 +475,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) ...@@ -455,6 +475,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
config_setting_t *setting_srb1 = NULL; config_setting_t *setting_srb1 = NULL;
config_setting_t *setting_mme_addresses = NULL; config_setting_t *setting_mme_addresses = NULL;
config_setting_t *setting_mme_address = NULL; config_setting_t *setting_mme_address = NULL;
config_setting_t *setting_rrh_gws = NULL;
config_setting_t *setting_rrh_gw = NULL;
config_setting_t *setting_enb = NULL; config_setting_t *setting_enb = NULL;
config_setting_t *setting_otg = NULL; config_setting_t *setting_otg = NULL;
config_setting_t *subsetting_otg = NULL; config_setting_t *subsetting_otg = NULL;
...@@ -462,6 +484,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) ...@@ -462,6 +484,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
int enb_properties_index = 0; int enb_properties_index = 0;
int num_enbs = 0; int num_enbs = 0;
int num_mme_address = 0; int num_mme_address = 0;
int num_rrh_gw = 0;
int num_otg_elements =0; int num_otg_elements =0;
int num_component_carriers =0; int num_component_carriers =0;
int i = 0; int i = 0;
...@@ -558,10 +581,15 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) ...@@ -558,10 +581,15 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
libconfig_int my_int; libconfig_int my_int;
char* if_name = NULL;
char* ipv4 = NULL; char* ipv4 = NULL;
char* ipv4_remote = NULL;
char* ipv6 = NULL; char* ipv6 = NULL;
char* active = NULL; char* active = NULL;
char* preference = NULL; char* preference = NULL;
libconfig_int local_port = 0;
libconfig_int remote_port = 0;
const char* active_enb[MAX_ENB]; const char* active_enb[MAX_ENB];
char* enb_interface_name_for_S1U = NULL; char* enb_interface_name_for_S1U = NULL;
char* enb_ipv4_address_for_S1U = NULL; char* enb_ipv4_address_for_S1U = NULL;
...@@ -2136,6 +2164,63 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) ...@@ -2136,6 +2164,63 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
} }
} }
// RRH Config
setting_rrh_gws = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_RRH_GW_CONFIG);
if ( setting_rrh_gws != NULL) {
num_rrh_gw = config_setting_length(setting_rrh_gws);
enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;
for (j = 0; j < num_rrh_gw; j++) {
setting_rrh_gw = config_setting_get_elem(setting_rrh_gws, j);
if ( !(
config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME, (const char **)&if_name)
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS, (const char **)&ipv4)
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS , (const char **)&ipv4_remote)
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT, &local_port)
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT, &remote_port)
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_ACTIVE, (const char **)&active)
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_PREFERENCE, (const char **)&preference)
)
) {
AssertError (0, parse_errors ++,
"Failed to parse eNB configuration file %s, %u th enb %u the RRH GW address !\n",
lib_config_file_name_pP, i, j);
continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
}
enb_properties.properties[enb_properties_index]->nb_rrh_gw += 1;
enb_properties.properties[enb_properties_index]->rrh_gw_if_name = strdup(if_name);
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address = strdup(ipv4);
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = strdup(ipv4_remote);
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port= local_port;
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port= remote_port;
if (strcmp(active, "yes") == 0) {
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 1;
}
if (strcmp(preference, "udp") == 0) {
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
} else if (strcmp(preference, "raw") == 0) {
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
} else {//if (strcmp(preference, "no") == 0)
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
}
}
} else {
enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;
enb_properties.properties[enb_properties_index]->rrh_gw_if_name = "none";
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address = "0.0.0.0";
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = "0.0.0.0";
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port= 0;
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port= 0;
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 0;
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 0;
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 0;
}
// SCTP SETTING // SCTP SETTING
enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS; enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS;
......
...@@ -78,6 +78,17 @@ typedef struct mme_ip_address_s { ...@@ -78,6 +78,17 @@ typedef struct mme_ip_address_s {
char *ipv6_address; char *ipv6_address;
} mme_ip_address_t; } mme_ip_address_t;
typedef struct rrh_gw_config_s {
unsigned udp:1;
unsigned raw:1;
unsigned active:1;
char *local_address;
char *remote_address;
uint16_t local_port;
uint16_t remote_port;
} rrh_gw_config_t;
typedef struct Enb_properties_s { typedef struct Enb_properties_s {
/* Unique eNB_id to identify the eNB within EPC. /* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long. * For macro eNB ids this field should be 20 bits long.
...@@ -203,6 +214,13 @@ typedef struct Enb_properties_s { ...@@ -203,6 +214,13 @@ typedef struct Enb_properties_s {
char *enb_interface_name_for_S1_MME; char *enb_interface_name_for_S1_MME;
in_addr_t enb_ipv4_address_for_S1_MME; in_addr_t enb_ipv4_address_for_S1_MME;
/* Nb of RRH to connect to */
uint8_t nb_rrh_gw;
char *rrh_gw_if_name;
/* List of MME to connect to */
rrh_gw_config_t rrh_gw_config[4];
// otg config // otg config
/* Nb of OTG elements */ /* Nb of OTG elements */
uint8_t num_otg_elements; uint8_t num_otg_elements;
......
...@@ -1101,8 +1101,9 @@ boolean_t CCE_allocation_infeasible(int module_idP, ...@@ -1101,8 +1101,9 @@ boolean_t CCE_allocation_infeasible(int module_idP,
DCI_pdu->Num_ue_spec_dci++; DCI_pdu->Num_ue_spec_dci++;
ret = allocate_CCEs(module_idP,CC_idP,subframe,1); ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
if (ret==-1) if (ret==-1)
res = FALSE; res = TRUE;
DCI_pdu->Num_ue_spec_dci--; DCI_pdu->Num_ue_spec_dci--;
} }
return(res);
} }
...@@ -106,6 +106,9 @@ const char* eurecomVariablesNames[] = { ...@@ -106,6 +106,9 @@ const char* eurecomVariablesNames[] = {
"lhw_cnt_tx", "lhw_cnt_tx",
"pck_rx", "pck_rx",
"pck_tx", "pck_tx",
"rx_seq_num",
"rx_seq_num_prv",
"tx_seq_num",
"cnt", "cnt",
"dummy_dump", "dummy_dump",
"itti_send_msg", "itti_send_msg",
......
...@@ -78,6 +78,9 @@ typedef enum { ...@@ -78,6 +78,9 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT, VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK, VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,
VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,
VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM,
VCD_SIGNAL_DUMPER_VARIABLES_CNT, VCD_SIGNAL_DUMPER_VARIABLES_CNT,
VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP, VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG, VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
......
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
#include <inttypes.h> #include <inttypes.h>
#include "bladerf_lib.h" #include "bladerf_lib.h"
/** @addtogroup _BLADERF_PHY_RF_INTERFACE_
* @{
*/
//! Number of BladeRF devices
#ifdef __SSE4_1__ #ifdef __SSE4_1__
# include <smmintrin.h> # include <smmintrin.h>
#endif #endif
...@@ -47,13 +52,21 @@ ...@@ -47,13 +52,21 @@
#endif #endif
int num_devices=0; int num_devices=0;
/*These items configure the underlying asynch stream used by the the sync interface. /*These items configure the underlying asynch stream used by the the sync interface.
*/ */
int trx_brf_init(openair0_device *openair0) { /*! \brief BladeRF Init function (not used at the moment)
* \param device RF frontend parameters set by application
*/
int trx_brf_init(openair0_device *device) {
} }
/*! \brief get current timestamp
*\param device the hardware to use
*\param module the bladeRf module
*/
openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module) { openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module) {
int status; int status;
...@@ -69,17 +82,29 @@ openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module mod ...@@ -69,17 +82,29 @@ openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module mod
return meta.timestamp; return meta.timestamp;
} }
/*! \brief Start BladeRF
int trx_brf_start(openair0_device *openair0) { *\param device the hardware to use
*/
int trx_brf_start(openair0_device *device) {
return 0; return 0;
} }
/*! \brief Get BladeRF stats
*\param device the hardware to use
*/
static void trx_brf_stats(openair0_device *device){ static void trx_brf_stats(openair0_device *device){
} }
/*! \brief Called to send samples to the BladeRF 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 buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param cc index of the component carrier
*/
static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc) { static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc) {
int status; int status;
...@@ -121,6 +146,16 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, ...@@ -121,6 +146,16 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp,
return(0); return(0);
} }
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
* the first channel. *ptimestamp is the time at which the first sample
* was received.
* \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param cc Index of component carrier
*/
static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
int status=0; int status=0;
...@@ -157,6 +192,9 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, ...@@ -157,6 +192,9 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
} }
/*! \brief Terminate operation of the BladeRF transceiver -- free all associated resources
* \param device the hardware to use
*/
int trx_brf_end(openair0_device *device) { int trx_brf_end(openair0_device *device) {
int status; int status;
...@@ -172,25 +210,39 @@ int trx_brf_end(openair0_device *device) { ...@@ -172,25 +210,39 @@ int trx_brf_end(openair0_device *device) {
return 0; return 0;
} }
/*! \brief print the BladeRF statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_brf_get_stats(openair0_device* device) { int trx_brf_get_stats(openair0_device* device) {
return(0); return(0);
} }
/*! \brief Reset the BladeRF statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_brf_reset_stats(openair0_device* device) { int trx_brf_reset_stats(openair0_device* device) {
return(0); return(0);
} }
/*! \brief Stop USRP
* \param device the hardware to use
*/
int trx_brf_stop(openair0_device* device) { int trx_brf_stop(openair0_device* device) {
return(0); return(0);
} }
/*! \brief Set frequencies (TX/RX)
* \param device the hardware to use
* \returns 0 in success
*/
int trx_brf_set_freq(openair0_device* device) { int trx_brf_set_freq(openair0_device* device) {
int status; int status;
...@@ -213,12 +265,19 @@ int trx_brf_set_freq(openair0_device* device) { ...@@ -213,12 +265,19 @@ int trx_brf_set_freq(openair0_device* device) {
return(0); return(0);
} }
/*! \brief Set Gains (TX/RX)
* \param device the hardware to use
* \returns 0 in success
*/
int trx_brf_set_gains(openair0_device* device) { int trx_brf_set_gains(openair0_device* device) {
return(0); return(0);
} }
#define RXDCLENGTH 16384 #define RXDCLENGTH 16384
int16_t cos_fsover8[8] = {2047, 1447, 0, -1448, -2047, -1448, 0, 1447}; int16_t cos_fsover8[8] = {2047, 1447, 0, -1448, -2047, -1448, 0, 1447};
int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, -1448}; int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, -1448};
...@@ -822,15 +881,23 @@ void calibrate_rf(openair0_device *device) { ...@@ -822,15 +881,23 @@ void calibrate_rf(openair0_device *device) {
// write_output("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1); // write_output("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1);
} }
int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) { /*! \brief Initialize Openair BLADERF target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
int status; int status;
int card=0; int card=0;
brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t)); brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t));
memset(brf, 0, sizeof(brf_state_t)); memset(brf, 0, sizeof(brf_state_t));
// init required params /* device specific */
openair0_cfg->txlaunch_wait = 1;//manage when TX processing is triggered
openair0_cfg->txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
openair0_cfg->iq_txshift = 0;// shift
openair0_cfg->iq_rxrescale = 15;//rescale iqs
// init required params
switch ((int)openair0_cfg->sample_rate) { switch ((int)openair0_cfg->sample_rate) {
case 30720000: case 30720000:
openair0_cfg->samples_per_packet = 2048; openair0_cfg->samples_per_packet = 2048;
...@@ -857,7 +924,8 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai ...@@ -857,7 +924,8 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai
exit(-1); exit(-1);
break; break;
} }
openair0_cfg->iq_txshift= 0;
openair0_cfg->iq_rxrescale = 15; /*not sure*/
openair0_cfg->rx_gain_calib_table = calib_table_fx4; openair0_cfg->rx_gain_calib_table = calib_table_fx4;
// The number of buffers to use in the underlying data stream // The number of buffers to use in the underlying data stream
...@@ -1001,6 +1069,7 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai ...@@ -1001,6 +1069,7 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai
printf("BLADERF: Initializing openair0_device\n"); printf("BLADERF: Initializing openair0_device\n");
device->priv = brf; device->priv = brf;
device->Mod_id = num_devices++; device->Mod_id = num_devices++;
device->type = BLADERF_DEV;
device->trx_start_func = trx_brf_start; device->trx_start_func = trx_brf_start;
device->trx_end_func = trx_brf_end; device->trx_end_func = trx_brf_end;
device->trx_read_func = trx_brf_read; device->trx_read_func = trx_brf_read;
...@@ -1019,6 +1088,9 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai ...@@ -1019,6 +1088,9 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai
return 0; return 0;
} }
/*! \brief bladeRF error report
* \param status
*/
int brf_error(int status) { int brf_error(int status) {
//exit(-1); //exit(-1);
...@@ -1026,7 +1098,9 @@ int brf_error(int status) { ...@@ -1026,7 +1098,9 @@ int brf_error(int status) {
} }
/*! \brief Open BladeRF from serial port
* \param serial name of serial port on which to open BladeRF device
*/
struct bladerf * open_bladerf_from_serial(const char *serial) { struct bladerf * open_bladerf_from_serial(const char *serial) {
int status; int status;
...@@ -1053,6 +1127,10 @@ struct bladerf * open_bladerf_from_serial(const char *serial) { ...@@ -1053,6 +1127,10 @@ struct bladerf * open_bladerf_from_serial(const char *serial) {
return dev; return dev;
} }
} }
/*! \brief Get BladeRF log level
* \param log_level log level
*/
int get_brf_log_level(int log_level){ int get_brf_log_level(int log_level){
int level=BLADERF_LOG_LEVEL_INFO; int level=BLADERF_LOG_LEVEL_INFO;
...@@ -1081,3 +1159,4 @@ int get_brf_log_level(int log_level){ ...@@ -1081,3 +1159,4 @@ int get_brf_log_level(int log_level){
} }
return level; return level;
} }
/*@}*/
...@@ -37,45 +37,69 @@ ...@@ -37,45 +37,69 @@
#include "common_lib.h" #include "common_lib.h"
#include "log.h" #include "log.h"
/** @addtogroup _BLADERF_PHY_RF_INTERFACE_
* @{
*/
/*! \brief BladeRF specific data structure */
typedef struct { typedef struct {
// opaque BRF data struct //! opaque BladeRF device struct. An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
struct bladerf *dev; struct bladerf *dev;
// An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
//! Number of buffers
unsigned int num_buffers; unsigned int num_buffers;
//! Buffer size
unsigned int buffer_size; unsigned int buffer_size;
//! Number of transfers
unsigned int num_transfers; unsigned int num_transfers;
//! RX timeout
unsigned int rx_timeout_ms; unsigned int rx_timeout_ms;
//! TX timeout
unsigned int tx_timeout_ms; unsigned int tx_timeout_ms;
//! Metadata for RX
struct bladerf_metadata meta_rx; struct bladerf_metadata meta_rx;
//!Metadata for TX
struct bladerf_metadata meta_tx; struct bladerf_metadata meta_tx;
//! Sample rate
unsigned int sample_rate; unsigned int sample_rate;
// time offset between transmiter timestamp and receiver timestamp; //! time offset between transmiter timestamp and receiver timestamp;
double tdiff; double tdiff;
// use brf_time_offset to get this value //! TX number of forward samples use brf_time_offset to get this value
int tx_forward_nsamps; //166 for 20Mhz int tx_forward_nsamps; //166 for 20Mhz
// -------------------------------- // --------------------------------
// Debug and output control // Debug and output control
// -------------------------------- // --------------------------------
//! Number of underflows
int num_underflows; int num_underflows;
//! Number of overflows
int num_overflows; int num_overflows;
//! number of sequential errors
int num_seq_errors; int num_seq_errors;
//! number of RX errors
int num_rx_errors; int num_rx_errors;
//! Number of TX errors
int num_tx_errors; int num_tx_errors;
//! timestamp of current TX
uint64_t tx_current_ts; uint64_t tx_current_ts;
//! timestamp of current RX
uint64_t rx_current_ts; uint64_t rx_current_ts;
//! number of actual samples transmitted
uint64_t tx_actual_nsamps; uint64_t tx_actual_nsamps;
//! number of actual samples received
uint64_t rx_actual_nsamps; uint64_t rx_actual_nsamps;
//! number of TX samples
uint64_t tx_nsamps; uint64_t tx_nsamps;
//! number of RX samples
uint64_t rx_nsamps; uint64_t rx_nsamps;
//! number of TX count
uint64_t tx_count; uint64_t tx_count;
//! number of RX count
uint64_t rx_count; uint64_t rx_count;
//! timestamp of RX packet
openair0_timestamp rx_timestamp; openair0_timestamp rx_timestamp;
} brf_state_t; } brf_state_t;
...@@ -84,3 +108,4 @@ typedef struct { ...@@ -84,3 +108,4 @@ typedef struct {
*/ */
int brf_error(int status); int brf_error(int status);
/*@}*/
...@@ -37,40 +37,140 @@ ...@@ -37,40 +37,140 @@
* \warning * \warning
*/ */
#include <stdio.h> #include <stdio.h>
#include <strings.h>
#include <dlfcn.h>
#include <errno.h>
#include <string.h>
#include "common_lib.h" #include "common_lib.h"
int set_device(openair0_device *device) {
switch (device->type) {
case EXMIMO_DEV:
printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
case USRP_B200_DEV:
printf("[%s] has loaded USRP B200 device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
case USRP_X300_DEV:
printf("[%s] has loaded USRP X300 device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
case BLADERF_DEV:
printf("[%s] has loaded BLADERF device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
case LMSSDR_DEV:
printf("[%s] has loaded LMSSDR device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
case NONE_DEV:
printf("[%s] has not loaded a HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
break;
default:
printf("[%s] invalid HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
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 == BBU_HOST) ? "BBU": "RRH"));
return 0;
break;
case NONE_TP:
printf("[%s] has not loaded a transport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
return 0;
break;
default:
printf("[%s] invalid transport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
return -1;
break;
}
}
/* 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) {
void *lib_handle;
oai_device_initfunc_t dp ;
oai_transport_initfunc_t tp ;
if (flag == BBU_LOCAL_RADIO_HEAD) {
lib_handle = dlopen(OAI_RF_LIBNAME, RTLD_LAZY);
if (!lib_handle) {
printf( "Unable to locate %s: HW device set to NONE_DEV.\n", OAI_RF_LIBNAME);
return 0;
}
dp = dlsym(lib_handle,"device_init");
if (dp != NULL ) {
dp(device,openair0_cfg);
} else {
fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror());
return -1;
}
} else {
lib_handle = dlopen(OAI_TP_LIBNAME, RTLD_LAZY);
if (!lib_handle) {
printf( "Unable to locate %s: transport protocol set to NONE_TP.\n", OAI_TP_LIBNAME);
return 0;
}
tp = dlsym(lib_handle,"transport_init");
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) { if (tp != NULL ) {
tp(device,openair0_cfg,cfg);
#ifdef ETHERNET } else {
device->type=ETH_IF; fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror());
device->func_type = BBU_FUNC; return -1;
printf(" openair0_dev_init_eth ...\n"); }
return(openair0_dev_init_eth(device, openair0_cfg)); }
#elif EXMIMO
device->type=EXMIMO_IF;
printf("openair0_dev_init_exmimo...\n");
return(openair0_dev_init_exmimo(device, openair0_cfg));
#elif OAI_USRP
device->type=USRP_B200_IF;
openair0_dev_init_usrp(device, openair0_cfg);
printf("openair0_dev_init_usrp ...\n");
return(openair0_dev_init_usrp(device, openair0_cfg));
#elif OAI_BLADERF
device->type=BLADERF_IF;
printf("openair0_dev_init_bladerf ...\n");
return(openair0_dev_init_bladerf(device, openair0_cfg));
#elif OAI_LMSSDR
device->type=LMSSDR_IF;
printf("openair0_dev_init_lmssdr ...\n");
/*
if (openair0_cfg[0].configFilename==NULL) {
printf("Please provide a configuration file for SoDeRa\n");
exit(-1);
}*/
return(openair0_dev_init_lms(device, openair0_cfg));
#endif
return 0;
} }
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {
int rc;
//ToDo: EXMIMO harmonization is not complete. That is the reason for this ifdef
#ifdef EXMIMO
device_init(device, openair0_cfg);
#else
rc=load_lib(device, openair0_cfg, NULL,BBU_LOCAL_RADIO_HEAD );
if ( rc >= 0) {
if ( set_device(device) < 0) {
fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
return -1;
}
}
#endif
return 0;
}
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, BBU_REMOTE_RADIO_HEAD);
if ( rc >= 0) {
if ( set_transport(device) < 0) {
fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__);
return -1;
}
}
return 0;
}
...@@ -42,11 +42,20 @@ ...@@ -42,11 +42,20 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
/* name of shared library implementing the radio front end */
#define OAI_RF_LIBNAME "liboai_device.so"
/* name of shared library implementing the transport */
#define OAI_TP_LIBNAME "liboai_transpro.so"
/* flags for BBU to determine whether the attached radio head is local or remote */
#define BBU_LOCAL_RADIO_HEAD 0
#define BBU_REMOTE_RADIO_HEAD 1
typedef int64_t openair0_timestamp; typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp; typedef volatile int64_t openair0_vtimestamp;
/* structrue holds the parameters to configure USRP devices*/ /*!\brief structrue holds the parameters to configure USRP devices*/
typedef struct openair0_device_t openair0_device; typedef struct openair0_device_t openair0_device;
...@@ -65,10 +74,56 @@ typedef enum { ...@@ -65,10 +74,56 @@ typedef enum {
} duplex_mode_t; } duplex_mode_t;
/** @addtogroup _PHY_RF_INTERFACE_
/** @addtogroup _GENERIC_PHY_RF_INTERFACE_
* @{ * @{
*/ */
/*!\brief RF device types
*/
typedef enum {
MIN_RF_DEV_TYPE = 0,
/*!\brief device is ExpressMIMO */
EXMIMO_DEV,
/*!\brief device is USRP B200/B210*/
USRP_B200_DEV,
/*!\brief device is USRP X300/X310*/
USRP_X300_DEV,
/*!\brief device is BLADE RF*/
BLADERF_DEV,
/*!\brief device is LMSSDR (SoDeRa)*/
LMSSDR_DEV,
/*!\brief device is NONE*/
NONE_DEV,
MAX_RF_DEV_TYPE
} dev_type_t;
/*!\brief transport protocol types
*/
typedef enum {
MIN_TRANSP_TYPE = 0,
/*!\brief transport protocol ETHERNET */
ETHERNET_TP,
/*!\brief no transport protocol*/
NONE_TP,
MAX_TRANSP_TYPE
} transport_type_t;
/*!\brief openair0 device host type */
typedef enum {
MIN_HOST_TYPE = 0,
/*!\brief device functions within a BBU */
BBU_HOST,
/*!\brief device functions within a RRH */
RRH_HOST,
MAX_HOST_TYPE
}host_type_t;
/*! \brief RF Gain clibration */
typedef struct { typedef struct {
//! Frequency for which RX chain was calibrated //! Frequency for which RX chain was calibrated
double freq; double freq;
...@@ -76,10 +131,11 @@ typedef struct { ...@@ -76,10 +131,11 @@ typedef struct {
double offset; double offset;
} rx_gain_calib_table_t; } rx_gain_calib_table_t;
/*! \brief RF frontend parameters set by application */
typedef struct { typedef struct {
//! Module ID for this configuration //! Module ID for this configuration
int Mod_id; int Mod_id;
// device log level //! device log level
int log_level; int log_level;
//! duplexing mode //! duplexing mode
duplex_mode_t duplex_mode; duplex_mode_t duplex_mode;
...@@ -90,11 +146,15 @@ typedef struct { ...@@ -90,11 +146,15 @@ typedef struct {
//! the sample rate for both transmit and receive. //! the sample rate for both transmit and receive.
double sample_rate; double sample_rate;
//! number of samples per RX/TX packet (USRP + Ethernet) //! number of samples per RX/TX packet (USRP + Ethernet)
int samples_per_packet; unsigned int samples_per_packet;
//! delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist //! delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist
int tx_scheduling_advance; int tx_scheduling_advance;
//! offset in samples between TX and RX paths //! offset in samples between TX and RX paths
int tx_sample_advance; int tx_sample_advance;
//! configurable tx thread lauch delay
int txlaunch_wait; /* 1 or 0 */
//! configurable tx thread lauch delay
int txlaunch_wait_slotcount;
//! number of RX channels (=RX antennas) //! number of RX channels (=RX antennas)
int rx_num_channels; int rx_num_channels;
//! number of TX channels (=TX antennas) //! number of TX channels (=TX antennas)
...@@ -125,80 +185,64 @@ typedef struct { ...@@ -125,80 +185,64 @@ typedef struct {
double tx_bw; double tx_bw;
//! Auto calibration flag //! Auto calibration flag
int autocal[4]; int autocal[4];
//! RRH IP addr for Ethernet interface //! rf devices work with x bits iqs when oai have its own iq format
char *remote_ip; //! the two following parameters are used to convert iqs
//! RRH port number for Ethernet interface int iq_txshift;
int remote_port; int iq_rxrescale;
//! my IP addr for Ethernet interface (eNB/BBU, UE) //! remote IP/MAC addr for Ethernet interface
char *my_ip; char *remote_addr;
//! my port number for Ethernet interface (eNB/BBU, UE) //! remote port number for Ethernet interface
int my_port; unsigned int remote_port;
//! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
char *my_addr;
//! local port number for Ethernet interface (eNB/BBU, UE)
unsigned int my_port;
//! Configuration file for LMS7002M //! Configuration file for LMS7002M
char *configFilename; char *configFilename;
} openair0_config_t; } openair0_config_t;
/*! \brief RF mapping */
typedef struct { typedef struct {
/* card id */ //! card id
int card; int card;
/* rf chain id */ //! rf chain id
int chain; int chain;
} openair0_rf_map; } openair0_rf_map;
typedef struct {
/*!\brief interface types that apply to modules (RRH_BBU/RRH_UE) created in RRH (rrh_gw.c) char *remote_addr;
and are defined with respect to the RF device that is present in RRH //! remote port number for Ethernet interface
-RRH_BBU modules have two devices, one is by default ETHERNET (will have ETH_IF) and the other one is a unsigned int remote_port;
RF device (EXMIMO,USRP,BLADERF) or no device (NONE_IF). //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
-RRH_UE modules have two devices one is by default ETHERNET (will have ETH_IF) char *my_addr;
and the other one by default not present so it will have NONE_IF //! local port number for Ethernet interface (eNB/BBU, UE)
*/ unsigned int my_port;
typedef enum { //! local port number for Ethernet interface (eNB/BBU, UE)
MIN_DEV_TYPE = 0, char *local_if_name;
/*!\brief device is ETH */ //! local port number for Ethernet interface (eNB/BBU, UE)
ETH_IF, uint8_t transp_preference;
/*!\brief device is ExpressMIMO */ } eth_params_t;
EXMIMO_IF,
/*!\brief device is USRP B200/B210*/
USRP_B200_IF, /*!\brief structure holds the parameters to configure USRP devices */
/*!\brief device is USRP X300/X310*/
USRP_X300_IF,
/*!\brief device is BLADE RF*/
BLADERF_IF,
/*!\brief device is LMSSDR*/
LMSSDR_IF,
/*!\brief device is NONE*/
NONE_IF,
MAX_DEV_TYPE
} dev_type_t;
/*!\brief openair0 device host type */
typedef enum {
MIN_FUNC_TYPE = 0,
/*!\brief device functions within a BBU */
BBU_FUNC,
/*!\brief device functions within a RRH */
RRH_FUNC,
MAX_FUNC_TYPE
}func_type_t;
struct openair0_device_t { struct openair0_device_t {
/* Module ID of this device */ /*!brief Module ID of this device */
int Mod_id; int Mod_id;
/* Type of this device */ /*!brief Type of this device */
dev_type_t type; dev_type_t type;
/* Type of the device's host (BBU/RRH) */ /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */
func_type_t func_type; transport_type_t transp_type;
/* RF frontend parameters set by application */ /*!brief Type of the device's host (BBU/RRH) */
host_type_t host_type;
/* !brief RF frontend parameters set by application */
openair0_config_t *openair0_cfg; openair0_config_t *openair0_cfg;
/* Can be used by driver to hold internal structure*/ /*!brief Can be used by driver to hold internal structure*/
void *priv; void *priv;
/* Functions API, which are called by the application*/ /* Functions API, which are called by the application*/
...@@ -220,7 +264,7 @@ struct openair0_device_t { ...@@ -220,7 +264,7 @@ struct openair0_device_t {
@param msg pointer to the message structure passed between BBU-RRH @param msg pointer to the message structure passed between BBU-RRH
@param msg_len length of the message @param msg_len length of the message
*/ */
int (*trx_reply_func)(openair0_device *openair0, void *msg, ssize_t msg_len); int (*trx_reply_func)(openair0_device *device, void *msg, ssize_t msg_len);
/*! \brief Called to send samples to the RF target /*! \brief Called to send samples to the RF target
@param device pointer to the device structure specific to the RF hardware target @param device pointer to the device structure specific to the RF hardware target
...@@ -238,9 +282,9 @@ struct openair0_device_t { ...@@ -238,9 +282,9 @@ struct openair0_device_t {
* was received. * was received.
* \param device the hardware to use * \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received. * \param[out] ptimestamp the time at which the first sample was received.
* \param[out] An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps. * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param cc Number of channels. If cc == 1, only buff[0] is filled with samples. * \param antenna_id Index of antenna for which to receive samples
* \returns the number of sample read * \returns the number of sample read
*/ */
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id); int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
...@@ -257,50 +301,64 @@ struct openair0_device_t { ...@@ -257,50 +301,64 @@ struct openair0_device_t {
*/ */
int (*trx_reset_stats_func)(openair0_device *device); 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); void (*trx_end_func)(openair0_device *device);
/* Terminate operation */ /*! \brief Stop operation of the transceiver
* \param card RF Card to use
*/
int (*trx_stop_func)(int card); int (*trx_stop_func)(int card);
/* Functions API related to UE*/ /* Functions API related to UE*/
/*! \brief Set RX feaquencies /*! \brief Set RX feaquencies
* \param * \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 * \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 /*! \brief Set gains
* \param * \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);
}; };
/* 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);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif
/*! \brief Initialize Openair RF target. It returns 0 if OK */
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
//USRP /*! \brief Initialize openair RF target. It returns 0 if OK */
/*! \brief Get the current timestamp of USRP */ 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); openair0_timestamp get_usrp_time(openair0_device *device);
/*! \brief Set the RX frequency of USRP RF TARGET */
/*! \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); int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
//extern
/*! \brief Initialize Openair ETHERNET target. It returns 0 if OK */
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_dev_init_lms(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg);
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
......
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file ethernet_lib.c
* \brief API to stream I/Q samples over standard ethernet
* \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <errno.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#define DEBUG 0
struct sockaddr_ll dest_addr[MAX_INST];
struct sockaddr_ll local_addr[MAX_INST];
int addr_len[MAX_INST];
struct ifreq if_index[MAX_INST];
struct ether_header eh;
int eth_socket_init_raw(openair0_device *device) {
int i = 0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
const char *local_mac, *remote_mac;
int local_port=0, remote_port=0;
int sock_dom=0;
int sock_type=0;
int sock_proto=0;
if (device->host_type == RRH_HOST ) { /* RRH doesn't know remote MAC(will be retrieved from first packet send from BBU) and remote port(don't care) */
local_mac = device->openair0_cfg->my_addr;
local_port = device->openair0_cfg->my_port;
remote_mac = malloc(ETH_ALEN);
memset(remote_mac,0,ETH_ALEN);
remote_port = 0;
printf("[%s] local MAC addr %s remote MAC addr %s\n","RRH", local_mac,remote_mac);
} else {
local_mac = device->openair0_cfg->my_addr;
local_port = device->openair0_cfg->my_port;
remote_mac = device->openair0_cfg->remote_addr;
remote_port = device->openair0_cfg->remote_port;
printf("[%s] local MAC addr %s remote MAC addr %s\n","BBU", local_mac,remote_mac);
}
/* Open a RAW socket to send on */
sock_dom=AF_PACKET;
sock_type=SOCK_RAW;
sock_proto=IPPROTO_RAW;
if ((eth->sockfd[Mod_id] = socket(sock_dom, sock_type, sock_proto)) == -1) {
perror("ETHERNET: Error opening RAW socket");
exit(0);
}
/* initialize destination address */
for (i=0; i< MAX_INST; i++) {
bzero((void *)&(local_addr[i]), sizeof(struct sockaddr_ll));
bzero((void *)&(if_index[i]), sizeof(struct ifreq));
}
/* Get the index of the interface to send on */
strcpy(if_index[Mod_id].ifr_name,eth->if_name[Mod_id]);
if (ioctl(eth->sockfd[Mod_id], SIOCGIFINDEX, &(if_index[Mod_id])) < 0)
perror("SIOCGIFINDEX");
local_addr[Mod_id].sll_family = AF_PACKET;
local_addr[Mod_id].sll_ifindex = if_index[Mod_id].ifr_ifindex;
/* hear traffic from specific protocol*/
local_addr[Mod_id].sll_protocol = htons((short)device->openair0_cfg->my_port);
local_addr[Mod_id].sll_halen = ETH_ALEN;
local_addr[Mod_id].sll_pkttype = PACKET_OTHERHOST;
addr_len[Mod_id] = sizeof(struct sockaddr_ll);
if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&local_addr[Mod_id],addr_len[Mod_id])<0) {
perror("ETHERNET: Cannot bind to socket");
exit(0);
}
/* Construct the Ethernet header */
ether_aton_r(local_mac, (struct ether_addr *)(&(eh.ether_shost)));
ether_aton_r(remote_mac, (struct ether_addr *)(&(eh.ether_dhost)));
eh.ether_type = htons((short)device->openair0_cfg->my_port);
printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eh.ether_shost[0],eh.ether_shost[1],eh.ether_shost[2],eh.ether_shost[3],eh.ether_shost[4],eh.ether_shost[5]);
return 0;
}
int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int bytes_sent=0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
int sendto_flag =0;
int i=0;
//sendto_flag|=flags;
eth->tx_nsamps=nsamps;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in tx buffer where the payload to be sent is
buff2 points to the position in tx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES);
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
struct ether_header temp = *(struct ether_header *)buff2;
int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES);
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
bytes_sent = 0;
memcpy(buff2,(void*)&eh,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;
/*printf("[RRH]write mod_%d %d , len %d, buff %p \n",
Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/
while(bytes_sent < RAW_PACKET_SIZE_BYTES(nsamps)) {
#if DEBUG
printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n",
(void *)(buff2+bytes_sent),
RAW_PACKET_SIZE_BYTES(nsamps) - bytes_sent,
bytes_sent);
#endif
/* Send packet */
bytes_sent += send(eth->sockfd[Mod_id],
buff2,
RAW_PACKET_SIZE_BYTES(nsamps),
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 == BBU_HOST)? "BBU":"RRH", buff2, RAW_PACKET_SIZE_BYTES(nsamps), TX_FLAG);
#endif
eth->tx_actual_nsamps=bytes_sent>>2;
eth->tx_count++;
}
}
/* tx buffer values restored */
*(struct ether_header *)buff2 = temp;
*(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES) = temp0;
*(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = temp1;
}
return (bytes_sent-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES)>>2;
}
int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
int bytes_received=0;
int i=0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
int rcvfrom_flag =0;
eth->rx_nsamps=nsamps;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in rx buffer where the payload to be received will be placed
buff2 points to the position in rx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES);
/* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
struct ether_header temp = *(struct ether_header *)buff2;
int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES);
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
bytes_received=0;
while(bytes_received < RAW_PACKET_SIZE_BYTES(nsamps)) {
bytes_received +=recv(eth->sockfd[Mod_id],
buff2,
RAW_PACKET_SIZE_BYTES(nsamps),
rcvfrom_flag);
if (bytes_received ==-1) {
eth->num_rx_errors++;
perror("ETHERNET READ: ");
exit(-1);
} else {
/* store the timestamp value from packet's header */
*timestamp = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
eth->rx_actual_nsamps=bytes_received>>2;
eth->rx_count++;
}
}
#if DEBUG
printf("------- RX------: nu=%x an_id=%d ts%d bytes_recv=%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_received);
dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, RAW_PACKET_SIZE_BYTES(nsamps),RX_FLAG);
#endif
/* tx buffer values restored */
*(struct ether_header *)buff2 = temp;
*(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES) = temp0;
*(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = temp1;
}
return (bytes_received-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES)>>2;
}
int eth_set_dev_conf_raw(openair0_device *device) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
void *msg;
ssize_t msg_len;
/* a BBU client sends to RRH a set of configuration parameters (openair0_config_t)
so that RF front end is configured appropriately and
frame/packet size etc. can be set */
msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
memcpy(msg,(void*)&eh,MAC_HEADER_SIZE_BYTES);
memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t));
if (send(eth->sockfd[Mod_id],
msg,
msg_len,
0)==-1) {
perror("ETHERNET: ");
exit(0);
}
return 0;
}
int eth_get_dev_conf_raw(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str[INET_ADDRSTRLEN];
void *msg;
ssize_t msg_len;
msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
/* RRH receives from BBU openair0_config_t */
if (recv(eth->sockfd[Mod_id],
msg,
msg_len,
0)==-1) {
perror("ETHERNET: ");
exit(0);
}
/* RRH stores the remote MAC address */
memcpy(eh.ether_dhost,(msg+ETH_ALEN),ETH_ALEN);
//memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t));
device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES);
printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eh.ether_shost[0],eh.ether_shost[1],eh.ether_shost[2],eh.ether_shost[3],eh.ether_shost[4],eh.ether_shost[5],eh.ether_dhost[0],eh.ether_dhost[1],eh.ether_dhost[2],eh.ether_dhost[3],eh.ether_dhost[4],eh.ether_dhost[5]);
return 0;
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file ethernet_lib.c
* \brief API to stream I/Q samples over standard ethernet
* \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <errno.h>
#include "vcd_signal_dumper.h"
#include "common_lib.h"
#include "ethernet_lib.h"
#define DEBUG 0
struct sockaddr_in dest_addr[MAX_INST];
struct sockaddr_in local_addr[MAX_INST];
int addr_len[MAX_INST];
uint16_t pck_seq_num = 1;
uint16_t pck_seq_num_cur=0;
uint16_t pck_seq_num_prev=0;
int eth_socket_init_udp(openair0_device *device) {
int i = 0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str_local[INET_ADDRSTRLEN];
char str_remote[INET_ADDRSTRLEN];
const char *local_ip, *remote_ip;
int local_port=0, remote_port=0;
int sock_dom=0;
int sock_type=0;
int sock_proto=0;
int enable=1;
if (device->host_type == RRH_HOST ) {
local_ip = device->openair0_cfg->my_addr;
local_port = device->openair0_cfg->my_port;
remote_ip = "0.0.0.0";
remote_port = 0;
printf("[%s] local ip addr %s port %d\n", "RRH", local_ip, local_port);
} else {
local_ip = device->openair0_cfg->my_addr;
local_port = device->openair0_cfg->my_port;
remote_ip = device->openair0_cfg->remote_addr;
remote_port = device->openair0_cfg->remote_port;
printf("[%s] local ip addr %s port %d\n","BBU", local_ip, local_port);
}
/* Open socket to send on */
sock_dom=AF_INET;
sock_type=SOCK_DGRAM;
sock_proto=IPPROTO_UDP;
if ((eth->sockfd[Mod_id] = socket(sock_dom, sock_type, sock_proto)) == -1) {
perror("ETHERNET: Error opening socket");
exit(0);
}
/* initialize addresses */
for (i=0; i< MAX_INST; i++) {
bzero((void *)&(dest_addr[i]), sizeof(dest_addr[i]));
bzero((void *)&(local_addr[i]), sizeof(local_addr[i]));
}
addr_len[Mod_id] = sizeof(struct sockaddr_in);
dest_addr[Mod_id].sin_family = AF_INET;
inet_pton(AF_INET,remote_ip,&(dest_addr[Mod_id].sin_addr.s_addr));
dest_addr[Mod_id].sin_port=htons(remote_port);
inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str_remote, INET_ADDRSTRLEN);
local_addr[Mod_id].sin_family = AF_INET;
inet_pton(AF_INET,local_ip,&(local_addr[Mod_id].sin_addr.s_addr));
local_addr[Mod_id].sin_port=htons(local_port);
inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str_local, INET_ADDRSTRLEN);
/* set reuse address flag */
if (setsockopt(eth->sockfd[Mod_id], SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) {
perror("ETHERNET: Cannot set SO_REUSEADDR option on socket");
exit(0);
}
/* want to receive -> so bind */
if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&local_addr[Mod_id],addr_len[Mod_id])<0) {
perror("ETHERNET: Cannot bind to socket");
exit(0);
} else {
printf("[%s] binding mod_%d to %s:%d\n","RRH",Mod_id,str_local,ntohs(local_addr[Mod_id].sin_port));
}
return 0;
}
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int bytes_sent=0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
int sendto_flag =0;
int i=0;
//sendto_flag|=flags;
eth->tx_nsamps=nsamps;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in tx buffer where the payload to be sent is
buff2 points to the position in tx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES);
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
bytes_sent = 0;
/* constract application header */
// eth->pck_header.seq_num = pck_seq_num;
//eth->pck_header.antenna_id = 1+(i<<1);
//eth->pck_header.timestamp = timestamp;
*(uint16_t *)buff2 = pck_seq_num;
*(uint16_t *)(buff2 + sizeof(uint16_t)) = 1+(i<<1);
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, pck_seq_num);
while(bytes_sent < UDP_PACKET_SIZE_BYTES(nsamps)) {
#if DEBUG
printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n",
(void *)(buff2+bytes_sent),
UDP_PACKET_SIZE_BYTES(nsamps) - bytes_sent,
bytes_sent);
#endif
/* Send packet */
bytes_sent += sendto(eth->sockfd[Mod_id],
buff2,
UDP_PACKET_SIZE_BYTES(nsamps),
sendto_flag,
(struct sockaddr*)&dest_addr[Mod_id],
addr_len[Mod_id]);
if ( bytes_sent == -1) {
eth->num_tx_errors++;
perror("ETHERNET WRITE: ");
exit(-1);
} else {
#if DEBUG
printf("------- TX ------: nu=%d an_id=%d ts%d bytes_send=%d\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
bytes_sent);
dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, UDP_PACKET_SIZE_BYTES(nsamps), TX_FLAG);
#endif
eth->tx_actual_nsamps=bytes_sent>>2;
eth->tx_count++;
pck_seq_num++;
if ( pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,76800) ) pck_seq_num = 1;
}
}
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
}
return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2;
}
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
int bytes_received=0;
eth_state_t *eth = (eth_state_t*)device->priv;
openair0_timestamp prev_timestamp = -1;
int Mod_id = device->Mod_id;
int rcvfrom_flag =0;
int block_cnt=0;
int again_cnt=0;
int i=0;
eth->rx_nsamps=nsamps;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in rx buffer where the payload to be received will be placed
buff2 points to the position in rx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES);
/* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
bytes_received=0;
block_cnt=0;
while(bytes_received < UDP_PACKET_SIZE_BYTES(nsamps)) {
again:
#if DEBUG
printf("------- RX------: buff2 current position=%d remaining_bytes=%d bytes_recv=%d \n",
(void *)(buff2+bytes_received),
UDP_PACKET_SIZE_BYTES(nsamps) - bytes_received,
bytes_received);
#endif
bytes_received +=recvfrom(eth->sockfd[Mod_id],
buff2,
UDP_PACKET_SIZE_BYTES(nsamps),
rcvfrom_flag,
(struct sockaddr *)&dest_addr[Mod_id],
(socklen_t *)&addr_len[Mod_id]);
if (bytes_received ==-1) {
eth->num_rx_errors++;
if (errno == EAGAIN) {
again_cnt++;
usleep(10);
if (again_cnt == 1000) {
perror("ETHERNET READ: ");
exit(-1);
} else {
printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n");
goto again;
}
} else if (errno == EWOULDBLOCK) {
block_cnt++;
usleep(10);
if (block_cnt == 1000) {
perror("ETHERNET READ: ");
exit(-1);
} else {
printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
goto again;
}
}
} else {
#if DEBUG
printf("------- RX------: nu=%d an_id=%d ts%d bytes_recv=%d\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
bytes_received);
dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, UDP_PACKET_SIZE_BYTES(nsamps),RX_FLAG);
#endif
/* store the timestamp value from packet's header */
*timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
/* store the sequence number of the previous packet received */
if (pck_seq_num_cur == 0) {
pck_seq_num_prev = *(uint16_t *)buff2;
} else {
pck_seq_num_prev = pck_seq_num_cur;
}
/* get the packet sequence number from packet's header */
pck_seq_num_cur = *(uint16_t *)buff2;
//printf("cur=%d prev=%d buff=%d\n",pck_seq_num_cur,pck_seq_num_prev,*(uint16_t *)(buff2));
if ( ( pck_seq_num_cur != (pck_seq_num_prev + 1) ) && !((pck_seq_num_prev==75) && (pck_seq_num_cur==1 ))){
printf("out of order packet received1! %d|%d|%d\n",pck_seq_num_cur,pck_seq_num_prev, *timestamp);
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,pck_seq_num_cur);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,pck_seq_num_prev);
eth->rx_actual_nsamps=bytes_received>>2;
eth->rx_count++;
}
}
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
}
return (bytes_received-APP_HEADER_SIZE_BYTES)>>2;
}
int eth_set_dev_conf_udp(openair0_device *device) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
void *msg;
ssize_t msg_len;
/* a BBU client sents to RRH a set of configuration parameters (openair0_config_t)
so that RF front end is configured appropriately and
frame/packet size etc. can be set */
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
memcpy(msg,(void*)device->openair0_cfg,msg_len);
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&dest_addr[Mod_id],addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
return 0;
}
int eth_get_dev_conf_udp(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str1[INET_ADDRSTRLEN],str[INET_ADDRSTRLEN];
void *msg;
ssize_t msg_len;
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str1, INET_ADDRSTRLEN);
/* RRH receives from BBU openair0_config_t */
if (recvfrom(eth->sockfd[Mod_id],
msg,
msg_len,
0,
(struct sockaddr *)&dest_addr[Mod_id],
(socklen_t *)&addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
device->openair0_cfg=(openair0_config_t *)msg;
/* get remote ip address and port */
/* inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str1, INET_ADDRSTRLEN); */
/* device->openair0_cfg->remote_port =ntohs(dest_addr[Mod_id].sin_port); */
/* device->openair0_cfg->remote_addr =str1; */
/* /\* restore local ip address and port *\/ */
/* inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN); */
/* device->openair0_cfg->my_port =ntohs(local_addr[Mod_id].sin_port); */
/* device->openair0_cfg->my_addr =str; */
/* printf("[RRH] mod_%d socket %d connected to BBU %s:%d %s:%d\n", Mod_id, eth->sockfd[Mod_id],str1, device->openair0_cfg->remote_port, str, device->openair0_cfg->my_port); */
return 0;
}
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
*******************************************************************************/ *******************************************************************************/
/*! \file ethernet_lib.c /*! \file ethernet_lib.c
* \brief API to stream I/Q samples over standard ethernet * \brief API to stream I/Q samples over standard ethernet
* \author Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp * \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
* \date 2015 * \date 2015
* \version 0.2 * \version 0.2
* \company Eurecom * \company Eurecom
...@@ -52,196 +52,56 @@ ...@@ -52,196 +52,56 @@
#include "common_lib.h" #include "common_lib.h"
#include "ethernet_lib.h" #include "ethernet_lib.h"
//#define DEBUG 1
int num_devices_eth = 0; int num_devices_eth = 0;
struct sockaddr_in dest_addr[MAX_INST];
int dest_addr_len[MAX_INST]; int dest_addr_len[MAX_INST];
char sendbuf[MAX_INST][BUF_SIZ]; /*TODO*/
/*! \fn static int eth_socket_init(openair0_device *device)
* \brief initialization of UDP Socket to communicate with one destination
* \param[in] *device openair device for which the socket will be created
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
static int eth_socket_init(openair0_device *device);
/*! \fn static int eth_set_dev_conf(openair0_device *device)
* \brief
* \param[in] *device openair device
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
static int eth_set_dev_conf(openair0_device *device);
/*! \fn static int eth_get_dev_conf(openair0_device *device)
* \brief
* \param[in] *device openair device
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
static int eth_get_dev_conf(openair0_device *device);
int trx_eth_start(openair0_device *device) { int trx_eth_start(openair0_device *device) {
/* initialize socket */
if (eth_socket_init(device)!=0) {
return -1;
}
/* RRH gets openair0 device configuration BBU sets openair0 device configuration*/
if (device->func_type == BBU_FUNC) {
return eth_set_dev_conf(device);
} else {
return eth_get_dev_conf(device);
}
return 0;
}
int trx_eth_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int n_written=0,i;
uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
int sendto_flag =0;
sendto_flag|=MSG_DONTWAIT;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in tx buffer where the payload to be sent is
buff2 points to the position in tx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]-header_size);
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
n_written = 0;
*(int16_t *)(buff2 + sizeof(int16_t))=1+(i<<1);
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
/* printf("[RRH]write mod_%d %d , len %d, buff %p antenna %d\n",
Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
while(n_written < nsamps) {
/* Send packet */
if ((n_written += sendto(eth->sockfd[Mod_id],
buff2,
(nsamps<<2)+header_size,
0,
(struct sockaddr*)&eth->dest_addr[Mod_id],
dest_addr_len[Mod_id])) < 0) {
perror("ETHERNET WRITE");
exit(-1);
}
}
#if DEBUG
printf("Buffer head TX: nu=%d an_id=%d ts%d samples_send=%d i=%d data=%x\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
n_written>>2,i,*(int32_t *)(buff2 + 20*sizeof(int32_t)));
#endif
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
}
return n_written;
}
int trx_eth_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
int bytes_received=0;
int block_cnt=0;
int ret=0,i;
uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
eth_state_t *eth = (eth_state_t*)device->priv; eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
for (i=0;i<cc;i++) { /* initialize socket */
/* buff[i] points to the position in rx buffer where the payload to be received will be placed if ((eth->flags & ETH_RAW_MODE) != 0 ) {
buff2 points to the position in rx buffer where the packet header will be placed */ if (eth_socket_init_raw(device)!=0) return -1;
void *buff2 = (void*)(buff[i]-header_size); /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if (device->host_type == BBU_HOST) {
/* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/ if(eth_set_dev_conf_raw(device)!=0) return -1;
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
bytes_received=0;
block_cnt=0;
ret=0;
/* printf("[RRH] read mod_%d %d,len %d, buff %p antenna %d\n",
Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
while(bytes_received < (int)((nsamps<<2))) {
ret=recvfrom(eth->sockfd[Mod_id],
buff2+bytes_received,
(nsamps<<2)+header_size-bytes_received,
0,//MSG_DONTWAIT,
(struct sockaddr *)&eth->dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id]);
if (ret==-1) {
if (errno == EAGAIN) {
perror("ETHERNET READ: ");
return((nsamps<<2) + header_size);
} else if (errno == EWOULDBLOCK) {
block_cnt++;
usleep(10);
if (block_cnt == 100) return(-1);
}
} else { } else {
bytes_received+=ret; if(eth_get_dev_conf_raw(device)!=0) return -1;
} }
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
} else {
if (eth_socket_init_udp(device)!=0) return -1;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if (device->host_type == BBU_HOST) {
if(eth_set_dev_conf_udp(device)!=0) return -1;
} else {
if(eth_get_dev_conf_udp(device)!=0) return -1;
} }
/* adjust MTU wrt number of samples per packet */
#if DEBUG //if(ethernet_tune (device,MTU_SIZE,UDP_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
printf("Buffer head RX: nu=%d an_id=%d ts%d samples_recv=%d i=%d data=%x\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
ret>>2,i,*(int32_t *)(buff2 + 20*sizeof(int32_t)));
#endif
/* store the timestamp value from packet's header */
*timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
} }
return nsamps; /* apply additional configuration */
if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1;
if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1;
return 0;
} }
void trx_eth_end(openair0_device *device) { void trx_eth_end(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv; eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id; int Mod_id = device->Mod_id;
/*destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
if ( close(eth->sockfd[Mod_id]) <0 ) { if ( close(eth->sockfd[Mod_id]) <0 ) {
perror("ETHERNET: Failed to close socket"); perror("ETHERNET: Failed to close socket");
exit(0); exit(0);
} else { } else {
printf("[RRH] socket for mod_id %d has been successfully closed.\n",Mod_id); printf("[%s] socket for mod_id %d has been successfully closed.\n",(device->host_type == BBU_HOST)? "BBU":"RRH",Mod_id);
} }
} }
...@@ -253,7 +113,7 @@ int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) { ...@@ -253,7 +113,7 @@ int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
eth_state_t *eth = (eth_state_t*)device->priv; eth_state_t *eth = (eth_state_t*)device->priv;
/* BBU sends a message to RRH */ /* BBU sends a message to RRH */
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) { if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: "); perror("ETHERNET: ");
exit(0); exit(0);
} }
...@@ -262,7 +122,6 @@ int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) { ...@@ -262,7 +122,6 @@ int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
} }
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) { int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
eth_state_t *eth = (eth_state_t*)device->priv; eth_state_t *eth = (eth_state_t*)device->priv;
...@@ -273,7 +132,7 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) { ...@@ -273,7 +132,7 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
msg, msg,
msg_len, msg_len,
0, 0,
(struct sockaddr *)&eth->dest_addr[Mod_id], (struct sockaddr *)&dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1) { (socklen_t *)&dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: "); perror("ETHERNET: ");
exit(0); exit(0);
...@@ -283,65 +142,6 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) { ...@@ -283,65 +142,6 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
} }
static int eth_set_dev_conf(openair0_device *device) {
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
void *msg;
ssize_t msg_len;
/* a BBU client sents to RRH a set of configuration parameters (openair0_config_t)
so that RF front end is configured appropriately and
frame/packet size etc. can be set */
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
memcpy(msg,(void*)&device->openair0_cfg,msg_len);
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
return 0;
}
static int eth_get_dev_conf(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str[INET_ADDRSTRLEN];
void *msg;
ssize_t msg_len;
msg=malloc(sizeof(openair0_config_t));
msg_len=sizeof(openair0_config_t);
/* RRH receives from BBU openair0_config_t */
if (recvfrom(eth->sockfd[Mod_id],
msg,
msg_len,
0,
(struct sockaddr *)&eth->dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
}
memcpy((void*)&device->openair0_cfg,msg,msg_len);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
device->openair0_cfg.remote_port =ntohs(eth->dest_addr[Mod_id].sin_port);
device->openair0_cfg.remote_ip=str;
/*apply additional configuration*/
//ethernet_tune (device, RING_PAR);
// printf("[RRH] write mod_%d %d to %s:%d\n",Mod_id,eth->sockfd[Mod_id],str,ntohs(eth->dest_addr[Mod_id].sin_port));
return 0;
}
int trx_eth_stop(int card) { int trx_eth_stop(int card) {
return(0); return(0);
...@@ -364,179 +164,165 @@ int trx_eth_reset_stats(openair0_device* device) { ...@@ -364,179 +164,165 @@ int trx_eth_reset_stats(openair0_device* device) {
} }
static int eth_socket_init(openair0_device *device) { int ethernet_tune(openair0_device *device, unsigned int option, int value) {
int i = 0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
char str[INET_ADDRSTRLEN];
const char *dest_ip;
int dest_port=0;
if (device->func_type == RRH_FUNC ) {
dest_ip = device->openair0_cfg.my_ip;
dest_port = device->openair0_cfg.my_port;
printf("[RRH] ip addr %s port %d\n",dest_ip, dest_port);
} else {
dest_ip = device->openair0_cfg.remote_ip;
dest_port = device->openair0_cfg.remote_port;
printf("[BBU] ip addr %s port %d\n",dest_ip, dest_port);
}
/* Open RAW socket to send on */
if ((eth->sockfd[Mod_id] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("ETHERNET: Error opening socket");
exit(0);
}
/* initialize destination address */
for (i=0; i< MAX_INST; i++) {
bzero((void *)&(eth->dest_addr[i]), sizeof(eth->dest_addr[i]));
}
// bzero((void *)dest,sizeof(struct sockaddr_in));
eth->dest_addr[Mod_id].sin_family = AF_INET;
inet_pton(AF_INET,dest_ip,&(eth->dest_addr[Mod_id].sin_addr.s_addr));
eth->dest_addr[Mod_id].sin_port=htons(dest_port);
dest_addr_len[Mod_id] = sizeof(struct sockaddr_in);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
/* if RRH, then I am the server, so bind */
if (device->func_type == RRH_FUNC ) {
if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&eth->dest_addr[Mod_id], dest_addr_len[Mod_id])<0) {
perror("ETHERNET: Cannot bind to socket");
exit(0);
} else {
printf("[RRH] binding mod_%d to %s:%d\n",Mod_id,str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
} else {
printf("[BBU] Connecting to %s:%d\n",str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
return 0;
}
int ethernet_tune(openair0_device *device , eth_opt_t option) {
eth_state_t *eth = (eth_state_t*)device->priv; eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id=device->Mod_id; int Mod_id=device->Mod_id;
struct timeval timeout;
unsigned int sndbuf_size=0, rcvbuf_size=0;
struct timeval snd_timeout, rcv_timeout;
struct ifreq ifr; struct ifreq ifr;
char system_cmd[256]; char system_cmd[256];
char* if_name=DEFAULT_IF; char* if_name=DEFAULT_IF;
struct in_addr ia;
struct if_nameindex *ids;
int ret=0;
int i=0;
/****************** socket level options ************************/ /****************** socket level options ************************/
if (option== SND_BUF_SIZE) { /* transmit socket buffer size */ switch(option) {
case SND_BUF_SIZE: /* transmit socket buffer size */
if (setsockopt(eth->sockfd[Mod_id], if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET, SOL_SOCKET,
SO_SNDBUF, SO_SNDBUF,
&sndbuf_size,sizeof(sndbuf_size))) { &value,sizeof(value))) {
perror("[ETHERNET] setsockopt()"); perror("[ETHERNET] setsockopt()");
} else { } else {
printf( "sndbuf_size= %d bytes\n", sndbuf_size); printf("send buffer size= %d bytes\n",value);
} }
} else if (option== RCV_BUF_SIZE) { /* receive socket buffer size */ break;
case RCV_BUF_SIZE: /* receive socket buffer size */
if (setsockopt(eth->sockfd[Mod_id], if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET, SOL_SOCKET,
SO_RCVBUF, SO_RCVBUF,
&rcvbuf_size,sizeof(rcvbuf_size))) { &value,sizeof(value))) {
perror("[ETHERNET] setsockopt()"); perror("[ETHERNET] setsockopt()");
} else { } else {
printf( "rcvbuf_size= %d bytes\n", rcvbuf_size); printf("receive bufffer size= %d bytes\n",value);
} }
} else if (option==RCV_TIMEOUT) { break;
rcv_timeout.tv_sec = 0;
rcv_timeout.tv_usec = 180;//less than rt_period case RCV_TIMEOUT:
timeout.tv_sec = value/1000000000;
timeout.tv_usec = value%1000000000;//less than rt_period?
if (setsockopt(eth->sockfd[Mod_id], if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET, SOL_SOCKET,
SO_RCVTIMEO, SO_RCVTIMEO,
(char *)&rcv_timeout,sizeof(rcv_timeout))) { (char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()"); perror("[ETHERNET] setsockopt()");
} else { } else {
printf( "rcv_timeout= %d usecs\n", rcv_timeout.tv_usec); printf( "receive timeout= %d,%d sec\n",timeout.tv_sec,timeout.tv_usec);
} }
} else if (option==SND_TIMEOUT) { break;
snd_timeout.tv_sec = 0;
snd_timeout.tv_usec = 180;//less than rt_period case SND_TIMEOUT:
timeout.tv_sec = value/1000000000;
timeout.tv_usec = value%1000000000;//less than rt_period?
if (setsockopt(eth->sockfd[Mod_id], if (setsockopt(eth->sockfd[Mod_id],
SOL_SOCKET, SOL_SOCKET,
SO_SNDTIMEO, SO_SNDTIMEO,
(char *)&snd_timeout,sizeof(snd_timeout))) { (char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()"); perror("[ETHERNET] setsockopt()");
} else { } else {
printf( "snd_timeout= %d usecs\n", snd_timeout.tv_usec); printf( "send timeout= %d,%d sec\n",timeout.tv_sec,timeout.tv_usec);
}
} }
break;
/******************* interface level options *************************/ /******************* interface level options *************************/
else if (option==MTU_SIZE) { /* change MTU of the eth interface */ case MTU_SIZE: /* change MTU of the eth interface */
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name));
ifr.ifr_mtu =8960; ifr.ifr_mtu =value;
if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 ) if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the MTU"); perror ("[ETHERNET] Can't set the MTU");
else else
printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu); printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_mtu);
} else if (option==TX_Q_LEN) { /* change TX queue length of eth interface */ break;
case TX_Q_LEN: /* change TX queue length of eth interface */
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name));
ifr.ifr_qlen =3000 ; ifr.ifr_qlen =value;
if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the txqueuelen"); perror ("[ETHERNET] Can't set the txqueuelen");
else else
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",DEFAULT_IF,ifr.ifr_qlen); printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_qlen);
break;
/******************* device level options *************************/ /******************* device level options *************************/
} else if (option==COALESCE_PAR) { case COALESCE_PAR:
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs 3",DEFAULT_IF) > 0) { ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name[Mod_id],value);
system(system_cmd); if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret));
}
printf("[ETHERNET] Coalesce parameters %s\n",system_cmd); printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
} else { } else {
perror("[ETHERNET] Can't set coalesce parameters\n"); perror("[ETHERNET] Can't set coalesce parameters\n");
} }
break;
} else if (option==PAUSE_PAR ) {
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",DEFAULT_IF) > 0) { case PAUSE_PAR:
system(system_cmd); if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name[Mod_id]);
else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name[Mod_id]);
else break;
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret));
}
printf("[ETHERNET] Pause parameters %s\n",system_cmd); printf("[ETHERNET] Pause parameters %s\n",system_cmd);
} else { } else {
perror("[ETHERNET] Can't set pause parameters\n"); perror("[ETHERNET] Can't set pause parameters\n");
} }
} else if (option==RING_PAR ) { break;
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx 4096 tx 4096",DEFAULT_IF) > 0) {
system(system_cmd); case RING_PAR:
ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx %d tx %d",eth->if_name[Mod_id],value);
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret));
}
printf("[ETHERNET] Ring parameters %s\n",system_cmd); printf("[ETHERNET] Ring parameters %s\n",system_cmd);
} else { } else {
perror("[ETHERNET] Can't set ring parameters\n"); perror("[ETHERNET] Can't set ring parameters\n");
} }
break;
default:
break;
} }
return 0; return 0;
} }
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg) { int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) {
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
int card = 0;
memset(eth, 0, sizeof(eth_state_t)); memset(eth, 0, sizeof(eth_state_t));
eth->buffer_size = (unsigned int)openair0_cfg[card].samples_per_packet*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024
eth->sample_rate = (unsigned int)openair0_cfg[card].sample_rate;
device->priv = eth;
printf("ETHERNET: Initializing openair0_device for %s ...\n", ((device->func_type == BBU_FUNC) ? "BBU": "RRH")); if (eth_params->transp_preference == 1) {
eth->flags = ETH_RAW_MODE;
} else {
eth->flags = ETH_UDP_MODE;
}
printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == BBU_HOST) ? "BBU": "RRH"));
device->Mod_id = num_devices_eth++; device->Mod_id = num_devices_eth++;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_eth_start; device->trx_start_func = trx_eth_start;
device->trx_request_func = trx_eth_request; device->trx_request_func = trx_eth_request;
device->trx_reply_func = trx_eth_reply; device->trx_reply_func = trx_eth_reply;
device->trx_write_func = trx_eth_write;
device->trx_read_func = trx_eth_read;
device->trx_get_stats_func = trx_eth_get_stats; device->trx_get_stats_func = trx_eth_get_stats;
device->trx_reset_stats_func = trx_eth_reset_stats; device->trx_reset_stats_func = trx_eth_reset_stats;
device->trx_end_func = trx_eth_end; device->trx_end_func = trx_eth_end;
...@@ -544,6 +330,149 @@ int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_c ...@@ -544,6 +330,149 @@ int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_c
device->trx_set_freq_func = trx_eth_set_freq; device->trx_set_freq_func = trx_eth_set_freq;
device->trx_set_gains_func = trx_eth_set_gains; device->trx_set_gains_func = trx_eth_set_gains;
memcpy((void*)&device->openair0_cfg,(void*)openair0_cfg,sizeof(openair0_config_t)); if ((eth->flags & ETH_RAW_MODE) != 0 ) {
device->trx_write_func = trx_eth_write_raw;
device->trx_read_func = trx_eth_read_raw;
} else {
device->trx_write_func = trx_eth_write_udp;
device->trx_read_func = trx_eth_read_udp;
}
eth->if_name[device->Mod_id] = eth_params->local_if_name;
device->priv = eth;
/* device specific */
openair0_cfg[0].txlaunch_wait = 0;//manage when TX processing is triggered
openair0_cfg[0].txlaunch_wait_slotcount = 0; //manage when TX processing is triggered
openair0_cfg[0].iq_txshift = 5;// shift
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
/* RRH does not have any information to make this configuration atm */
if (device->host_type == BBU_HOST) {
/*Note scheduling advance values valid only for case 7680000 */
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
openair0_cfg[0].samples_per_packet = 4096;
openair0_cfg[0].tx_sample_advance = 0;
openair0_cfg[0].tx_scheduling_advance = 22*openair0_cfg[0].samples_per_packet;
break;
case 23040000:
openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 0;
openair0_cfg[0].tx_scheduling_advance = 16*openair0_cfg[0].samples_per_packet;
break;
case 15360000:
openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 0;
openair0_cfg[0].tx_scheduling_advance = 10*openair0_cfg[0].samples_per_packet;
break;
case 7680000:
openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].tx_sample_advance = 0;
openair0_cfg[0].tx_scheduling_advance = 10*openair0_cfg[0].samples_per_packet;
break;
case 1920000:
openair0_cfg[0].samples_per_packet = 256;
openair0_cfg[0].tx_sample_advance = 0;
openair0_cfg[0].tx_scheduling_advance = 16*openair0_cfg[0].samples_per_packet;
break;
default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
exit(-1);
break;
}
}
device->openair0_cfg=&openair0_cfg[0];
return 0; return 0;
} }
/**************************************************************************************************************************
* DEBUGING-RELATED FUNCTIONS *
**************************************************************************************************************************/
void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag) {
static int numSend = 1;
static int numRecv = 1;
int num, k;
char tmp[48];
unsigned short int cksum;
num = (tx_rx_flag)? numSend++:numRecv++;
for (k = 0; k < 24; k++) sprintf(tmp+k, "%02X", pkt[k]);
cksum = calc_csum((unsigned short *)pkt, bytes>>2);
printf("%s-%s (%06d): %s 0x%04X\n", title,(tx_rx_flag)? "TX":"RX", num, tmp, cksum);
}
unsigned short calc_csum (unsigned short *buf, int nwords) {
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
void dump_dev(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
printf("Ethernet device interface %i configuration:\n" ,device->openair0_cfg->Mod_id);
printf(" Log level is %i :\n" ,device->openair0_cfg->log_level);
printf(" RB number: %i, sample rate: %lf \n" ,
device->openair0_cfg->num_rb_dl, device->openair0_cfg->sample_rate);
printf(" Scheduling_advance: %i, Sample_advance: %u \n" ,
device->openair0_cfg->tx_scheduling_advance, device->openair0_cfg->tx_sample_advance);
printf(" BBU configured for %i tx/%i rx channels)\n",
device->openair0_cfg->tx_num_channels,device->openair0_cfg->rx_num_channels);
printf(" Running flags: %s %s %s\n",
((eth->flags & ETH_RAW_MODE) ? "RAW socket mode - ":""),
((eth->flags & ETH_UDP_MODE) ? "UDP socket mode - ":""));
printf(" Number of iqs dumped when displaying packets: %i\n\n",eth->iqdumpcnt);
}
void inline dump_txcounters(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
printf(" Ethernet device interface %i, tx counters:\n" ,device->openair0_cfg->Mod_id);
printf(" Sent packets: %llu send errors: %i\n", eth->tx_count, eth->num_tx_errors);
}
void inline dump_rxcounters(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
printf(" Ethernet device interface %i rx counters:\n" ,device->openair0_cfg->Mod_id);
printf(" Received packets: %llu missed packets errors: %i\n", eth->rx_count, eth->num_underflows);
}
void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_flag, int nsamps) {
char *strptr;
eth_state_t *eth = (eth_state_t*)device->priv;
/*need to add ts number of iqs in printf need to fix dump iqs call */
strptr = (( tx_rx_flag == TX_FLAG) ? "TX" : "RX");
printf("\n %s, nsamps=%i \n" ,strptr,nsamps);
if (tx_rx_flag == 1) {
dump_txcounters(device);
printf(" First %i iqs of TX buffer\n",eth->iqdumpcnt);
dump_iqs(buff,eth->iqdumpcnt);
} else {
dump_rxcounters(device);
printf(" First %i iqs of RX buffer\n",eth->iqdumpcnt);
dump_iqs(buff,eth->iqdumpcnt);
}
}
void dump_iqs(char * buff, int iq_cnt) {
int i;
for (i=0;i<iq_cnt;i++) {
printf("s%02i: Q=%+ij I=%+i%s",i,
((iqoai_t *)(buff))[i].q,
((iqoai_t *)(buff))[i].i,
((i+1)%3 == 0) ? "\n" : " ");
}
}
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
* \note * \note
* \warning * \warning
*/ */
#ifndef ETHERNET_LIB_H
#define ETHERNET_LIB_H
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
...@@ -49,69 +51,88 @@ ...@@ -49,69 +51,88 @@
#define MAX_INST 4 #define MAX_INST 4
#define DEFAULT_IF "lo" #define DEFAULT_IF "lo"
#define BUF_SIZ 8960 /*Jumbo frame size*/
typedef struct { #define ETH_RAW_MODE 1
#define ETH_UDP_MODE 0
// opaque eth data struct #define TX_FLAG 1
//struct eth_if *dev; #define RX_FLAG 0
// An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
int sockfd[MAX_INST]; #define MAX_PACKET_SEQ_NUM(spp,spf) (spf/spp)
struct sockaddr_in dest_addr[MAX_INST]; #define MAC_HEADER_SIZE_BYTES (sizeof(struct ether_header))
#define APP_HEADER_SIZE_BYTES (sizeof(int32_t) + sizeof(openair0_timestamp))
#define PAYLOAD_SIZE_BYTES(nsamps) (nsamps<<2)
#define UDP_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
#define RAW_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
unsigned int buffer_size;
unsigned int timeout_ns;
//struct eth_metadata meta_rx; /*!\brief opaque ethernet data structure */
//struct eth_metadata meta_tx; typedef struct {
unsigned int sample_rate; /*!\brief socket file desc */
// time offset between transmiter timestamp and receiver timestamp; int sockfd[MAX_INST];
/*!\brief interface name */
char *if_name[MAX_INST];
/*!\brief buffer size */
unsigned int buffer_size;
/*!\brief timeout ms */
unsigned int rx_timeout_ms;
/*!\brief timeout ms */
unsigned int tx_timeout_ms;
/*!\brief runtime flags */
uint32_t flags;
/*!\ time offset between transmiter timestamp and receiver timestamp */
double tdiff; double tdiff;
// use brf_time_offset to get this value /*!\ calibration */
int tx_forward_nsamps; //166 for 20Mhz int tx_forward_nsamps;
// -------------------------------- // --------------------------------
// Debug and output control // Debug and output control
// -------------------------------- // --------------------------------
/*!\brief number of I/Q samples to be printed */
int iqdumpcnt;
/*!\brief number of underflows in interface */
int num_underflows; int num_underflows;
/*!\brief number of overflows in interface */
int num_overflows; int num_overflows;
/*!\brief number of concesutive errors in interface */
int num_seq_errors; int num_seq_errors;
/*!\brief number of errors in interface's receiver */
int num_rx_errors; int num_rx_errors;
/*!\brief umber of errors in interface's transmitter */
int num_tx_errors; int num_tx_errors;
uint64_t tx_actual_nsamps; // actual number of samples transmitted /*!\brief current TX timestamp */
openair0_timestamp tx_current_ts;
/*!\brief socket file desc */
openair0_timestamp rx_current_ts;
/*!\brief actual number of samples transmitted */
uint64_t tx_actual_nsamps;
/*!\brief actual number of samples received */
uint64_t rx_actual_nsamps; uint64_t rx_actual_nsamps;
uint64_t tx_nsamps; // number of planned samples /*!\brief number of samples to be transmitted */
uint64_t tx_nsamps;
/*!\brief number of samples to be received */
uint64_t rx_nsamps; uint64_t rx_nsamps;
uint64_t tx_count; // number pf packets /*!\brief number of packets transmitted */
uint64_t tx_count;
/*!\brief number of packets received */
uint64_t rx_count; uint64_t rx_count;
//openair0_timestamp rx_timestamp;
} eth_state_t; } eth_state_t;
#define ETH_META_STATUS_OVERRUN (1 << 0)
#define ETH_META_STATUS_UNDERRUN (1 << 1)
struct eth_meta_data{
uint64_t timestamp;
uint32_t flags;
uint32_t status;
unsigned int actual_count;
};
/*!\brief packet header */ /*!\brief packet header */
typedef struct { typedef struct {
/*!\brief packet sequence number max value=packets per frame*/
uint16_t seq_num ;
/*!\brief antenna port used to resynchronize */
uint16_t antenna_id;
/*!\brief packet's timestamp */ /*!\brief packet's timestamp */
openair0_timestamp timestamp; openair0_timestamp timestamp;
/*!\brief variable declared for alignment purposes (sample size=32 bit) */
int16_t not_used;
/*!\brief antenna port used to resynchronize */
int16_t antenna_id;
} header_t; } header_t;
/*!\brief different options for ethernet tuning in socket and driver level */ /*!\brief different options for ethernet tuning in socket and driver level */
...@@ -138,9 +159,37 @@ typedef enum { ...@@ -138,9 +159,37 @@ typedef enum {
MAX_OPT MAX_OPT
} eth_opt_t; } eth_opt_t;
/*
#define SND_BUF_SIZE 1
#define RCV_BUF_SIZE 1<<1
#define SND_TIMEOUT 1<<2
#define RCV_TIMEOUT 1<<3
#define MTU_SIZE 1<<4
#define TX_Q_LEN 1<<5
#define RING_PAR 1<<5
#define COALESCE_PAR 1<<6
#define PAUSE_PAR 1<<7
*/
/*!\brief I/Q samples */
typedef struct {
/*!\brief phase */
short i;
/*!\brief quadrature */
short q;
} iqoai_t ;
/*! \fn int ethernet_tune (openair0_device *device, eth_opt_t option) void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag);
unsigned short calc_csum (unsigned short *buf, int nwords);
void dump_dev(openair0_device *device);
void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_flag,int nsamps);
void inline dump_rxcounters(openair0_device *device);
void inline dump_txcounters(openair0_device *device);
void dump_iqs(char * buff, int iq_cnt);
/*! \fn int ethernet_tune (openair0_device *device, unsigned int option, int value);
* \brief this function allows you to configure certain ethernet parameters in socket or device level * \brief this function allows you to configure certain ethernet parameters in socket or device level
* \param[in] openair0 device which bears the socket * \param[in] openair0 device which bears the socket
* \param[in] name of parameter to configure * \param[in] name of parameter to configure
...@@ -148,6 +197,37 @@ typedef enum { ...@@ -148,6 +197,37 @@ typedef enum {
* \note * \note
* @ingroup _oai * @ingroup _oai
*/ */
int ethernet_tune (openair0_device *device, eth_opt_t option); int ethernet_tune(openair0_device *device, unsigned int option, int value);
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc) ;
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int cc);
/*! \fn int eth_socket_init_udp(openair0_device *device)
* \brief initialization of UDP Socket to communicate with one destination
* \param[in] *device openair device for which the socket will be created
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int eth_socket_init_udp(openair0_device *device);
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int eth_get_dev_conf_udp(openair0_device *device);
/*! \fn static int eth_set_dev_conf_udp(openair0_device *device)
* \brief
* \param[in] *device openair device
* \param[out]
* \return 0 on success, otherwise -1
* \note
* @ingroup _oai
*/
int eth_set_dev_conf_udp(openair0_device *device);
int eth_socket_init_raw(openair0_device *device);
int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int eth_get_dev_conf_raw(openair0_device *device);
int eth_set_dev_conf_raw(openair0_device *device);
#endif
...@@ -247,7 +247,7 @@ int openair0_stop_without_reset(int card) ...@@ -247,7 +247,7 @@ int openair0_stop_without_reset(int card)
#define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX) #define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX)
#define RF_MODE_BASE (LNA1ON + RFBBNORM) #define RF_MODE_BASE (LNA1ON + RFBBNORM)
int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg) { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// Initialize card // Initialize card
// exmimo_config_t *p_exmimo_config; // exmimo_config_t *p_exmimo_config;
...@@ -287,6 +287,8 @@ int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair ...@@ -287,6 +287,8 @@ int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair
return(-1); return(-1);
} }
device->type = EXMIMO_DEV;
return(0); return(0);
} }
...@@ -323,6 +325,12 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) ...@@ -323,6 +325,12 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
else else
p_exmimo_config->framing.multicard_syncmode=SYNCMODE_SLAVE; p_exmimo_config->framing.multicard_syncmode=SYNCMODE_SLAVE;
/* device specific */
openair0_cfg[card].txlaunch_wait = 1;//manage when TX processing is triggered
openair0_cfg[card].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
openair0_cfg[card].iq_txshift = 4;//shift
openair0_cfg[card].iq_rxrescale = 15;//rescale iqs
if (openair0_cfg[card].sample_rate==30.72e6) { if (openair0_cfg[card].sample_rate==30.72e6) {
resampling_factor = 0; resampling_factor = 0;
rx_filter = RXLPF10; rx_filter = RXLPF10;
......
...@@ -812,11 +812,15 @@ void trx_lms_end(openair0_device *device) { ...@@ -812,11 +812,15 @@ void trx_lms_end(openair0_device *device) {
} }
extern "C" {
int openair0_dev_init_lms(openair0_device *device, openair0_config_t *openair0_cfg){ /*! \brief Initialize Openair LMSSDR target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int device_init(openair0_device *device, openair0_config_t *openair0_cfg){
printf("LMSSDR: Initializing openair0_device for %s ...\n", ((device->func_type == BBU_FUNC) ? "BBU": "RRH")); printf("LMSSDR: Initializing openair0_device for %s ...\n", ((device->host_type == BBU_HOST) ? "BBU": "RRH"));
switch ((int)openair0_cfg[0].sample_rate) { switch ((int)openair0_cfg[0].sample_rate) {
case 30720000: case 30720000:
...@@ -872,3 +876,4 @@ int openair0_dev_init_lms(openair0_device *device, openair0_config_t *openair0_c ...@@ -872,3 +876,4 @@ int openair0_dev_init_lms(openair0_device *device, openair0_config_t *openair0_c
return 0; return 0;
} }
}
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/** usrp_lib.cpp /** usrp_lib.cpp
* *
* Author: HongliangXU : hong-liang-xu@agilent.com * \author: HongliangXU : hong-liang-xu@agilent.com
*/ */
#include <string.h> #include <string.h>
...@@ -55,47 +55,71 @@ ...@@ -55,47 +55,71 @@
# include <immintrin.h> # include <immintrin.h>
#endif #endif
/** @addtogroup _USRP_PHY_RF_INTERFACE_
* @{
*/
/*! \brief USRP Configuration */
typedef struct typedef struct
{ {
// -------------------------------- // --------------------------------
// variables for USRP configuration // variables for USRP configuration
// -------------------------------- // --------------------------------
//! USRP device pointer
uhd::usrp::multi_usrp::sptr usrp; uhd::usrp::multi_usrp::sptr usrp;
//uhd::usrp::multi_usrp::sptr rx_usrp; //uhd::usrp::multi_usrp::sptr rx_usrp;
//create a send streamer and a receive streamer //create a send streamer and a receive streamer
//! USRP TX Stream
uhd::tx_streamer::sptr tx_stream; uhd::tx_streamer::sptr tx_stream;
//! USRP RX Stream
uhd::rx_streamer::sptr rx_stream; uhd::rx_streamer::sptr rx_stream;
//! USRP TX Metadata
uhd::tx_metadata_t tx_md; uhd::tx_metadata_t tx_md;
//! USRP RX Metadata
uhd::rx_metadata_t rx_md; uhd::rx_metadata_t rx_md;
//! USRP Timestamp Information
uhd::time_spec_t tm_spec; uhd::time_spec_t tm_spec;
//setup variables and allocate buffer //setup variables and allocate buffer
//! USRP Metadata
uhd::async_metadata_t async_md; uhd::async_metadata_t async_md;
//! Sampling rate
double sample_rate; double sample_rate;
// time offset between transmiter timestamp and receiver timestamp;
//! time offset between transmiter timestamp and receiver timestamp;
double tdiff; double tdiff;
// use usrp_time_offset to get this value
//! TX forward samples. We use usrp_time_offset to get this value
int tx_forward_nsamps; //166 for 20Mhz int tx_forward_nsamps; //166 for 20Mhz
// -------------------------------- // --------------------------------
// Debug and output control // Debug and output control
// -------------------------------- // --------------------------------
//! Number of underflows
int num_underflows; int num_underflows;
//! Number of overflows
int num_overflows; int num_overflows;
int num_seq_errors;
//! Number of sequential errors
int num_seq_errors;
//! tx count
int64_t tx_count; int64_t tx_count;
//! rx count
int64_t rx_count; int64_t rx_count;
//! timestamp of RX packet
openair0_timestamp rx_timestamp; openair0_timestamp rx_timestamp;
} usrp_state_t; } usrp_state_t;
/*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
static int trx_usrp_start(openair0_device *device) static int trx_usrp_start(openair0_device *device)
{ {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -118,7 +142,9 @@ static int trx_usrp_start(openair0_device *device) ...@@ -118,7 +142,9 @@ static int trx_usrp_start(openair0_device *device)
return 0; return 0;
} }
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
* \param device the hardware to use
*/
static void trx_usrp_end(openair0_device *device) static void trx_usrp_end(openair0_device *device)
{ {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -132,6 +158,14 @@ static void trx_usrp_end(openair0_device *device) ...@@ -132,6 +158,14 @@ static void trx_usrp_end(openair0_device *device)
} }
/*! \brief Called to send samples to the USRP 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 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
*/
static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{ {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -153,6 +187,17 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, ...@@ -153,6 +187,17 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
return 0; return 0;
} }
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
* the first channel. *ptimestamp is the time at which the first sample
* was received.
* \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param antenna_id Index of antenna for which to receive samples
* \returns the number of sample read
*/
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc)
{ {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -172,7 +217,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -172,7 +217,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
#endif #endif
if (device->type == USRP_B200_IF) { if (device->type == USRP_B200_DEV) {
if (cc>1) { if (cc>1) {
// receive multiple channels (e.g. RF A and RF B) // receive multiple channels (e.g. RF A and RF B)
std::vector<void *> buff_ptrs; std::vector<void *> buff_ptrs;
...@@ -198,7 +243,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -198,7 +243,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
#endif #endif
} }
} }
} else if (device->type == USRP_X300_IF) { } else if (device->type == USRP_X300_DEV) {
if (cc>1) { if (cc>1) {
// receive multiple channels (e.g. RF A and RF B) // receive multiple channels (e.g. RF A and RF B)
std::vector<void *> buff_ptrs; std::vector<void *> buff_ptrs;
...@@ -238,6 +283,9 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -238,6 +283,9 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
return samples_received; return samples_received;
} }
/*! \brief Get current timestamp of USRP
* \param device the hardware to use
*/
openair0_timestamp get_usrp_time(openair0_device *device) openair0_timestamp get_usrp_time(openair0_device *device)
{ {
...@@ -246,11 +294,21 @@ openair0_timestamp get_usrp_time(openair0_device *device) ...@@ -246,11 +294,21 @@ openair0_timestamp get_usrp_time(openair0_device *device)
return s->usrp->get_time_now().to_ticks(s->sample_rate); return s->usrp->get_time_now().to_ticks(s->sample_rate);
} }
/*! \brief Compares two variables within precision
* \param a first variable
* \param b second variable
*/
static bool is_equal(double a, double b) static bool is_equal(double a, double b)
{ {
return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); return std::fabs(a-b) < std::numeric_limits<double>::epsilon();
} }
/*! \brief Set frequencies (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \param dummy dummy variable not used
* \returns 0 in success
*/
int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) { int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -262,6 +320,11 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, ...@@ -262,6 +320,11 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,
} }
/*! \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) { int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) {
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t*)device->priv;
...@@ -279,6 +342,11 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open ...@@ -279,6 +342,11 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open
} }
/*! \brief Set Gains (TX/RX)
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int trx_usrp_set_gains(openair0_device* device, int trx_usrp_set_gains(openair0_device* device,
openair0_config_t *openair0_cfg) { openair0_config_t *openair0_cfg) {
...@@ -299,11 +367,14 @@ int trx_usrp_set_gains(openair0_device* device, ...@@ -299,11 +367,14 @@ int trx_usrp_set_gains(openair0_device* device,
return(0); return(0);
} }
/*! \brief Stop USRP
* \param card refers to the hardware index to use
*/
int trx_usrp_stop(int card) { int trx_usrp_stop(int card) {
return(0); return(0);
} }
/*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t calib_table_b210[] = { rx_gain_calib_table_t calib_table_b210[] = {
{3500000000.0,44.0}, {3500000000.0,44.0},
{2660000000.0,49.0}, {2660000000.0,49.0},
...@@ -312,6 +383,7 @@ rx_gain_calib_table_t calib_table_b210[] = { ...@@ -312,6 +383,7 @@ rx_gain_calib_table_t calib_table_b210[] = {
{816000000.0,58.0}, {816000000.0,58.0},
{-1,0}}; {-1,0}};
/*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t calib_table_b210_38[] = { rx_gain_calib_table_t calib_table_b210_38[] = {
{3500000000.0,44.0}, {3500000000.0,44.0},
{2660000000.0,49.8}, {2660000000.0,49.8},
...@@ -320,6 +392,7 @@ rx_gain_calib_table_t calib_table_b210_38[] = { ...@@ -320,6 +392,7 @@ rx_gain_calib_table_t calib_table_b210_38[] = {
{816000000.0,57.0}, {816000000.0,57.0},
{-1,0}}; {-1,0}};
/*! \brief USRPx310 RX calibration table */
rx_gain_calib_table_t calib_table_x310[] = { rx_gain_calib_table_t calib_table_x310[] = {
{3500000000.0,77.0}, {3500000000.0,77.0},
{2660000000.0,81.0}, {2660000000.0,81.0},
...@@ -328,6 +401,11 @@ rx_gain_calib_table_t calib_table_x310[] = { ...@@ -328,6 +401,11 @@ rx_gain_calib_table_t calib_table_x310[] = {
{816000000.0,85.0}, {816000000.0,85.0},
{-1,0}}; {-1,0}};
/*! \brief Set RX gain offset
* \param openair0_cfg RF frontend parameters set by application
* \param chain_index RF chain to apply settings to
* \returns 0 in success
*/
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) {
int i=0; int i=0;
...@@ -373,12 +451,20 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ ...@@ -373,12 +451,20 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_
} }
/*! \brief print the USRP statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_usrp_get_stats(openair0_device* device) { int trx_usrp_get_stats(openair0_device* device) {
return(0); return(0);
} }
/*! \brief Reset the USRP statistics
* \param device the hardware to use
* \returns 0 on success
*/
int trx_usrp_reset_stats(openair0_device* device) { int trx_usrp_reset_stats(openair0_device* device) {
return(0); return(0);
...@@ -386,14 +472,21 @@ int trx_usrp_reset_stats(openair0_device* device) { ...@@ -386,14 +472,21 @@ int trx_usrp_reset_stats(openair0_device* device) {
} }
int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg)
{ extern "C" {
/*! \brief Initialize Openair USRP target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
uhd::set_thread_priority_safe(1.0); uhd::set_thread_priority_safe(1.0);
usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t)); usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t));
memset(s, 0, sizeof(usrp_state_t)); memset(s, 0, sizeof(usrp_state_t));
// Initialize USRP device // Initialize USRP device
std::string args = "type=b200"; std::string args = "type=b200";
...@@ -436,7 +529,7 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ ...@@ -436,7 +529,7 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
s->usrp->set_clock_source("internal"); s->usrp->set_clock_source("internal");
//Setting device type to USRP X300/X310 //Setting device type to USRP X300/X310
device->type=USRP_X300_IF; device->type=USRP_X300_DEV;
// this is not working yet, master clock has to be set via constructor // this is not working yet, master clock has to be set via constructor
// set master clock rate and sample rate for tx & rx for streaming // set master clock rate and sample rate for tx & rx for streaming
...@@ -482,17 +575,18 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ ...@@ -482,17 +575,18 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
} else { } else {
printf("Found USRP B200"); printf("Found USRP B200");
args += ",num_recv_frames=256" ;
s->usrp = uhd::usrp::multi_usrp::make(args); s->usrp = uhd::usrp::multi_usrp::make(args);
// s->usrp->set_rx_subdev_spec(rx_subdev); // s->usrp->set_rx_subdev_spec(rx_subdev);
// s->usrp->set_tx_subdev_spec(tx_subdev); // s->usrp->set_tx_subdev_spec(tx_subdev);
// do not explicitly set the clock to "internal", because this will disable the gpsdo // do not explicitly set the clock to "internal", because this will disable the gpsdo
// // lock mboard clocks // // lock mboard clocks
// s->usrp->set_clock_source("internal"); // s->usrp->set_clock_source("internal");
// set master clock rate and sample rate for tx & rx for streaming // set master clock rate and sample rate for tx & rx for streaming
device->type = USRP_B200_IF; device->type = USRP_B200_DEV;
if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
...@@ -552,6 +646,12 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ ...@@ -552,6 +646,12 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
} }
} }
/* device specific */
openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered
openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
openair0_cfg[0].iq_txshift = 4;//shift
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
for(i=0;i<s->usrp->get_rx_num_channels();i++) { for(i=0;i<s->usrp->get_rx_num_channels();i++) {
if (i<openair0_cfg[0].rx_num_channels) { if (i<openair0_cfg[0].rx_num_channels) {
s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i); s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i);
...@@ -607,9 +707,6 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ ...@@ -607,9 +707,6 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
s->usrp->set_time_now(uhd::time_spec_t(0.0)); s->usrp->set_time_now(uhd::time_spec_t(0.0));
for (i=0;i<openair0_cfg[0].rx_num_channels;i++) { for (i=0;i<openair0_cfg[0].rx_num_channels;i++) {
if (i<openair0_cfg[0].rx_num_channels) { if (i<openair0_cfg[0].rx_num_channels) {
printf("RX Channel %lu\n",i); printf("RX Channel %lu\n",i);
...@@ -656,4 +753,6 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_ ...@@ -656,4 +753,6 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
if(is_equal(s->sample_rate, (double)7.68e6)) if(is_equal(s->sample_rate, (double)7.68e6))
s->tx_forward_nsamps = 50; s->tx_forward_nsamps = 50;
return 0; return 0;
}
} }
/*@}*/
...@@ -793,7 +793,10 @@ INPUT = $(OPENAIR1_DIR)/PHY/defs.h \ ...@@ -793,7 +793,10 @@ INPUT = $(OPENAIR1_DIR)/PHY/defs.h \
$(OPENAIR2_DIR)/LAYER2/RLC/UM_v9.3.0/rlc_um.h \ $(OPENAIR2_DIR)/LAYER2/RLC/UM_v9.3.0/rlc_um.h \
$(OPENAIR2_DIR)/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h \ $(OPENAIR2_DIR)/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h \
$(OPENAIR2_DIR)/NETWORK_DRIVER/MESH/proto_extern.h \ $(OPENAIR2_DIR)/NETWORK_DRIVER/MESH/proto_extern.h \
$(OPENAIR_TARGETS)/ARCH/COMMON/common_lib.h $(OPENAIR_TARGETS)/ARCH/COMMON/common_lib.h \
$(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp \
$(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c \
$(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
......
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "92";
////////// Physical parameters:
component_carriers = (
{
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -29;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -90;
pusch_alpha = "AL1";
pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.170";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
rrh_gw_config = (
{
local_if_name = "eth0";
remote_address = "169.254.8.28";
#remote_address = "127.0.0.1";
#remote_address = "74:d4:35:cc:88:45";
local_address = "169.254.7.91";
#local_address = "127.0.0.1";
#local_address = "d4:be:d9:22:0a:ac";
#for raw option local port must be the same to remote
local_port = 50001;
remote_port = 50000;
active = "yes";
preference = "udp";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.242/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.242/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
...@@ -148,7 +148,7 @@ void *rrh_proc_UE_thread(void * arg) { ...@@ -148,7 +148,7 @@ void *rrh_proc_UE_thread(void * arg) {
unsigned int samples_per_frame=0; unsigned int samples_per_frame=0;
rrh_module_t *dev=(rrh_module_t *)arg; rrh_module_t *dev=(rrh_module_t *)arg;
samples_per_frame= dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame;
AssertFatal(samples_per_frame <=0, "invalide samples_per_frame !%u\n",samples_per_frame); AssertFatal(samples_per_frame <=0, "invalide samples_per_frame !%u\n",samples_per_frame);
time_req.tv_sec = 0; time_req.tv_sec = 0;
...@@ -260,7 +260,7 @@ void *rrh_UE_thread(void *arg) { ...@@ -260,7 +260,7 @@ void *rrh_UE_thread(void *arg) {
void *tmp; void *tmp;
unsigned int samples_per_frame=0; unsigned int samples_per_frame=0;
samples_per_frame= dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame;
time_req_1us.tv_sec = 0; time_req_1us.tv_sec = 0;
time_req_1us.tv_nsec = 1000; time_req_1us.tv_nsec = 1000;
...@@ -269,26 +269,26 @@ void *rrh_UE_thread(void *arg) { ...@@ -269,26 +269,26 @@ void *rrh_UE_thread(void *arg) {
cmd=dev->eth_dev.trx_start_func(&dev->eth_dev); cmd=dev->eth_dev.trx_start_func(&dev->eth_dev);
/* allocate memory for TX/RX buffers */ /* allocate memory for TX/RX buffers */
rx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*)); rx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*));
tx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*)); tx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*));
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4)); tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4)); memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4));
rx_buffer_UE[i]=(tmp+4*sizeof(int32_t)); rx_buffer_UE[i]=(tmp+4*sizeof(int32_t));
} }
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4)); tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4)); memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4));
tx_buffer_UE[i]=(tmp+4*sizeof(int32_t)); tx_buffer_UE[i]=(tmp+4*sizeof(int32_t));
} }
printf("Client %s:%d is connected (DL_RB=%d) rt=%d|%d. \n" , dev->eth_dev.openair0_cfg.remote_ip, printf("Client %s:%d is connected (DL_RB=%d) rt=%d|%d. \n" , dev->eth_dev.openair0_cfg->remote_addr,
dev->eth_dev.openair0_cfg.remote_port, dev->eth_dev.openair0_cfg->remote_port,
dev->eth_dev.openair0_cfg.num_rb_dl, dev->eth_dev.openair0_cfg->num_rb_dl,
dev->eth_dev.openair0_cfg.rx_num_channels, dev->eth_dev.openair0_cfg->rx_num_channels,
dev->eth_dev.openair0_cfg.tx_num_channels); dev->eth_dev.openair0_cfg->tx_num_channels);
if (cmd==START_CMD) { if (cmd==START_CMD) {
...@@ -348,8 +348,8 @@ void *rrh_UE_rx_thread(void *arg) { ...@@ -348,8 +348,8 @@ void *rrh_UE_rx_thread(void *arg) {
openair0_timestamp temp, last_hw_counter=0; openair0_timestamp temp, last_hw_counter=0;
antenna_index = 0; antenna_index = 0;
nsamps = dev->eth_dev.openair0_cfg.samples_per_packet; nsamps = dev->eth_dev.openair0_cfg->samples_per_packet;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
while (rrh_exit == 0) { while (rrh_exit == 0) {
if (!UE_rx_started) { if (!UE_rx_started) {
...@@ -492,8 +492,8 @@ void *rrh_UE_tx_thread(void *arg) { ...@@ -492,8 +492,8 @@ void *rrh_UE_tx_thread(void *arg) {
unsigned int samples_per_frame=0; unsigned int samples_per_frame=0;
antenna_index = 0; antenna_index = 0;
nsamps = dev->eth_dev.openair0_cfg.samples_per_packet; nsamps = dev->eth_dev.openair0_cfg->samples_per_packet;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
while (rrh_exit == 0) { while (rrh_exit == 0) {
......
...@@ -127,7 +127,7 @@ static void check_dev_config( rrh_module_t *mod_enb); ...@@ -127,7 +127,7 @@ static void check_dev_config( rrh_module_t *mod_enb);
* \note * \note
* @ingroup _oai * @ingroup _oai
*/ */
static void calc_rt_period_ns( openair0_config_t openair0_cfg); static void calc_rt_period_ns( openair0_config_t *openair0_cfg);
...@@ -141,104 +141,33 @@ void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) { ...@@ -141,104 +141,33 @@ void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) {
RT_flag_eNB=RT_flag; RT_flag_eNB=RT_flag;
NRT_flag_eNB=NRT_flag; NRT_flag_eNB=NRT_flag;
/* handshake with client to exchange parameters */ /* init socket and have handshake-like msg with client to exchange parameters */
mod_enb->eth_dev.trx_start_func(&mod_enb->eth_dev);//change port make it plus_id mod_enb->eth_dev.trx_start_func(&mod_enb->eth_dev);//change port make it plus_id
/* if a RF iterface is added to RRH module get the configuration parameters sent from eNB */ mod_enb->devs->openair0_cfg = mod_enb->eth_dev.openair0_cfg;
if (mod_enb->devs->type != NONE_IF ) {
memcpy((void*)&mod_enb->devs->openair0_cfg,(void *)&mod_enb->eth_dev.openair0_cfg,sizeof(openair0_config_t));
/* certain parameters have to be updated (calibration related)*/
if ( mod_enb->devs->type == EXMIMO_IF ) {
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
mod_enb->devs->openair0_cfg.tx_delay = 5;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
mod_enb->devs->openair0_cfg.tx_delay = 6;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 256;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
else if ((mod_enb->devs->type == USRP_B200_IF )||(mod_enb->devs->type == USRP_X300_IF )) {
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
mod_enb->devs->openair0_cfg.tx_delay = 5;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
mod_enb->devs->openair0_cfg.tx_delay = 6;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 256;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
else if(mod_enb->devs->type == BLADERF_IF) {
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
mod_enb->devs->openair0_cfg.tx_delay = 5;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
mod_enb->devs->openair0_cfg.tx_delay = 6;
}
else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
mod_enb->devs->openair0_cfg.samples_per_packet = 256;
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
/* check sanity of configuration parameters and print */ /* check sanity of configuration parameters and print */
check_dev_config(mod_enb); check_dev_config(mod_enb);
/* initialize and configure the RF device */ /* initialize and configure the RF device */
if (openair0_device_init(mod_enb->devs, &mod_enb->devs->openair0_cfg)<0){ if (openair0_device_load(mod_enb->devs, mod_enb->devs->openair0_cfg)<0) {
LOG_E(RRH,"Exiting, cannot initialize RF device.\n"); LOG_E(RRH,"Exiting, cannot initialize RF device.\n");
exit(-1); exit(-1);
} } else {
else { if (mod_enb->devs->type != NONE_DEV) {
LOG_I(RRH,"RF device has been successfully initialized.\n");
}
/* start RF device */ /* start RF device */
if (mod_enb->devs->type == EXMIMO_IF ) { if (mod_enb->devs->type == EXMIMO_DEV) {
//call start function for exmino
} else { } else {
if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0) if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0)
LOG_E(RRH,"Unable to initiate RF device.\n"); LOG_E(RRH,"Unable to initiate RF device.\n");
} else
LOG_I(RRH,"RF device has been initiated.\n"); LOG_I(RRH,"RF device has been initiated.\n");
} }
}
}
/* create main eNB module thread /* create main eNB module thread
main_rrh_eNB_thread allocates memory main_rrh_eNB_thread allocates memory
for TX/RX buffers and creates TX/RX for TX/RX buffers and creates TX/RX
...@@ -266,7 +195,7 @@ void *rrh_eNB_thread(void *arg) { ...@@ -266,7 +195,7 @@ void *rrh_eNB_thread(void *arg) {
void *tmp; void *tmp;
unsigned int samples_per_frame=0; unsigned int samples_per_frame=0;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
while (rrh_exit==0) { while (rrh_exit==0) {
...@@ -278,42 +207,42 @@ void *rrh_eNB_thread(void *arg) { ...@@ -278,42 +207,42 @@ void *rrh_eNB_thread(void *arg) {
/* allocate memory for TX/RX buffers /* allocate memory for TX/RX buffers
each antenna port has a TX and a RX buffer each antenna port has a TX and a RX buffer
each TX and RX buffer is of (samples_per_frame + HEADER_SIZE) samples (size of samples is 4 bytes) */ each TX and RX buffer is of (samples_per_frame + HEADER_SIZE) samples (size of samples is 4 bytes) */
rx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*)); rx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*));
tx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*)); tx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*));
LOG_D(RRH,"rx_buffer_eNB address =%p tx_buffer_eNB address =%p \n",rx_buffer_eNB,tx_buffer_eNB); LOG_D(RRH,"rx_buffer_eNB address =%p tx_buffer_eNB address =%p \n",rx_buffer_eNB,tx_buffer_eNB);
/* rx_buffer_eNB points to the beginning of data */ /* rx_buffer_eNB points to the beginning of data */
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32)); tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32)); memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32));
rx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) ); rx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) );
LOG_D(RRH,"i=%d rx_buffer_eNB[i]=%p tmp= %p\n",i,rx_buffer_eNB[i],tmp); LOG_D(RRH,"i=%d rx_buffer_eNB[i]=%p tmp= %p\n",i,rx_buffer_eNB[i],tmp);
} }
/* tx_buffer_eNB points to the beginning of data */ /* tx_buffer_eNB points to the beginning of data */
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32)); tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32)); memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32));
tx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) ); tx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) );
LOG_D(RRH,"i= %d tx_buffer_eNB[i]=%p tmp= %p \n",i,tx_buffer_eNB[i],tmp); LOG_D(RRH,"i= %d tx_buffer_eNB[i]=%p tmp= %p \n",i,tx_buffer_eNB[i],tmp);
} }
/* dummy initialization for TX/RX buffers */ /* dummy initialization for TX/RX buffers */
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
for (j=0; j<samples_per_frame; j++) { for (j=0; j<samples_per_frame; j++) {
rx_buffer_eNB[i][j]=32+i; rx_buffer_eNB[i][j]=32+i;
} }
} }
/* dummy initialization for TX/RX buffers */ /* dummy initialization for TX/RX buffers */
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
for (j=0; j<samples_per_frame; j++) { for (j=0; j<samples_per_frame; j++) {
tx_buffer_eNB[i][j]=12+i; tx_buffer_eNB[i][j]=12+i;
} }
} }
/* allocate TX/RX buffers pointers used in write/read operations */ /* allocate TX/RX buffers pointers used in write/read operations */
rx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*)); rx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*));
tx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*)); tx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*));
/* init mutexes */ /* init mutexes */
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
pthread_mutex_init(&sync_eNB_mutex[i],NULL); pthread_mutex_init(&sync_eNB_mutex[i],NULL);
pthread_cond_init(&sync_eNB_cond[i],NULL); pthread_cond_init(&sync_eNB_cond[i],NULL);
} }
...@@ -353,7 +282,7 @@ void *rrh_eNB_thread(void *arg) { ...@@ -353,7 +282,7 @@ void *rrh_eNB_thread(void *arg) {
} }
/* create timer thread; when no RF device is present a software clock is generated */ /* create timer thread; when no RF device is present a software clock is generated */
if (dev->devs->type == NONE_IF) { if (dev->devs->type == NONE_DEV) {
int error_code_timer; int error_code_timer;
pthread_t main_timer_proc_thread; pthread_t main_timer_proc_thread;
...@@ -405,10 +334,11 @@ void *rrh_eNB_thread(void *arg) { ...@@ -405,10 +334,11 @@ void *rrh_eNB_thread(void *arg) {
return(0); return(0);
} }
/* Receive from RF and transmit to RRH */
void *rrh_eNB_rx_thread(void *arg) { void *rrh_eNB_rx_thread(void *arg) {
/* measuremnt related vars */ /* measurement related vars */
struct timespec time0,time1,time2; struct timespec time0,time1,time2;
unsigned long long max_rx_time=0, min_rx_time=rt_period, total_rx_time=0, average_rx_time=rt_period, s_period=0, trial=0; unsigned long long max_rx_time=0, min_rx_time=rt_period, total_rx_time=0, average_rx_time=rt_period, s_period=0, trial=0;
int trace_cnt=0; int trace_cnt=0;
...@@ -425,10 +355,10 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -425,10 +355,10 @@ void *rrh_eNB_rx_thread(void *arg) {
time_req_1us.tv_sec = 0; time_req_1us.tv_sec = 0;
time_req_1us.tv_nsec =1000; //time_req_1us.tv_nsec = (int)rt_period/2;--->granularity issue time_req_1us.tv_nsec =1000; //time_req_1us.tv_nsec = (int)rt_period/2;--->granularity issue
spp_eth = dev->eth_dev.openair0_cfg.samples_per_packet; spp_eth = dev->eth_dev.openair0_cfg->samples_per_packet;
spp_rf = dev->devs->openair0_cfg.samples_per_packet; spp_rf = dev->devs->openair0_cfg->samples_per_packet;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
samples_per_subframe = (unsigned int)samples_per_frame/10; samples_per_subframe = (unsigned int)samples_per_frame/10;
loopback = dev->loopback; loopback = dev->loopback;
measurements = dev->measurements; measurements = dev->measurements;
...@@ -456,14 +386,14 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -456,14 +386,14 @@ void *rrh_eNB_rx_thread(void *arg) {
while (rrh_exit == 0) { while (rrh_exit == 0) {
while (rx_pos <(1 + subframe)*samples_per_subframe) { while (rx_pos <(1 + subframe)*samples_per_subframe) {
LOG_D(RRH,"starting a new send:%d %d\n",sync_trx,frame); //LOG_D(RRH,"starting a new send:%d %d\n",sync_trx,frame);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX, frame); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX, frame);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX, subframe ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX, subframe );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK, pck_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK, pck_rx );
LOG_D(RRH,"pack=%d rx_pos=%d subframe=%d frame=%d\n ",pck_rx, rx_pos, subframe,frame); LOG_D(RRH,"pack=%d rx_pos=%d subframe=%d frame=%d\n ",pck_rx, rx_pos, subframe,frame);
if (dev->devs->type == NONE_IF) { if (dev->devs->type == NONE_DEV) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, hw_counter ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT, last_hw_counter ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT, last_hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, s_cnt ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, s_cnt );
...@@ -501,19 +431,19 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -501,19 +431,19 @@ void *rrh_eNB_rx_thread(void *arg) {
} }
} }
for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) { for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos]; rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos];
LOG_D(RRH," rx_eNB[i]=%p rx_buffer_eNB[i][rx_pos]=%p ,rx_pos=%d, i=%d ts=%d\n",rx_eNB[i],&rx_buffer_eNB[i][rx_pos],rx_pos,i,timestamp_rx); LOG_D(RRH," rx_eNB[i]=%p rx_buffer_eNB[i][rx_pos]=%p ,rx_pos=%d, i=%d ts=%d\n",rx_eNB[i],&rx_buffer_eNB[i][rx_pos],rx_pos,i,timestamp_rx);
} }
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, rx_pos ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, rx_pos );
if (dev->devs->type != NONE_IF) { if (dev->devs->type != NONE_DEV) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 1 );
/* Read operation to RF device (RX)*/ /* Read operation to RF device (RX)*/
if ( dev->devs->trx_read_func (dev->devs, if ( dev->devs->trx_read_func (dev->devs,
&timestamp_rx, &timestamp_rx,
rx_eNB, rx_eNB,
spp_rf, spp_rf,
dev->devs->openair0_cfg.rx_num_channels dev->devs->openair0_cfg->rx_num_channels
)<0) { )<0) {
perror("RRH eNB : USRP read"); perror("RRH eNB : USRP read");
} }
...@@ -526,14 +456,14 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -526,14 +456,14 @@ void *rrh_eNB_rx_thread(void *arg) {
timestamp_rx, timestamp_rx,
rx_eNB, rx_eNB,
spp_eth, spp_eth,
dev->eth_dev.openair0_cfg.rx_num_channels, dev->eth_dev.openair0_cfg->rx_num_channels,
0))<0) { 0))<0) {
perror("RRH eNB : ETHERNET write"); perror("RRH eNB : ETHERNET write");
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
/* when there is no RF timestamp is updated by number of samples */ /* when there is no RF timestamp is updated by number of samples */
if (dev->devs->type == NONE_IF) { if (dev->devs->type == NONE_DEV) {
timestamp_rx+=spp_eth; timestamp_rx+=spp_eth;
last_hw_counter=hw_counter; last_hw_counter=hw_counter;
} }
...@@ -559,7 +489,7 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -559,7 +489,7 @@ void *rrh_eNB_rx_thread(void *arg) {
} }
if (s_period++ == PRINTF_PERIOD) { if (s_period++ == PRINTF_PERIOD) {
s_period=0; s_period=0;
LOG_I(RRH,"Average eNB RX time : %lu\tMax RX time : %lu\tMin RX time : %lu\n",average_rx_time,max_rx_time,min_rx_time); LOG_I(RRH,"Average eNB RX time : %lu ns\tMax RX time : %lu ns\tMin RXX time : %lu ns\n",average_rx_time,max_rx_time,min_rx_time);
} }
} }
...@@ -577,7 +507,7 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -577,7 +507,7 @@ void *rrh_eNB_rx_thread(void *arg) {
next_rx_pos=(rx_pos+spp_eth); next_rx_pos=(rx_pos+spp_eth);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 );
/**/ /*
if (frame>50) { if (frame>50) {
pthread_mutex_lock(&sync_trx_mutex); pthread_mutex_lock(&sync_trx_mutex);
while (sync_trx) { while (sync_trx) {
...@@ -587,7 +517,7 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -587,7 +517,7 @@ void *rrh_eNB_rx_thread(void *arg) {
LOG_D(RRH,"out of while send:%d %d\n",sync_trx,frame); LOG_D(RRH,"out of while send:%d %d\n",sync_trx,frame);
pthread_cond_signal(&sync_trx_cond); pthread_cond_signal(&sync_trx_cond);
pthread_mutex_unlock(&sync_trx_mutex); pthread_mutex_unlock(&sync_trx_mutex);
} }*/
} // while } // while
subframe++; subframe++;
...@@ -609,6 +539,7 @@ void *rrh_eNB_rx_thread(void *arg) { ...@@ -609,6 +539,7 @@ void *rrh_eNB_rx_thread(void *arg) {
return 0; return 0;
} }
/* Receive from eNB and transmit to RF */
void *rrh_eNB_tx_thread(void *arg) { void *rrh_eNB_tx_thread(void *arg) {
...@@ -647,12 +578,11 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -647,12 +578,11 @@ void *rrh_eNB_tx_thread(void *arg) {
time_req_1us.tv_sec = 1; time_req_1us.tv_sec = 1;
time_req_1us.tv_nsec = 0; time_req_1us.tv_nsec = 0;
spp_eth = dev->eth_dev.openair0_cfg.samples_per_packet; spp_eth = dev->eth_dev.openair0_cfg->samples_per_packet;
spp_rf = dev->devs->openair0_cfg.samples_per_packet; spp_rf = dev->devs->openair0_cfg->samples_per_packet;
samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame; samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
samples_per_subframe = (unsigned int)samples_per_frame/10; samples_per_subframe = (unsigned int)samples_per_frame/10;
tx_pos=0; tx_pos=0;
//tx_pos_rf=spp_rf*dev->devs->openair0_cfg.tx_delay;
loopback = dev->loopback; loopback = dev->loopback;
measurements = dev->measurements; measurements = dev->measurements;
...@@ -660,47 +590,22 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -660,47 +590,22 @@ void *rrh_eNB_tx_thread(void *arg) {
while (rrh_exit == 0) { while (rrh_exit == 0) {
while (tx_pos < (1 + subframe)*samples_per_subframe) { while (tx_pos < (1 + subframe)*samples_per_subframe) {
LOG_D(RRH,"bef lock read:%d %d\n",sync_trx,frame); //LOG_D(RRH,"bef lock read:%d %d\n",sync_trx,frame);
pthread_mutex_lock(&sync_trx_mutex); //pthread_mutex_lock(&sync_trx_mutex);
while (!sync_trx) { //while (!sync_trx) {
LOG_D(RRH,"in sync read:%d %d\n",sync_trx,frame); //LOG_D(RRH,"in sync read:%d %d\n",sync_trx,frame);
pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex); //pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex);
} //}
LOG_D(RRH,"out of while read:%d %d\n",sync_trx,frame); //LOG_D(RRH,"out of while read:%d %d\n",sync_trx,frame);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, subframe ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, subframe );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, pck_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, pck_tx );
/*
if (dev->devs->type == NONE_IF) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT, hw_counter );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT, last_hw_counter );
if (!eNB_tx_started) {
eNB_tx_started=1; // set this flag to 1 to indicate that eNB started
if (RT_flag_eNB==1) {
last_hw_counter=hw_counter;
}
} else {
if (RT_flag_eNB==1) {
if (hw_counter > last_hw_counter+1) {
printf("LT");
} else {
while ((hw_counter < last_hw_counter+1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP, 1 );
nanosleep(&time_req_1us,&time_rem_1us);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP, 0 );
}
}
}
}
} */
if (measurements == 1 ) clock_gettime(CLOCK_MONOTONIC,&time1); if (measurements == 1 ) clock_gettime(CLOCK_MONOTONIC,&time1);
for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos]; //RF!!!!! for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos];
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TXCNT, tx_pos ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TXCNT, tx_pos );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
...@@ -710,12 +615,12 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -710,12 +615,12 @@ void *rrh_eNB_tx_thread(void *arg) {
&timestamp_tx, &timestamp_tx,
tx_eNB, tx_eNB,
spp_eth, spp_eth,
dev->eth_dev.openair0_cfg.tx_num_channels))<0) { dev->eth_dev.openair0_cfg->tx_num_channels))<0) {
perror("RRH eNB : ETHERNET read"); perror("RRH eNB : ETHERNET read");
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
if (dev->devs->type != NONE_IF) { if (dev->devs->type != NONE_DEV) {
LOG_D(RRH," tx_buffer_eNB[i][tx_pos]=%x t_buffer_eNB[i][tx_pos+1]=%x t_buffer_eNB[i][tx_pos+2]=%x \n",tx_buffer_eNB[0][tx_pos],tx_buffer_eNB[0][tx_pos+1],tx_buffer_eNB[0][tx_pos+2]); LOG_D(RRH," tx_buffer_eNB[i][tx_pos]=%x t_buffer_eNB[i][tx_pos+1]=%x t_buffer_eNB[i][tx_pos+2]=%x \n",tx_buffer_eNB[0][tx_pos],tx_buffer_eNB[0][tx_pos+1],tx_buffer_eNB[0][tx_pos+2]);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 1 );
/* Write operation to RF device (TX)*/ /* Write operation to RF device (TX)*/
...@@ -723,8 +628,8 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -723,8 +628,8 @@ void *rrh_eNB_tx_thread(void *arg) {
timestamp_tx, timestamp_tx,
tx_eNB, tx_eNB,
spp_rf, spp_rf,
dev->devs->openair0_cfg.tx_num_channels, dev->devs->openair0_cfg->tx_num_channels,
0)<0){ 1)<0){
perror("RRH eNB : USRP write"); perror("RRH eNB : USRP write");
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 0 );
...@@ -733,7 +638,7 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -733,7 +638,7 @@ void *rrh_eNB_tx_thread(void *arg) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_tx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_tx&0xffffffff );
if (dev->devs->type == NONE_IF) last_hw_counter=hw_counter; if (dev->devs->type == NONE_DEV) last_hw_counter=hw_counter;
if (loopback ==1 ) { if (loopback ==1 ) {
...@@ -754,10 +659,10 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -754,10 +659,10 @@ void *rrh_eNB_tx_thread(void *arg) {
tx_pos += spp_eth; tx_pos += spp_eth;
pck_tx++; pck_tx++;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 ); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 );
sync_trx=0; //sync_trx=0;
pthread_cond_signal(&sync_trx_cond); //pthread_cond_signal(&sync_trx_cond);
pthread_mutex_unlock(&sync_trx_mutex); //pthread_mutex_unlock(&sync_trx_mutex);
} }
/* wrap around tx buffer index */ /* wrap around tx buffer index */
...@@ -775,9 +680,9 @@ void *rrh_eNB_tx_thread(void *arg) { ...@@ -775,9 +680,9 @@ void *rrh_eNB_tx_thread(void *arg) {
} }
static void calc_rt_period_ns( openair0_config_t openair0_cfg) { static void calc_rt_period_ns( openair0_config_t *openair0_cfg) {
rt_period= (double)(openair0_cfg.samples_per_packet/(openair0_cfg.samples_per_frame/10.0)*1000000); rt_period= (double)(openair0_cfg->samples_per_packet/(openair0_cfg->samples_per_frame/10.0)*1000000);
AssertFatal(rt_period > 0, "Invalid rt period !%u\n", rt_period); AssertFatal(rt_period > 0, "Invalid rt period !%u\n", rt_period);
LOG_I(RRH,"[eNB] Real time period is set to %u ns\n", rt_period); LOG_I(RRH,"[eNB] Real time period is set to %u ns\n", rt_period);
} }
...@@ -785,62 +690,57 @@ static void calc_rt_period_ns( openair0_config_t openair0_cfg) { ...@@ -785,62 +690,57 @@ static void calc_rt_period_ns( openair0_config_t openair0_cfg) {
static void check_dev_config( rrh_module_t *mod_enb) { static void check_dev_config( rrh_module_t *mod_enb) {
AssertFatal( (mod_enb->devs->openair0_cfg->num_rb_dl==100 || mod_enb->devs->openair0_cfg->num_rb_dl==50 || mod_enb->devs->openair0_cfg->num_rb_dl==25 || mod_enb->devs->openair0_cfg->num_rb_dl==6) , "Invalid number of resource blocks! %d\n", mod_enb->devs->openair0_cfg->num_rb_dl);
AssertFatal( (mod_enb->devs->openair0_cfg.num_rb_dl==100 || mod_enb->devs->openair0_cfg.num_rb_dl==50 || mod_enb->devs->openair0_cfg.num_rb_dl==25 || mod_enb->devs->openair0_cfg.num_rb_dl==6) , "Invalid number of resource blocks! %d\n", mod_enb->devs->openair0_cfg.num_rb_dl); AssertFatal( mod_enb->devs->openair0_cfg->samples_per_frame > 0 , "Invalid number of samples per frame! %d\n",mod_enb->devs->openair0_cfg->samples_per_frame);
AssertFatal( mod_enb->devs->openair0_cfg.samples_per_frame > 0 , "Invalid number of samples per frame! %d\n",mod_enb->devs->openair0_cfg.samples_per_frame); AssertFatal( mod_enb->devs->openair0_cfg->sample_rate > 0.0, "Invalid sample rate! %f\n", mod_enb->devs->openair0_cfg->sample_rate);
AssertFatal( mod_enb->devs->openair0_cfg.sample_rate > 0.0, "Invalid sample rate! %f\n", mod_enb->devs->openair0_cfg.sample_rate); AssertFatal( mod_enb->devs->openair0_cfg->samples_per_packet > 0 , "Invalid number of samples per packet! %d\n",mod_enb->devs->openair0_cfg->samples_per_packet);
AssertFatal( mod_enb->devs->openair0_cfg.samples_per_packet > 0 , "Invalid number of samples per packet! %d\n",mod_enb->devs->openair0_cfg.samples_per_packet); AssertFatal( mod_enb->devs->openair0_cfg->rx_num_channels > 0 , "Invalid number of RX antennas! %d\n", mod_enb->devs->openair0_cfg->rx_num_channels);
AssertFatal( mod_enb->devs->openair0_cfg.rx_num_channels > 0 , "Invalid number of RX antennas! %d\n", mod_enb->devs->openair0_cfg.rx_num_channels); AssertFatal( mod_enb->devs->openair0_cfg->tx_num_channels > 0 , "Invalid number of TX antennas! %d\n", mod_enb->devs->openair0_cfg->tx_num_channels);
AssertFatal( mod_enb->devs->openair0_cfg.tx_num_channels > 0 , "Invalid number of TX antennas! %d\n", mod_enb->devs->openair0_cfg.tx_num_channels); AssertFatal( mod_enb->devs->openair0_cfg->rx_freq[0] > 0.0 ,"Invalid RX frequency! %f\n", mod_enb->devs->openair0_cfg->rx_freq[0]);
AssertFatal( mod_enb->devs->openair0_cfg.rx_freq[0] > 0.0 ,"Invalid RX frequency! %f\n", mod_enb->devs->openair0_cfg.rx_freq[0]); AssertFatal( mod_enb->devs->openair0_cfg->tx_freq[0] > 0.0 ,"Invalid TX frequency! %f\n", mod_enb->devs->openair0_cfg->tx_freq[0]);
AssertFatal( mod_enb->devs->openair0_cfg.tx_freq[0] > 0.0 ,"Invalid TX frequency! %f\n", mod_enb->devs->openair0_cfg.tx_freq[0]); AssertFatal( mod_enb->devs->openair0_cfg->rx_gain[0] > 0.0 ,"Invalid RX gain! %f\n", mod_enb->devs->openair0_cfg->rx_gain[0]);
AssertFatal( mod_enb->devs->openair0_cfg.rx_gain[0] > 0.0 ,"Invalid RX gain! %f\n", mod_enb->devs->openair0_cfg.rx_gain[0]); AssertFatal( mod_enb->devs->openair0_cfg->tx_gain[0] > 0.0 ,"Invalid TX gain! %f\n", mod_enb->devs->openair0_cfg->tx_gain[0]);
AssertFatal( mod_enb->devs->openair0_cfg.tx_gain[0] > 0.0 ,"Invalid TX gain! %f\n", mod_enb->devs->openair0_cfg.tx_gain[0]); AssertFatal( mod_enb->devs->openair0_cfg->rx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg->rx_bw);
AssertFatal( mod_enb->devs->openair0_cfg.rx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg.rx_bw); AssertFatal( mod_enb->devs->openair0_cfg->tx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg->tx_bw);
AssertFatal( mod_enb->devs->openair0_cfg.tx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg.tx_bw); AssertFatal( mod_enb->devs->openair0_cfg->autocal[0] > 0 , "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg->autocal[0]);
AssertFatal( mod_enb->devs->openair0_cfg.autocal[0] > 0 , "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg.autocal[0]);
printf("\n---------------------RF device configuration parameters---------------------\n"); printf("\n---------------------RF device configuration parameters---------------------\n");
printf("\tMod_id=%d\n \tlog level=%d\n \tDL_RB=%d\n \tsamples_per_frame=%d\n \tsample_rate=%f\n \tsamples_per_packet=%d\n \ttx_delay=%d\n \ttx_forward_nsamps=%d\n \trx_num_channels=%d\n \ttx_num_channels=%d\n \trx_freq_0=%f\n \ttx_freq_0=%f\n \trx_freq_1=%f\n \ttx_freq_1=%f\n \trx_freq_2=%f\n \ttx_freq_2=%f\n \trx_freq_3=%f\n \ttx_freq_3=%f\n \trxg_mode=%d\n \trx_gain_0=%f\n \ttx_gain_0=%f\n \trx_gain_1=%f\n \ttx_gain_1=%f\n \trx_gain_2=%f\n \ttx_gain_2=%f\n \trx_gain_3=%f\n \ttx_gain_3=%f\n \trx_gain_offset_2=%f\n \ttx_gain_offset_3=%f\n \trx_bw=%f\n \ttx_bw=%f\n \tautocal=%d\n \trem_addr %s:%d\n \tmy_addr %s:%d\n", printf("\tMod_id=%d\n \tlog level=%d\n \tDL_RB=%d\n \tsamples_per_frame=%d\n \tsample_rate=%f\n \tsamples_per_packet=%d\n \ttx_scheduling_advance=%d\n \ttx_sample_advance=%d\n \trx_num_channels=%d\n \ttx_num_channels=%d\n \trx_freq_0=%f\n \ttx_freq_0=%f\n \trx_freq_1=%f\n \ttx_freq_1=%f\n \trx_freq_2=%f\n \ttx_freq_2=%f\n \trx_freq_3=%f\n \ttx_freq_3=%f\n \trxg_mode=%d\n \trx_gain_0=%f\n \ttx_gain_0=%f\n \trx_gain_1=%f\n \ttx_gain_1=%f\n \trx_gain_2=%f\n \ttx_gain_2=%f\n \trx_gain_3=%f\n \ttx_gain_3=%f\n \trx_gain_offset_2=%f\n \ttx_gain_offset_3=%f\n \trx_bw=%f\n \ttx_bw=%f\n \tautocal=%d\n",
mod_enb->devs->openair0_cfg.Mod_id, mod_enb->devs->openair0_cfg->Mod_id,
mod_enb->devs->openair0_cfg.log_level, mod_enb->devs->openair0_cfg->log_level,
mod_enb->devs->openair0_cfg.num_rb_dl, mod_enb->devs->openair0_cfg->num_rb_dl,
mod_enb->devs->openair0_cfg.samples_per_frame, mod_enb->devs->openair0_cfg->samples_per_frame,
mod_enb->devs->openair0_cfg.sample_rate, mod_enb->devs->openair0_cfg->sample_rate,
mod_enb->devs->openair0_cfg.samples_per_packet, mod_enb->devs->openair0_cfg->samples_per_packet,
mod_enb->devs->openair0_cfg.tx_delay, mod_enb->devs->openair0_cfg->tx_scheduling_advance,
mod_enb->devs->openair0_cfg.tx_forward_nsamps, mod_enb->devs->openair0_cfg->tx_sample_advance,
mod_enb->devs->openair0_cfg.rx_num_channels, mod_enb->devs->openair0_cfg->rx_num_channels,
mod_enb->devs->openair0_cfg.tx_num_channels, mod_enb->devs->openair0_cfg->tx_num_channels,
mod_enb->devs->openair0_cfg.rx_freq[0], mod_enb->devs->openair0_cfg->rx_freq[0],
mod_enb->devs->openair0_cfg.tx_freq[0], mod_enb->devs->openair0_cfg->tx_freq[0],
mod_enb->devs->openair0_cfg.rx_freq[1], mod_enb->devs->openair0_cfg->rx_freq[1],
mod_enb->devs->openair0_cfg.tx_freq[1], mod_enb->devs->openair0_cfg->tx_freq[1],
mod_enb->devs->openair0_cfg.rx_freq[2], mod_enb->devs->openair0_cfg->rx_freq[2],
mod_enb->devs->openair0_cfg.tx_freq[2], mod_enb->devs->openair0_cfg->tx_freq[2],
mod_enb->devs->openair0_cfg.rx_freq[3], mod_enb->devs->openair0_cfg->rx_freq[3],
mod_enb->devs->openair0_cfg.tx_freq[3], mod_enb->devs->openair0_cfg->tx_freq[3],
mod_enb->devs->openair0_cfg.rxg_mode[0], mod_enb->devs->openair0_cfg->rxg_mode[0],
mod_enb->devs->openair0_cfg.rx_gain[0], mod_enb->devs->openair0_cfg->tx_gain[0],
mod_enb->devs->openair0_cfg.tx_gain[0], mod_enb->devs->openair0_cfg->tx_gain[0],
mod_enb->devs->openair0_cfg.rx_gain[1], mod_enb->devs->openair0_cfg->rx_gain[1],
mod_enb->devs->openair0_cfg.tx_gain[1], mod_enb->devs->openair0_cfg->tx_gain[1],
mod_enb->devs->openair0_cfg.rx_gain[2], mod_enb->devs->openair0_cfg->rx_gain[2],
mod_enb->devs->openair0_cfg.tx_gain[2], mod_enb->devs->openair0_cfg->tx_gain[2],
mod_enb->devs->openair0_cfg.rx_gain[3], mod_enb->devs->openair0_cfg->rx_gain[3],
mod_enb->devs->openair0_cfg.tx_gain[3], mod_enb->devs->openair0_cfg->tx_gain[3],
//mod_enb->devs->openair0_cfg.rx_gain_offset[0], //mod_enb->devs->openair0_cfg->rx_gain_offset[0],
//mod_enb->devs->openair0_cfg.rx_gain_offset[1], //mod_enb->devs->openair0_cfg->rx_gain_offset[1],
mod_enb->devs->openair0_cfg.rx_gain_offset[2], mod_enb->devs->openair0_cfg->rx_gain_offset[2],
mod_enb->devs->openair0_cfg.rx_gain_offset[3], mod_enb->devs->openair0_cfg->rx_gain_offset[3],
mod_enb->devs->openair0_cfg.rx_bw, mod_enb->devs->openair0_cfg->rx_bw,
mod_enb->devs->openair0_cfg.tx_bw, mod_enb->devs->openair0_cfg->tx_bw,
mod_enb->devs->openair0_cfg.autocal[0], mod_enb->devs->openair0_cfg->autocal[0]
mod_enb->devs->openair0_cfg.remote_ip,
mod_enb->devs->openair0_cfg.remote_port,
mod_enb->devs->openair0_cfg.my_ip,
mod_enb->devs->openair0_cfg.my_port
); );
printf("----------------------------------------------------------------------------\n"); printf("----------------------------------------------------------------------------\n");
......
...@@ -332,7 +332,6 @@ void reset_opp_meas(void); ...@@ -332,7 +332,6 @@ void reset_opp_meas(void);
void print_opp_meas(void); void print_opp_meas(void);
int transmission_mode=1; int transmission_mode=1;
int16_t glog_level = LOG_INFO; int16_t glog_level = LOG_INFO;
int16_t glog_verbosity = LOG_MED; int16_t glog_verbosity = LOG_MED;
int16_t hw_log_level = LOG_INFO; int16_t hw_log_level = LOG_INFO;
...@@ -363,16 +362,60 @@ int16_t osa_log_verbosity = LOG_MED; ...@@ -363,16 +362,60 @@ int16_t osa_log_verbosity = LOG_MED;
#ifdef ETHERNET #ifdef ETHERNET
char rrh_eNB_ip[20] = "127.0.0.1";
int rrh_eNB_port = 50000;
char *rrh_UE_ip = "127.0.0.1"; char *rrh_UE_ip = "127.0.0.1";
int rrh_UE_port = 51000; int rrh_UE_port = 51000;
#endif #endif
/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;
char uecap_xer[1024],uecap_xer_in=0; char uecap_xer[1024],uecap_xer_in=0;
extern void *UE_thread(void *arg); extern void *UE_thread(void *arg);
extern void init_UE_threads(void); extern void init_UE_threads(void);
/*---------------------BMC: timespec helpers -----------------------------*/
struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec clock_difftime(struct timespec start, struct timespec end)
{
struct timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
void print_difftimes()
{
#ifdef DEBUG
printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#else
LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#endif
}
void update_difftimes(struct timespec start, struct timespec end)
{
struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
int changed = 0;
diff_time = clock_difftime(start, end);
if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
#if 1
if (changed) print_difftimes();
#endif
}
/*------------------------------------------------------------------------*/
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
{ {
return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
...@@ -433,7 +476,6 @@ void help (void) { ...@@ -433,7 +476,6 @@ void help (void) {
printf(" -h provides this help message!\n"); printf(" -h provides this help message!\n");
printf(" -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"); printf(" -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n");
printf(" -m Set the maximum downlink MCS\n"); printf(" -m Set the maximum downlink MCS\n");
printf(" -M IP address of RRH\n");
printf(" -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n"); printf(" -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n");
printf(" -q Enable processing timing measurement of lte softmodem on per subframe basis \n"); printf(" -q Enable processing timing measurement of lte softmodem on per subframe basis \n");
printf(" -r Set the PRB, valid values: 6, 25, 50, 100 \n"); printf(" -r Set the PRB, valid values: 6, 25, 50, 100 \n");
...@@ -958,27 +1000,9 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -958,27 +1000,9 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti)) if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti; tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti;
((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]= ((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0] = ((short*)dummy_tx_b)[2*i]<<openair0_cfg[0].iq_txshift;
#ifdef EXMIMO
((short*)dummy_tx_b)[2*i]<<4; ((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift;
#elif OAI_BLADERF
((short*)dummy_tx_b)[2*i];
#elif OAI_LMSSDR
//phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset]=dummy_tx_b[i];
((short*)dummy_tx_b)[2*i];
#else
((short*)dummy_tx_b)[2*i]<<4;
#endif
((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
#ifdef EXMIMO
((short*)dummy_tx_b)[2*i+1]<<4;
#elif OAI_BLADERF
((short*)dummy_tx_b)[2*i+1];
#elif OAI_LMSSDR
((short*)dummy_tx_b)[2*i+1];
#else
((short*)dummy_tx_b)[2*i+1]<<4;
#endif
} }
// if S-subframe switch to RX in second subframe // if S-subframe switch to RX in second subframe
if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_S) { if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_S) {
...@@ -1835,7 +1859,9 @@ static void* eNB_thread( void* arg ) ...@@ -1835,7 +1859,9 @@ static void* eNB_thread( void* arg )
PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx); PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
stop_meas( &softmodem_stats_hw ); stop_meas( &softmodem_stats_hw );
if (frame > 50) {
clock_gettime( CLOCK_MONOTONIC, &trx_time1 ); clock_gettime( CLOCK_MONOTONIC, &trx_time1 );
}
if (frame > 20){ if (frame > 20){
if (rxs != spp) if (rxs != spp)
...@@ -1845,8 +1871,6 @@ static void* eNB_thread( void* arg ) ...@@ -1845,8 +1871,6 @@ static void* eNB_thread( void* arg )
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers // prepare tx buffer pointers
for (i=0; i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx; i++) for (i=0; i<PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx; i++)
...@@ -1865,17 +1889,28 @@ static void* eNB_thread( void* arg ) ...@@ -1865,17 +1889,28 @@ static void* eNB_thread( void* arg )
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp+(openair0_cfg[card].tx_scheduling_advance)-openair0_cfg[card].tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp+(openair0_cfg[card].tx_scheduling_advance)-openair0_cfg[card].tx_sample_advance)&0xffffffff );
stop_meas( &softmodem_stats_mt ); stop_meas( &softmodem_stats_mt );
if (frame > 50) {
clock_gettime( CLOCK_MONOTONIC, &trx_time2 ); clock_gettime( CLOCK_MONOTONIC, &trx_time2 );
//update_difftimes(trx_time1, trx_time2);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
#else #else
// USRP_DEBUG is active // USRP_DEBUG is active
rt_sleep_ns(1000000); rt_sleep_ns(1000000);
#endif #endif
/* FT configurable tx lauch delay (in slots): txlaunch_wait, txlaunch_wait_slotcount is device specific and
set in the corresponding library (with txlaunch_wait=1 and txlaunch_wait_slotcount=1 the check is as it previously was) */
/* old check:
if ((frame>50) && if ((frame>50) &&
(tx_launched == 0) && (tx_launched == 0) &&
(rx_pos >= (((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) { (rx_pos >= (((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) {*/
if ( (frame>50) && (tx_launched == 0) &&
((openair0_cfg[card].txlaunch_wait == 0) ||
((openair0_cfg[card].txlaunch_wait == 1) &&
(rx_pos >= (((2*hw_subframe)+openair0_cfg[card].txlaunch_wait_slotcount)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))))) {
tx_launched = 1; tx_launched = 1;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
...@@ -2037,6 +2072,9 @@ eNB_thread_cleanup: ...@@ -2037,6 +2072,9 @@ eNB_thread_cleanup:
#endif #endif
eNB_thread_status = 0; eNB_thread_status = 0;
// print_difftimes();
return &eNB_thread_status; return &eNB_thread_status;
} }
...@@ -2176,13 +2214,6 @@ static void get_options (int argc, char **argv) ...@@ -2176,13 +2214,6 @@ static void get_options (int argc, char **argv)
case LONG_OPTION_DUMP_FRAME: case LONG_OPTION_DUMP_FRAME:
mode = rx_dump_frame; mode = rx_dump_frame;
break; break;
case 'M':
#ifdef ETHERNET
strcpy(rrh_eNB_ip,optarg);
#endif
break;
case 'A': case 'A':
timing_advance = atoi (optarg); timing_advance = atoi (optarg);
break; break;
...@@ -2425,6 +2456,34 @@ static void get_options (int argc, char **argv) ...@@ -2425,6 +2456,34 @@ static void get_options (int argc, char **argv)
"lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!", "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!",
MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i); MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i);
for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
local_remote_radio = BBU_REMOTE_RADIO_HEAD;
eth_params = (eth_params_t*)malloc(sizeof(eth_params_t));
memset(eth_params, 0, sizeof(eth_params_t));
printf( "\n\tRRH GW %d config for eNB %u:\n\n", j, i);
printf( "\tinterface name : \t%s:\n",enb_properties->properties[i]->rrh_gw_if_name);
printf( "\tlocal address : \t%s:\n",enb_properties->properties[i]->rrh_gw_config[j].local_address);
printf( "\tlocal port : \t%d:\n",enb_properties->properties[i]->rrh_gw_config[j].local_port);
printf( "\tremote address : \t%s:\n",enb_properties->properties[i]->rrh_gw_config[j].remote_address);
printf( "\tremote port : \t%d:\n",enb_properties->properties[i]->rrh_gw_config[j].remote_port);
printf( "\ttransport : \t%s Ethernet:\n\n",(enb_properties->properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : "UDP");
eth_params->local_if_name = enb_properties->properties[i]->rrh_gw_if_name;
eth_params->my_addr = enb_properties->properties[i]->rrh_gw_config[j].local_address;
eth_params->my_port = enb_properties->properties[i]->rrh_gw_config[j].local_port;
eth_params->remote_addr = enb_properties->properties[i]->rrh_gw_config[j].remote_address;
eth_params->remote_port = enb_properties->properties[i]->rrh_gw_config[j].remote_port;
eth_params->transp_preference = enb_properties->properties[i]->rrh_gw_config[j].raw;
} else {
local_remote_radio = BBU_LOCAL_RADIO_HEAD;
}
}
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->frame_type = enb_properties->properties[i]->frame_type[CC_id]; frame_parms[CC_id]->frame_type = enb_properties->properties[i]->frame_type[CC_id];
frame_parms[CC_id]->tdd_config = enb_properties->properties[i]->tdd_config[CC_id]; frame_parms[CC_id]->tdd_config = enb_properties->properties[i]->tdd_config[CC_id];
...@@ -2967,20 +3026,13 @@ int main( int argc, char **argv ) ...@@ -2967,20 +3026,13 @@ int main( int argc, char **argv )
else //FDD else //FDD
openair0_cfg[card].duplex_mode = duplex_mode_FDD; openair0_cfg[card].duplex_mode = duplex_mode_FDD;
#ifdef ETHERNET
//calib needed
openair0_cfg[card].tx_scheduling_advance = 0;
openair0_cfg[card].tx_sample_advance = 0;
if (frame_parms[0]->N_RB_DL == 6)
openair0_cfg[card].samples_per_packet = 256;
else
openair0_cfg[card].samples_per_packet = 1024;
printf("HW: samples_per_packet %d\n",openair0_cfg[card].samples_per_packet);
#endif
if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {
openair0_cfg[card].remote_addr = eth_params->remote_addr;
openair0_cfg[card].remote_port = eth_params->remote_port;
openair0_cfg[card].my_addr = eth_params->my_addr;
openair0_cfg[card].my_port = eth_params->my_port;
}
printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx), ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx),
...@@ -2990,13 +3042,10 @@ int main( int argc, char **argv ) ...@@ -2990,13 +3042,10 @@ int main( int argc, char **argv )
if (UE_flag) { if (UE_flag) {
printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port); printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
openair0_cfg[card].remote_ip = &rrh_UE_ip[0]; openair0_cfg[card].remote_addr = &rrh_UE_ip[0];
openair0_cfg[card].remote_port = rrh_UE_port; openair0_cfg[card].remote_port = rrh_UE_port;
} else {
printf("ETHERNET: Configuring eNB ETH for %s:%d\n",rrh_eNB_ip,rrh_eNB_port);
openair0_cfg[card].remote_ip = &rrh_eNB_ip[0];
openair0_cfg[card].remote_port = rrh_eNB_port;
} }
openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
#endif #endif
...@@ -3053,21 +3102,39 @@ int main( int argc, char **argv ) ...@@ -3053,21 +3102,39 @@ int main( int argc, char **argv )
#endif #endif
} }
/* device host type is set*/
openair0.func_type = BBU_FUNC; openair0.host_type = BBU_HOST;
/* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
openair0.type = NONE_DEV;
/* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
openair0.transp_type = NONE_TP;
openair0_cfg[0].log_level = glog_level; openair0_cfg[0].log_level = glog_level;
if (mode!=loop_through_memory){ int returns=-1;
int ret; /* BBU can have either a local or a remote radio head */
ret= openair0_device_init(&openair0, &openair0_cfg[0]); if (local_remote_radio == BBU_LOCAL_RADIO_HEAD) { //local radio head active - load library of radio head and initiate it
printf("openair0_device_init returns %d\n",ret); if (mode!=loop_through_memory) {
if (ret<0) { returns=openair0_device_load(&openair0, &openair0_cfg[0]);
printf("openair0_device_init returns %d\n",returns);
if (returns<0) {
printf("Exiting, cannot initialize device\n"); printf("Exiting, cannot initialize device\n");
exit(-1); exit(-1);
} }
} }
else if (mode==loop_through_memory) { else if (mode==loop_through_memory) {
} }
} else { //remote radio head active - load library of transport protocol and initiate it
if (mode!=loop_through_memory) {
returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params);
printf("openair0_transport_init returns %d\n",returns);
if (returns<0) {
printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
}
else if (mode==loop_through_memory) {
}
}
printf("Done\n"); printf("Done\n");
...@@ -3491,7 +3558,6 @@ int main( int argc, char **argv ) ...@@ -3491,7 +3558,6 @@ int main( int argc, char **argv )
if (multi_thread>0) { if (multi_thread>0) {
printf("Killing eNB processing threads\n"); printf("Killing eNB processing threads\n");
kill_eNB_proc(); kill_eNB_proc();
} }
} }
...@@ -3583,10 +3649,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -3583,10 +3649,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
#endif #endif
// replace RX signal buffers with mmaped HW versions // replace RX signal buffers with mmaped HW versions
#ifdef EXMIMO #ifdef EXMIMO
openair0_cfg[CC_id].tx_num_channels = 0; openair0_cfg[CC_id].tx_num_channels = 0;
......
[*] [*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Thu Sep 17 14:23:43 2015 [*] Fri Jan 29 16:34:46 2016
[*] [*]
[dumpfile] "/tmp/openair_dump_rrh.vcd" [dumpfile] "/tmp/openair_dump_rrh.vcd"
[dumpfile_mtime] "Thu Sep 17 14:21:43 2015" [dumpfile_mtime] "Fri Jan 29 16:20:55 2016"
[dumpfile_size] 636509125 [dumpfile_size] 224259458
[savefile] "/home/guepe/openair4G/targets/RT/USER/rrh.gtkw" [savefile] "/home/guepe/openairinterface5g_rrh/openairinterface5g/targets/RT/USER/rrh.gtkw"
[timestart] 17746655400 [timestart] 31315875900
[size] 1855 1056 [size] 1004 1028
[pos] -1 -1 [pos] 926 -1
*-15.826077 17746846200 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 *-17.429794 31316090054 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 224 [sst_width] 224
[signals_width] 230 [signals_width] 261
[sst_expanded] 1 [sst_expanded] 1
[sst_vpaned_height] 287 [sst_vpaned_height] 278
@24 @24
[color] 1 [color] 1
variables.hw_frame_rx[63:0] variables.hw_frame_rx[63:0]
...@@ -23,7 +23,10 @@ variables.hw_subframe_rx[63:0] ...@@ -23,7 +23,10 @@ variables.hw_subframe_rx[63:0]
[color] 1 [color] 1
functions.eNB_rx functions.eNB_rx
functions.eNB_rx_sleep functions.eNB_rx_sleep
functions.trx_write_rf [color] 3
functions.trx_read_rf
[color] 7
functions.trx_write
@c00024 @c00024
variables.rxcnt[63:0] variables.rxcnt[63:0]
@28 @28
...@@ -95,24 +98,97 @@ variables.rxcnt[63:0] ...@@ -95,24 +98,97 @@ variables.rxcnt[63:0]
-group_end -group_end
@24 @24
variables.pck_rx[63:0] variables.pck_rx[63:0]
variables.rx_ts[63:0]
@c00024
variables.tx_seq_num[63:0]
@28
(0)variables.tx_seq_num[63:0]
(1)variables.tx_seq_num[63:0]
(2)variables.tx_seq_num[63:0]
(3)variables.tx_seq_num[63:0]
(4)variables.tx_seq_num[63:0]
(5)variables.tx_seq_num[63:0]
(6)variables.tx_seq_num[63:0]
(7)variables.tx_seq_num[63:0]
(8)variables.tx_seq_num[63:0]
(9)variables.tx_seq_num[63:0]
(10)variables.tx_seq_num[63:0]
(11)variables.tx_seq_num[63:0]
(12)variables.tx_seq_num[63:0]
(13)variables.tx_seq_num[63:0]
(14)variables.tx_seq_num[63:0]
(15)variables.tx_seq_num[63:0]
(16)variables.tx_seq_num[63:0]
(17)variables.tx_seq_num[63:0]
(18)variables.tx_seq_num[63:0]
(19)variables.tx_seq_num[63:0]
(20)variables.tx_seq_num[63:0]
(21)variables.tx_seq_num[63:0]
(22)variables.tx_seq_num[63:0]
(23)variables.tx_seq_num[63:0]
(24)variables.tx_seq_num[63:0]
(25)variables.tx_seq_num[63:0]
(26)variables.tx_seq_num[63:0]
(27)variables.tx_seq_num[63:0]
(28)variables.tx_seq_num[63:0]
(29)variables.tx_seq_num[63:0]
(30)variables.tx_seq_num[63:0]
(31)variables.tx_seq_num[63:0]
(32)variables.tx_seq_num[63:0]
(33)variables.tx_seq_num[63:0]
(34)variables.tx_seq_num[63:0]
(35)variables.tx_seq_num[63:0]
(36)variables.tx_seq_num[63:0]
(37)variables.tx_seq_num[63:0]
(38)variables.tx_seq_num[63:0]
(39)variables.tx_seq_num[63:0]
(40)variables.tx_seq_num[63:0]
(41)variables.tx_seq_num[63:0]
(42)variables.tx_seq_num[63:0]
(43)variables.tx_seq_num[63:0]
(44)variables.tx_seq_num[63:0]
(45)variables.tx_seq_num[63:0]
(46)variables.tx_seq_num[63:0]
(47)variables.tx_seq_num[63:0]
(48)variables.tx_seq_num[63:0]
(49)variables.tx_seq_num[63:0]
(50)variables.tx_seq_num[63:0]
(51)variables.tx_seq_num[63:0]
(52)variables.tx_seq_num[63:0]
(53)variables.tx_seq_num[63:0]
(54)variables.tx_seq_num[63:0]
(55)variables.tx_seq_num[63:0]
(56)variables.tx_seq_num[63:0]
(57)variables.tx_seq_num[63:0]
(58)variables.tx_seq_num[63:0]
(59)variables.tx_seq_num[63:0]
(60)variables.tx_seq_num[63:0]
(61)variables.tx_seq_num[63:0]
(62)variables.tx_seq_num[63:0]
(63)variables.tx_seq_num[63:0]
@1401200
-group_end
@24
variables.hw_frame[63:0] variables.hw_frame[63:0]
variables.hw_subframe[63:0] variables.hw_subframe[63:0]
@28 @28
[color] 1 [color] 1
functions.eNB_tx functions.eNB_tx
functions.eNB_tx_sleep functions.eNB_tx_sleep
functions.trx_read_rf
[color] 7
functions.trx_write
[color] 7 [color] 7
functions.trx_read functions.trx_read
[color] 3
functions.trx_write_rf
@24 @24
variables.txcnt[63:0] variables.txcnt[63:0]
variables.rx_ts[63:0] variables.pck_tx[63:0]
variables.tx_ts[63:0] variables.tx_ts[63:0]
@25
variables.rx_seq_num_prv[63:0]
@24
variables.rx_seq_num[63:0]
variables.hw_cnt_rx[63:0] variables.hw_cnt_rx[63:0]
variables.lhw_cnt_rx[63:0] variables.lhw_cnt_rx[63:0]
@25
[color] 3 [color] 3
variables.cnt[63:0] variables.cnt[63:0]
[pattern_trace] 1 [pattern_trace] 1
......
...@@ -51,9 +51,9 @@ ...@@ -51,9 +51,9 @@
#include <time.h> #include <time.h>
#include "common_lib.h" #include "common_lib.h"
#include "rrh_gw.h" // change to rrh_new.h, put externs in rrh_extern.h #include "rrh_gw.h"
#include "rt_wrapper.h" #include "rt_wrapper.h"
#include "rrh_gw_externs.h" // change to rrh_new.h, put externs in rrh_extern.h #include "rrh_gw_externs.h"
#include "log_if.h" #include "log_if.h"
...@@ -71,8 +71,9 @@ ...@@ -71,8 +71,9 @@
*****************************************************************************************/ *****************************************************************************************/
/* local IP/MAC address is detected*/
char rrh_ip[20] = "192.168.12.242"; // there is code to detect the my ip address char rrh_ip[20] = "0.0.0.0";
unsigned char rrh_mac[6] = "0:0:0:0:0:0";
int rrh_port = 50000; // has to be an option int rrh_port = 50000; // has to be an option
/* log */ /* log */
...@@ -86,7 +87,7 @@ int16_t ue_log_level = LOG_INFO; ...@@ -86,7 +87,7 @@ int16_t ue_log_level = LOG_INFO;
int16_t ue_log_verbosity = LOG_MED; int16_t ue_log_verbosity = LOG_MED;
/* flags definitions */ /* flag definitions */
uint8_t eNB_flag=0; uint8_t eNB_flag=0;
uint8_t UE_flag=0; uint8_t UE_flag=0;
uint8_t EXMIMO_flag=0; uint8_t EXMIMO_flag=0;
...@@ -102,10 +103,8 @@ uint8_t measurements_flag=0; ...@@ -102,10 +103,8 @@ uint8_t measurements_flag=0;
- default ethernet interface is local */ - default ethernet interface is local */
uint8_t num_eNB_mod=0; uint8_t num_eNB_mod=0;
uint8_t num_UE_mod=0; uint8_t num_UE_mod=0;
uint8_t num_EXMIMO_mod=0;
uint8_t num_USRP_mod=0;
uint8_t hardware_target=NONE_IF;
char* if_name="lo"; char* if_name="lo";
uint8_t eth_mode=ETH_UDP_MODE;
rrh_module_t *enb_array; rrh_module_t *enb_array;
rrh_module_t *ue_array; rrh_module_t *ue_array;
...@@ -128,14 +127,14 @@ static void print_help(void); ...@@ -128,14 +127,14 @@ static void print_help(void);
*/ */
static rrh_module_t new_module(unsigned int id); static rrh_module_t new_module(unsigned int id);
/*!\fn static int get_ip_address(char* if_name) /*!\fn static int get_address(char* if_name, uint8_t flag);
* \brief retrieves IP address from the specified network interface * \brief retrieves IP address from the specified network interface
* \param[in] name of network interface * \param[in] name of network interface
* \return 0 * \return 0
* \note * \note
* @ingroup _oai * @ingroup _oai
*/ */
static int get_ip_address(char* if_name); static int get_address(char* if_name, uint8_t flag);
...@@ -192,48 +191,53 @@ static rrh_module_t new_module (unsigned int id) { ...@@ -192,48 +191,53 @@ static rrh_module_t new_module (unsigned int id) {
rrh_mod.measurements=measurements_flag; rrh_mod.measurements=measurements_flag;
/* each module is associated with an ethernet device */ /* each module is associated with an ethernet device */
rrh_mod.eth_dev.type=ETH_IF; rrh_mod.eth_dev.type=NONE_DEV;
rrh_mod.eth_dev.transp_type=NONE_TP;
/* ethernet device is functioning within RRH */ /* ethernet device is functioning within RRH */
rrh_mod.eth_dev.func_type=RRH_FUNC; rrh_mod.eth_dev.host_type=RRH_HOST;
/* specify IP address */ /* */
get_ip_address(if_name); rrh_mod.eth_dev.openair0_cfg = (openair0_config_t*)malloc(sizeof(openair0_config_t));
openair0_cfg.my_ip=&rrh_ip[0]; memset(rrh_mod.eth_dev.openair0_cfg,0,sizeof(openair0_config_t));
openair0_cfg.my_port=rrh_port; /* get IP and MAC address */
get_address(if_name,eth_mode);
if(eth_mode==ETH_UDP_MODE) {
openair0_cfg.my_addr = &rrh_ip[0];
openair0_cfg.my_port = rrh_port;
LOG_I(RRH,"UDP mode selected for ethernet.\n");
} else if (eth_mode==ETH_RAW_MODE) {
openair0_cfg.my_addr = &rrh_mac[0];
openair0_cfg.my_port = rrh_port;
LOG_I(RRH,"RAW mode selected for ethernet.\n");
}
/* */
eth_params_t *eth_params = (eth_params_t*)malloc(sizeof(eth_params_t));
memset(eth_params, 0, sizeof(eth_params_t));
eth_params->local_if_name = if_name;
eth_params->transp_preference = eth_mode;
/* ethernet device initialization */ /* ethernet device initialization */
if (openair0_dev_init_eth(&rrh_mod.eth_dev, &openair0_cfg)<0){ if (openair0_transport_load(&rrh_mod.eth_dev, &openair0_cfg,eth_params)<0) {
LOG_E(RRH,"Exiting, cannot initialize ethernet interface.\n"); LOG_E(RRH,"Exiting, cannot initialize ethernet interface.\n");
exit(-1); exit(-1);
} }
/* allocate space and specify associated RF device */ /* allocate space and specify associated RF device */
openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_device)); openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_device));
memset(oai_dv,0, sizeof(openair0_device)); memset(oai_dv,0,sizeof(openair0_device));
#ifdef EXMIMO
rrh_mod.devs=oai_dv;
rrh_mod.devs->type=EXMIMO_IF;
LOG_I(RRH,"Setting RF device to EXMIMO\n");
#elif OAI_USRP
rrh_mod.devs=oai_dv; rrh_mod.devs=oai_dv;
rrh_mod.devs->type=USRP_B200_IF; rrh_mod.devs->type=NONE_DEV;
LOG_I(RRH,"Setting RF device to USRP\n"); rrh_mod.devs->transp_type=NONE_TP;
#elif OAI_BLADERF rrh_mod.devs->host_type=RRH_HOST;
rrh_mod.devs=oai_dv;
rrh_mod.devs->type=BLADERF_IF;
LOG_I(RRH,"Setting RF device to BLADERF\n");
#else
rrh_mod.devs=oai_dv;
rrh_mod.devs->type=NONE_IF;
LOG_I(RRH,"Setting RF interface to NONE_IF... \n");
#endif
return rrh_mod; return rrh_mod;
} }
static void debug_init(void) { static void debug_init(void) {
// log initialization /* log initialization */
logInit(); logInit();
set_glog(glog_level, glog_verbosity); set_glog(glog_level, glog_verbosity);
...@@ -241,7 +245,7 @@ static void debug_init(void) { ...@@ -241,7 +245,7 @@ static void debug_init(void) {
//set_comp_log(ENB_LOG, enb_log_level, enb_log_verbosity, 1); //set_comp_log(ENB_LOG, enb_log_level, enb_log_verbosity, 1);
//set_comp_log(UE_LOG, ue_log_level, ue_log_verbosity, 1); //set_comp_log(UE_LOG, ue_log_level, ue_log_verbosity, 1);
// vcd initialization /* vcd initialization */
if (ouput_vcd) { if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd"); vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd");
...@@ -253,7 +257,7 @@ static void get_options(int argc, char *argv[]) { ...@@ -253,7 +257,7 @@ static void get_options(int argc, char *argv[]) {
int opt; int opt;
while ((opt = getopt(argc, argv, "xvhlte:n:u:g:r:w:i:")) != -1) { while ((opt = getopt(argc, argv, "xvhlte:n:u:g:r:m:i:")) != -1) {
switch (opt) { switch (opt) {
case 'n': case 'n':
...@@ -273,6 +277,9 @@ static void get_options(int argc, char *argv[]) { ...@@ -273,6 +277,9 @@ static void get_options(int argc, char *argv[]) {
printf("RRH interface name is set to %s\n", if_name); printf("RRH interface name is set to %s\n", if_name);
} }
break; break;
case 'm':
eth_mode=atoi(optarg);
break;
case 'r': case 'r':
//rrh_log_level=atoi(optarg); //rrh_log_level=atoi(optarg);
break; break;
...@@ -293,13 +300,9 @@ static void get_options(int argc, char *argv[]) { ...@@ -293,13 +300,9 @@ static void get_options(int argc, char *argv[]) {
loopback_flag=1; loopback_flag=1;
break; break;
case 't': case 't':
/*When measurements are enabled statistics related to TX/RX time are printed*/ /* When measurements are enabled statistics related to TX/RX time are printed */
measurements_flag=1; measurements_flag=1;
break; break;
case 'w':
/* force to use this target*/
hardware_target=1;
break;
case 'h': case 'h':
print_help(); print_help();
exit(-1); exit(-1);
...@@ -311,31 +314,34 @@ static void get_options(int argc, char *argv[]) { ...@@ -311,31 +314,34 @@ static void get_options(int argc, char *argv[]) {
} }
static int get_ip_address(char* if_name) { static int get_address(char* if_name, uint8_t flag) {
int fd; int fd;
struct ifreq ifr; struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0); fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */ /* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "if_name" */ /* I want IP address attached to "if_name" */
strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1); strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1);
if (flag==ETH_UDP_MODE) {
if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) { if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
perror("IOCTL:"); perror("IOCTL:");
exit(-1); exit(-1);
} }
close(fd);
/* display result */
snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
LOG_I(RRH,"Got IP address %s from interface %s\n", rrh_ip,if_name); LOG_I(RRH,"%s: IP address: %s\n",if_name,rrh_ip);
} else if (flag==ETH_RAW_MODE) {
if ( ioctl(fd, SIOCGIFHWADDR, &ifr)<0 ) {
perror("IOCTL:");
exit(-1);
}
ether_ntoa_r ((unsigned char *)ifr.ifr_hwaddr.sa_data, rrh_mac);
LOG_I(RRH,"%s: MAC address: %s\n",if_name,rrh_mac);
}
close(fd);
return 0; return 0;
} }
...@@ -343,19 +349,19 @@ static int get_ip_address(char* if_name) { ...@@ -343,19 +349,19 @@ static int get_ip_address(char* if_name) {
static void print_help(void) { static void print_help(void) {
puts("Usage: \n"); puts("Usage: \n");
puts(" sudo -E chrt 99 ./rrh -n1 -g6 -v -t"); puts(" sudo -E chrt 99 ./rrh -n1 -g6 -v -t -i lo -m1");
puts("Options:\n"); puts("Options:\n");
puts("\t -n create eNB module\n"); puts("\t -n create eNB module\n");
puts("\t -u create UE module\n"); puts("\t -u create UE module\n");
puts("\t -g define global log level\n"); puts("\t -g define global log level\n");
puts("\t -i set the RRH interface (default lo)\n"); puts("\t -i set the RRH interface (default lo)\n");
puts("\t -m set ethernet mode to be used by RRH, valid options: (1:raw, 0:udp) \n");
puts("\t -r define rrh log level\n"); puts("\t -r define rrh log level\n");
puts("\t -e define eNB log level\n"); puts("\t -e define eNB log level\n");
puts("\t -x enable real time bahaviour\n"); puts("\t -x enable real time bahaviour\n");
puts("\t -v enable vcd dump\n"); puts("\t -v enable vcd dump\n");
puts("\t -l enable loopback mode\n"); puts("\t -l enable loopback mode\n");
puts("\t -t enable measurements\n"); puts("\t -t enable measurements\n");
puts("\t -w force to use specified HW\n");
puts("\t -h display info\n"); puts("\t -h display info\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment